#+TITLE:Config
#+AUTH
#+STARTUP: showeverything

* :toc:
- [[#auto-install-packages][auto install packages]]
  - [[#setup-use-package][Setup use-package]]
- [[#common][common]]
  - [[#ui][UI]]
- [[#main-packages][main packages]]
  - [[#general-keybindings][General keybindings]]
  - [[#window-move][Window move]]
  - [[#evil-mode][Evil Mode]]
  - [[#ivy][Ivy]]
  - [[#counsel][Counsel]]
  - [[#dired][dired]]
  - [[#image-viewer][Image Viewer]]
  - [[#openwith][openwith]]
  - [[#org-download][org-download]]
  - [[#perspective][perspective]]
  - [[#anzu][anzu]]
  - [[#doom-modeline][doom-modeline]]
  - [[#neotree][NeoTree]]
  - [[#file-copy-file-open-file-in-dired][file (copy file, open file in dired)]]
  - [[#bm-marks--org-tangle][bm-marks / org tangle]]
  - [[#project--projectile][project / projectile]]
  - [[#buffer--bookmarks--harpoon][buffer & bookmarks & harpoon]]
  - [[#sudo-edit--code-sudo-editsplitperfect-marginjson][Sudo Edit & code (sudo edit/split/perfect margin/json)]]
  - [[#magit][Magit]]
- [[#org-settings][ORG settings]]
  - [[#org-hot-key][org hot key]]
  - [[#org-temo-chet-sheet][Org Temo chet sheet]]
  - [[#toc][toc]]
  - [[#org-babel-execute][org babel execute]]
  - [[#org-agenda][org agenda]]
  - [[#org-image][Org Image]]
  - [[#org-level-size][org level size]]
  - [[#org-level-hide][org level hide]]
- [[#programming][PROGRAMMING]]
  - [[#snipets][snipets]]
  - [[#python][python]]
  - [[#go][go]]
  - [[#emacs-lisp][Emacs-lisp]]
- [[#decorations][decorations]]
  - [[#colorthemes][colorthemes]]
  - [[#diff][diff]]
  - [[#fonts][fonts]]
  - [[#ligature][ligature]]
  - [[#icons][icons]]
  - [[#rainbow-mode][rainbow mode]]
  - [[#nyan-mode][Nyan-mode]]
  - [[#evil-snipe][evil-snipe]]
  - [[#org-chckbox-hl][org chckbox hl]]
  - [[#hl-todo][hl-todo]]
- [[#programs][Programs]]
  - [[#emms][emms]]
  - [[#latex-pdf][Latex (pdf)]]
  - [[#terminal][Terminal]]
- [[#exwm][EXWM]]
  - [[#setup-windows-hotkey][setup windows hotkey]]
  - [[#setup-wm][setup wm]]
- [[#apps][Apps]]
  - [[#text-processor][Text Processor]]
  - [[#image-processor][Image Processor]]
- [[#scripts][scripts]]
  - [[#add-projectile-project][add projectile project]]
  - [[#rest][REST]]
  - [[#insert-some-text][insert some text]]

* auto install packages
#+begin_src emacs-lisp
(require 'package)
;; (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("gnu" . "https://elpa.gnu.org/packages/")))
(package-initialize)

(unless package-archive-contents
  (package-refresh-contents))

;; Список пакетов для установки.
;; (defvar my-required-packages
;;   '(doom-themes
;;     doom-modeline
;;     evil
;;     evil-collection
;;     evil-surround
;;     evil-snipe
;;     which-key
;;     general
;;     key-chord
;;     toc-org
;;     org-bullets
;;     projectile
;;     sudo-edit
;;     ivy
;;     counsel
;;     harpoon
;;     bm
;;     vterm
;;     org-download
;;     restclient
;;     magit
;;     magit-delta
;;     image-dired
;;     yaml-mode

;;     ;; decorations
;;     rainbow-mode
;;     all-the-icons
;;     all-the-icons-dired ;; M-x all-the-icons-install-fonts
;;     centered-window
;;     nyan-mode
;;     perfect-margin
;;     hl-todo
;;     ligature

;;     tree-sitter
;;     diff-hl
;;     dired-subtree
;;     tree-sitter-langs
;;     flycheck
;;     flycheck-pycheckers
;;     ;; python
;;     elpy
;;     ;; copilot
;;     ;; editorconfig
;;     ; jsonrpc
;;     haskell-mode

;;     ;; frontend
;;     web-mode
;;    ))

;; Список пакетов для установки.
(defvar my-required-packages
  '(org-download
   ))

;; Установите недостающие пакеты.
(dolist (p my-required-packages)
  (unless (package-installed-p p)
    (package-install p)))
#+end_src

** Setup use-package
#+begin_src emacs-lisp
;; This is only needed once, near the top of the file
(require 'use-package)
#+end_src


* common
#+begin_src emacs-lisp
(setq make-backup-files nil)                              ;  Отключение создания файлов резервных копий (файлов с суффиксом ~)
(setq auto-save-default nil)                              ;  Отключение автосохранения и создания файлов с префиксом .#

(setq-default isearch-lazy-highlight t)                   ;  Включение "ленивой" подсветки при поиске

(global-visual-line-mode t)                               ;  Включение переноса строк вместо горизонтального скролла
(setq-default display-line-numbers 'relative)             ;  Включение относительных номеров строк

(prefer-coding-system 'utf-8)                             ;  Установка предпочтительной системы кодирования на UTF-8
(set-default-coding-systems 'utf-8)                       ;  Установка системы кодирования по умолчанию на UTF-8
(set-terminal-coding-system 'utf-8)                       ;  Установка системы кодирования терминала на UTF-8
(set-keyboard-coding-system 'utf-8)                       ;  Установка системы кодирования клавиатуры на UTF-8
(setq default-buffer-file-coding-system 'utf-8)           ;  Установка системы кодирования файловых буферов на UTF-8
(setq scroll-conservatively 10000)                        ;  Установка плавного скроллинга без резкого перемещения экрана
(electric-pair-mode 1)                                    ;  автоматически закрывать скопки
(add-hook 'before-save-hook 'delete-trailing-whitespace)  ;  Удаление пустых пробелов в конце строк перед сохранением файла
(blink-cursor-mode 0)                                     ;  cursorline
(setq display-fill-column-indicator nil)                  ;  отключить вертикальные линии
(setq warning-minimum-level :error)                       ;  отключить предупреждения

;; (setq indent-tabs-mode nil)  ;; Использовать пробелы вместо табов
;; (setq tab-width 4)
#+end_src

** UI
#+begin_src emacs-lisp
(setq inhibit-startup-screen t)                           ;  Отключение стартового экрана при запуске Emacs
(menu-bar-mode -1)                                        ;  Отключение меню-бара
(tool-bar-mode -1)                                        ;  Отключение панели инструментов
(scroll-bar-mode -1)                                      ;  Отключение вертикальной полосы прокрутки
(show-paren-mode 1)                                       ;  Включение подсветки соответствующих скобок
#+end_src

*** Cursor LIne
#+begin_src emacs-lisp
(global-hl-line-mode 1)                                   ;  cursor line
#+end_src

* main packages
** General keybindings
https://github.com/noctuid/general.el
*** Setup
#+begin_src emacs-lisp
(use-package general
  :ensure t
  :config
  (general-evil-setup)

  (general-create-definer spc-leader
    :states '(normal insert visual emacs)
    :keymaps 'override
    :prefix "SPC"   ;; set leader key
    :global-prefix "M-SPC")) ;; access leader in insert mode
#+end_src

*** KeyBind
#+begin_src emacs-lisp
(defun select-all ()
  "Выделить весь буфер."
  (interactive)
  (goto-char (point-min))
  (push-mark (point-max) nil t))

(spc-leader
  "8" '(save-buffer :wk "save file")
  "2" '(evil-quit :wk "quit file")
  "7" '(evil-first-non-blank :wk "first non blank")
  "9" '(evil-last-non-blank :wk "last non blank")
  "s a" '(select-all :wk "last non blank")

  "h r r" '((lambda () (interactive) (load-file "/home/fs/.emacs.d/init.el")) :wk "Reload emacs config")
)
#+end_src

** Window move
#+begin_src emacs-lisp
(global-unset-key (kbd "C-j"))

(global-set-key (kbd "C-h") 'windmove-left)  ;; Alt-h для перехода влево
(global-set-key (kbd "C-l") 'windmove-right) ;; Alt-l для перехода вправо
(global-set-key (kbd "C-k") 'windmove-up)    ;; Alt-k для перехода вверх
(global-set-key (kbd "C-j") 'windmove-down)  ;; Alt-j для перехода вниз
#+end_src

** Evil Mode
https://github.com/emacs-evil/evil
*** Setup
#+begin_src emacs-lisp
(use-package evil
  :ensure t
  :init
  (setq evil-want-integration t)
  (setq evil-want-keybinding nil)
  (setq evil-vsplit-window-right t)
  (setq evil-split-window-below t)
  (setq evil-want-C-u-scroll t)
  :config
  (evil-mode 1)
  (define-key evil-normal-state-map "p" 'evil-paste-after)
  (setq evil-kill-on-visual-paste nil)

  (define-key evil-normal-state-map (kbd ",") 'evil-scroll-up)
  (define-key evil-normal-state-map (kbd ".") 'evil-scroll-down)
  (define-key evil-normal-state-map (kbd "'") 'evil-execute-macro)
)

(use-package evil-collection
  :after evil
  :ensure t
  :config
  (setq evil-collection-mode-list '(dashboard dired ibuffer))
  (evil-collection-init))

(use-package evil-surround
  :ensure t
  :config
  (global-evil-surround-mode 1)
  (setq-default evil-surround-pairs-alist '((?\( . ("(" . ")"))
                                            (?\[ . ("[" . "]"))
                                            (?\{ . ("{" . "}"))
                                            (?\" . ("\"" . "\""))
                                            (?\` . ("`" . "`"))
                                            (?\' . ("'" . "'"))
                                            (?\) . ("(" . ")"))
                                            (?\] . ("[" . "]"))
                                            (?\} . ("{" . "}")))))
#+end_src

*** KeyBing
#+begin_src emacs-lisp
(use-package key-chord
  :ensure t
  :config
  (key-chord-mode 1)
  (key-chord-define evil-insert-state-map "jk" 'evil-normal-state)
  (key-chord-define evil-insert-state-map "kj" 'evil-normal-state))

(spc-leader
  "l l" 'evil-scroll-line-to-center)
#+end_src


** Ivy
пакет для Emacs, который предоставляет интерфейс для интерактивного выбора (completion) и навигации. Это часть экосистемы swiper и counsel и часто используется для упрощения работы с различными функциями Emacs

*** Setup
#+begin_src emacs-lisp
(use-package ivy
  :ensure t
  :config
  (ivy-mode 1)  ;; Включение Ivy
  :bind (:map ivy-minibuffer-map
              ("C-l" . ivy-immediate-done)  ;; Завершить без проверки
              ("RET" . ivy-done)            ;; Завершить выбор
              ("<return>" . ivy-done)       ;; Завершить выбор
              ("C-j" . ivy-next-line)       ;; Перейти к следующей строке
              ("C-k" . ivy-previous-line))  ;; Перейти к предыдущей строке
  :custom
  (ivy-use-virtual-buffers t)  ;; Показывать виртуальные буферы (например, недавние файлы)
  (ivy-count-format "(%d/%d) "))  ;; Показывать счетчик выбора

#+end_src

** Counsel
#+begin_src emacs-lisp
(use-package counsel
  :ensure t
  :config
  ;; Настройка команды fzf для counsel
  (setq counsel-fzf-cmd
        (concat
         "find . -type f -not -path '*/.*' 2>&1 | "
         "grep -v 'Permission denied' | "
         "grep -v './env/' | "
         "grep -v './fonts/' | "
         "grep -v './__pycache__/' | "
         "grep -v 'site-packages' | "
         "grep -v '.pyc' | "
         "grep -v '_minted' | "
         "fzf -f '%s'"))
  ;; Включение counsel для различных функций
  :bind (("M-x" . counsel-M-x)                ;; Улучшенная команда M-x
         ))

#+end_src

показывать ошибки при rg поиске
#+begin_src emacs-lisp
(with-eval-after-load 'counsel
  (advice-add 'counsel-rg
              :around
              (lambda (func &rest args)
                (cl-flet ((filter-func (code) (if (= code 2) 0 code)))
                  (unwind-protect
                      (progn (advice-add 'process-exit-status :filter-return #'filter-func)
                             (apply func args))
                    (advice-remove 'process-exit-status #'filter-func))))))
#+end_src


** dired
*** setup
#+begin_src emacs-lisp
(require 'dired)
(setq dired-listing-switches "-alXGh --group-directories-first"
      dired-recursive-copies 'always
      dired-recursive-deletes 'top
      global-auto-revert-non-file-buffers t
      auto-revert-verbose nil
      dired-dwim-target t
      wdired-allow-to-change-permissions t)

#+end_src

*** открыть файл в вертикально разделенном экране
#+begin_src emacs-lisp
(defun dired-open-split-horizontal ()
  "In dired, open current file in another window if exists, otherwise split window horizontally."
  (interactive)
  ;; Сохраняем путь текущего файла
  (let ((current-file (dired-get-file-for-visit)))
    ;; Проверяем, есть ли другое окно
    (if (one-window-p)
        (split-window-horizontally))
    ;; Переключаемся на другое окно
    (other-window 1)
    ;; Открываем файл или каталог, используя сохраненный путь
    (find-file current-file))
    (other-window 1)
)

(define-key dired-mode-map (kbd "s") 'dired-open-in-split-window)

(evil-define-key 'normal dired-mode-map (kbd "s") 'dired-open-split-horizontal)
(evil-define-key 'normal dired-mode-map (kbd "h") 'dired-up-directory)
#+end_src


*** dired subtree
#+begin_src emacs-lisp
(require 'dired-subtree)

(evil-define-key 'normal dired-mode-map (kbd "i") 'dired-subtree-insert)
(evil-define-key 'normal dired-mode-map (kbd "r") 'dired-subtree-remove)

#+end_src

*** открыть pcmanfm
#+begin_src emacs-lisp
(defun dired-open-pcmanfm ()
  "Open the current directory in Dired with PCManFM."
  (interactive)
  (let ((current-dir (dired-current-directory)))
    (start-process "pcmanfm" nil "pcmanfm" current-dir)))
#+end_src

*** функция для копирования текущего пути
#+begin_src emacs-lisp
(defun copy-current-file-path-to-clipboard ()
  "Copy the current buffer file name to the clipboard."
  (interactive)
  (let ((filename (if (equal major-mode 'dired-mode)
                      default-directory
                    (buffer-file-name))))
    (when filename
      (kill-new filename)
      (message "Copied buffer file name '%s' to the clipboard." filename))))
#+end_src

*** KeyBind
#+begin_src emacs-lisp
(spc-leader
  "d" '(:ignore t :wk "dired")
  "d o" '(dired :wk "open dired")

  "d c" '(:ignore t :wk "copy/crete")
  "d c c" '(dired-do-copy :wk "dired copy")
  "d c d" '(dired-create-directory :wk "create dir")
  "d c f" '(dired-create-empty-file :wk "crete file")
  "d c p" '(copy-current-file-path-to-clipboard :wk "copy file path to clipboard")
  "d r" '(dired-do-rename :wk "renema & move")

  "d p" '(:ignore t :wk "permissions")
  "d p p" '(dired-do-chmod :wk "chmod")
  "d p o" '(dired-do-chown :wk "chown")

  "d h" '(dired-hide-details-mode :wk "hide/show deteils")
)
#+end_src

** Image Viewer
#+begin_src emacs-lisp
(setq imagemagick-enabled-types '("PNG" "JPEG" "GIF" "TIFF"))
(setq image-use-external-converter t)
#+end_src

** openwith
#+begin_src emacs-lisp
(use-package openwith
  :ensure t
  :config
  (openwith-mode t)
  ;; :defer t
  )

(defun activate-openwith()
    (setq openwith-associations
        (list (list (openwith-make-extension-regexp '("pdf" "djvu"))
                    "atril" '(file))
              ;; (list (openwith-make-extension-regexp '("flac" "mp3" "wav"))
              ;;       "vlc" '(file))
              ;; (list (openwith-make-extension-regexp '("bmp" "jpeg" "jpg" "png" "webp"))
              ;;       "nsxiv -t " '(file))
              (list (openwith-make-extension-regexp '("mpv" "mkv" "mp4" "mov"))
                    "mpv" '(file))
              (list (openwith-make-extension-regexp '("doc" "docx" "odt"))
                    "libreoffice" '("--writer" file))
              (list (openwith-make-extension-regexp '("ods" "xls" "xlsx"))
                    "libreoffice" '("--calc" file))
              (list (openwith-make-extension-regexp '("odp" "pps" "ppt" "pptx"))
                    "libreoffice" '("--impress" file))
              ))
)

;; Отключить автоматическое открытие изображений в Emacs
(setq auto-mode-alist (rassq-delete-all 'image-mode auto-mode-alist))

;; Функция для отключения openwith-mode в org-mode
(defun disable-openwith-in-org-mode ()
  "Disable openwith-mode in org-mode."
  (when openwith-mode
    (openwith-mode -1)))

;; Добавляем хук для отключения openwith-mode в org-mode
(add-hook 'org-mode-hook 'disable-openwith-in-org-mode)
;; Добавляем хук для активации openwith-mode в dired-mode
(add-hook 'dired-mode-hook 'activate-openwith)


;; setup open when make frame
(defun setup/openwith ()
  "Activate openwith in Dired mode."
  (when (derived-mode-p 'dired-mode)
    (activate-openwith)))

(add-hook 'after-make-frame-functions
          (lambda (_frame)
            (with-current-buffer (current-buffer)
              (setup/openwith))))
#+end_src


** org-download
#+begin_src emacs-lisp
(require 'org-download)
(defun my-org-download-set-dir ()
        "Set `org-download-image-dir` to the directory of the current
        buffer's file."
        (setq-local org-download-image-dir (concat (file-name-directory
        (buffer-file-name)) "/images/" (file-name-base buffer-file-name) "/") ))

(add-hook 'org-mode-hook 'my-org-download-set-dir)
(add-hook 'dired-mode-hook 'org-download-enable)
#+end_src


** perspective
#+begin_src emacs-lisp
(use-package perspective
  :ensure t
  :config
  (setq persp-mode-prefix-key nil
        persp-suppress-no-prefix-key-warning t)
  (persp-mode))

(spc-leader
  "w" '(:ignore t :wk "workspace")
  "w i" '(persp-switch :wk "switch workspace")
  "w n" '(persp-next :wk "next workspace")
  "w p" '(persp-prev :wk "prev workspace")
  "w k" '(persp-kill :wk "kill workspace")
  "w r" '(persp-rename :wk "rename workspace")

  "w l" '(persp-state-load :wk "state load")
  "w s" '(persp-state-save :wk "state save")

  "w 1" '((lambda () (interactive) (persp-switch-by-number 1)) :wk "1")
  "w 2" '((lambda () (interactive) (persp-switch-by-number 2)) :wk "2")
  "w 3" '((lambda () (interactive) (persp-switch-by-number 3)) :wk "3")
  "w 4" '((lambda () (interactive) (persp-switch-by-number 4)) :wk "4")
  "w 5" '((lambda () (interactive) (persp-switch-by-number 5)) :wk "5")
  "w 6" '((lambda () (interactive) (persp-switch-by-number 6)) :wk "6")
  "w 7" '((lambda () (interactive) (persp-switch-by-number 7)) :wk "7")
  "w 8" '((lambda () (interactive) (persp-switch-by-number 8)) :wk "8")
  "w 9" '((lambda () (interactive) (persp-switch-by-number 9)) :wk "9")
)
#+end_src

** anzu
улучшенный интерфейс для поиска и замены текста
#+begin_src emacs-lisp
(use-package anzu
  :ensure t
  :config
)

(use-package evil-anzu
  :ensure t
  :after (evil anzu)
  :config
  (setq anzu-search-threshold 0)
  (setq anzu-cons-mode-line-p nil)
  (global-anzu-mode 1))
#+end_src

** doom-modeline
#+begin_src emacs-lisp
(use-package doom-modeline
  :ensure t
  :hook (after-init . doom-modeline-mode)  ;; Включает doom-modeline после инициализации Emacs
)
#+end_src

** NeoTree
*** Setup
#+begin_src emacs-lisp
(use-package neotree
  :init
  :ensure t
  :bind ("<f8>" . neotree-toggle)
  :config
  ;; Отображать файлы и папки на том же уровне
  (setq-default neo-smart-open t)
  ;; Вертикальное расположение окна neotree
  (setq neo-window-position 'left)

  ;; Активация пакетов
  (use-package all-the-icons :ensure t)
  (setq neo-theme (if (display-graphic-p) 'icons 'arrow))
  (setq neo-window-fixed-size nil)
  (setq neo-smart-open t)
  (setq neo-window-width 50)
  )

(add-hook 'neotree-mode-hook
          (lambda ()
            (define-key evil-normal-state-local-map (kbd "q") 'neotree-hide)
            (define-key evil-normal-state-local-map (kbd "RET") 'neotree-enter)
            (define-key evil-normal-state-local-map (kbd "g") 'neotree-refresh)
            (define-key evil-normal-state-local-map (kbd "f") 'neotree-create-node)
            ))
#+end_src

*** KeyBind
#+begin_src emacs-lisp
(spc-leader
  "c c" '(neotree-show :wk "toggle neoTree")
)
#+end_src

** file (copy file, open file in dired)
*** Dired function
#+begin_src emacs-lisp
(defun open-current-directory-in-dired ()
  "Open the current directory of the current file in Dired.
If a Dired buffer is already opened, navigate to that buffer."
  (interactive)
  (let ((dir (file-name-directory (or buffer-file-name default-directory))))
    (if (get-buffer-window (dired-noselect dir))
        (switch-to-buffer-other-window (dired-noselect dir))
      (dired-jump nil dir))))
#+end_src


*** transpose-frame
#+begin_src emacs-lisp
(use-package transpose-frame
  :ensure t
  :bind (
    ("C-t" . transpose-frame)
))
#+end_src

#+begin_src emacs-lisp
(spc-leader
  "f" '(:ignore t :wk "file/frame")
  "f t" '(transpose-frame :wk "transpose-frame")
  "f c" '(copy-file :wk "copy file")
  "f o" '(open-current-directory-in-dired :wk "open in dired"))
#+end_src


** bm-marks / org tangle
#+begin_src emacs-lisp
(spc-leader
  "m" '(:ignore t :wk "marks")
  "m a" '(bm-toggle :wk "toggle mark")
  ;; "m n" '(bm-next :wk "next mark")
  "m n" '(lambda () (interactive) (bm-next) (recenter) :wk "next mark")
  "m p" '(lambda () (interactive) (bm-previous) (recenter) :wk "prev mark")
  ;; "m p" '(bm-previous :wk "prev mark")
  "m l" '(bm-show :wk "list marks")
  "m g" '(lambda () (interactive) (bm-show-goto-bookmark) (recenter) :wk "goto bookmark")
  "m c" '(bm-remove-all-all-buffers :wk "claer mark")

  "m 8" '(org-babel-tangle :wk "org-babel-tangle"))

(setq bm-marker 'bm-marker-left)
(setq bm-highlight-style nil)
(setq bm-highlight-style 'bm-highlight-only-fringe)
(custom-set-faces
 '(bm-face ((t (:background "yellow" :foreground "black" :weight bold)))))
#+end_src

** project / projectile
*** setup projectile
#+begin_src emacs-lisp
(use-package projectile
  :ensure t
  :init
  (projectile-mode +1)
  :config
  (setq projectile-completion-system 'ivy))
#+end_src

*** KeyBind

add and switch project
#+begin_src emacs-lisp
(defun projectile/open-and-switch-project (directory)
  " - "
  (interactive (list (read-directory-name "What directory? ")))
  (let (
    (projectile-file-path (concat directory "/.projectile"))
    (git-directory-path (concat directory "/.git")))
    (unless (file-directory-p git-directory-path)
      (unless (file-exists-p projectile-file-path)
        (make-empty-file projectile-file-path)))
    (projectile-add-known-project directory)))
#+end_src


*** Search M-x commands with fzf
#+begin_src emacs-lisp
(use-package fzf
  :ensure t
  :init (setenv "FZF_DEFAULT_COMMAND" "fd --type f")
)
#+end_src

hot keys
#+begin_src emacs-lisp
(spc-leader
  "," '(find-file :wk "find file")
  "SPC" '(counsel-fzf :wk "fzf find file")
  "." '(swiper :wk "swiper")

  "p" '(:ignore t :wk "projectile")
  "p a" '(projectile/open-and-switch-project :wk "add project and switch")
  "p s" '(projectile-switch-project :wk "switch project")
  "p g" '(counsel-rg :wk "project tile grep")
  ;; "p g" '(lambda () (interactive) (counsel-rg) (recenter) :wk "project tile grep")

  "b i" '(projectile-ibuffer :wk "Switch buffer")
  "b n" '(projectile-next-project-buffer :wk "next project buffer")
  "b p" '(projectile-previous-project-buffer :wk "previous project buffer"))

#+end_src

** buffer & bookmarks & harpoon
#+begin_src emacs-lisp
(spc-leader
  ;; buffer
  "b" '(:ignore t :wk "buffer")
  ;; "b i" '(counsel-ibuffer :wk "Switch ibuffer")
  "b i" '(ibuffer :wk "Switch ibuffer")
  "b c" '(counsel-ibuffer :wk "counsel Switch ibuffer")
  "b b" '(projectile-switch-to-buffer :wk "Switch buffer")
  "b m" '(rename-buffer :wk "rename buffer")

  "b k" '(:ignore t :wk "kill buffer")
  "b k t" '(kill-this-buffer :wk "Kill this buffer")
  "b k k" '(kill-buffer :wk "Kill buffer in imenu")

  ;; bookmark
  "b s" '(bookmark-set :wk "set bookmarks")
  "b d" '(bookmark-delete :wk "delete bookmarks")
  "b l" '(list-bookmarks :wk "list bookmarks")
  "b j" '(bookmark-jump :wk "list jump")
  "b a" '(bookmark-set :wk "bookmarks set")
  "b r" '(revert-buffer :wk "Reload buffer"))

(spc-leader
  )

(spc-leader
  "TAB" '(:ignore t :wk "?")
  "TAB TAB" '(comment-line :wk "comment line")
)

(spc-leader
  "h" '(:ignore t :wk "help & harpoon")
  "h a" '(harpoon-add-file :wk "add to harpoon")
  "h c" '(harpoon-clear :wk "harboon clear")
  "h l" '(harpoon-toggle-quick-menu :wk "toggle menu")
  "h m" '(harpoon-quick-menu-hydra :wk "quick menu")

  "h 1" '(harpoon-go-to-1 :wk "1")
  "h 2" '(harpoon-go-to-2 :wk "2")
  "h 3" '(harpoon-go-to-3 :wk "3")
  "h 4" '(harpoon-go-to-4 :wk "4")
  "h 5" '(harpoon-go-to-5 :wk "5")

  "h d" '(harpoon-delete-item :wk "delete item")
)
#+end_src



** Sudo Edit & code (sudo edit/split/perfect margin/json)
*** Perfect margin settings
#+begin_src emacs-lisp
;; (setq perfect-margin-visible-width 150)
(setq perfect-margin-visible-width 180)
#+end_src

*** KeyBind
#+begin_src emacs-lisp
(require 'sudo-edit)
(spc-leader
  "c" '(:ignore t :wk "code")
  "c s" '(sudo-edit :wk "sudo-edit")
  "c u" '(comment-line :wk "comment line")

  "s" '(:ignore t :wk "split window")
  "s h" '(split-window-right :wk "split window horizontaly")
  "s v" '(split-window-below :wk "split window verticalty")

  "c p" '(perfect-margin-mode :wk "center")
  "c j" '(json-pretty-print :wk "json")
)
#+end_src

** Magit
#+begin_src emacs-lisp
(require 'magit)
  (spc-leader
    "g" '(:ignore t :wk "git")
    "g g" '(magit :wk "magit")
    "g a" '(magit-stage-buffer-file :wk "add curent file")
    "g u" '(magit-unstage-buffer-file :wk "unstage current file")

    "g l" '(:ignore t :wk "log")
    "g l g" '(magit-log-current :wk "log")
    "g l l" '(magit-log-buffer-file :wk "log buffer")

    "g c" '(magit-commit-create t :wk "commit")

    "g b" '(:ignore t :wk "branch")
    "g b b" '(magit-branch-checkout t :wk "checkout")
    "g b c" '(magit-branch-create t :wk "create branch")
    "g b p" '(magit-pull-branch t :wk "pull")

    "g s" '(:ignore t :wk "stash")
    "g s s" '(magit-stash t :wk "stash")
    "g s p" '(magit-stash-pop t :wk "stash pop")

    "g d" '(:ignore t :wk "diff")
    "g d d" '(magit-diff-buffer-file :wk "log buffer")
    "g d g" '(magit-diff-unstaged :wk "diff unstaged buffer")
    "g d s" '(magit-diff-staged :wk "diff staged buffer")

    "g f" '(magit-fetch :wk "fetch")
  )
#+end_src

* ORG settings
** org hot key
#+begin_src emacs-lisp
(spc-leader
  "o" '(:ignore t :wk "org hot key")
  "o c" '(org-time-stamp :wk "calendar paste date")
  "o l" '(org-shiftmetaright :wk "move metric right")
  "o h" '(org-shiftmetaleft :wk "move metric left")
  "o t" '(org-tree-to-indirect-buffer :wk "tree to inderect buffer")
  "o o" '(org-cycle-global :wk "org cycle global")
  "o ;" '(org-cycle :wk "org cycle global")
  "o i" '(org-display-inline-images :wk "display image")

  "o m" '(org-babel-execute-src-block :wk "org babel execute")
  "o e" '(org-edit-src-code :wk "org babel execute")
  "o r" '(org-reset-checkbox-state-subtree :wk "reset checkboxs")
  "o g" '(org-agenda :wk "org agenda")
  "o m" '(eval-buffer :wk "eval buffer")
  "o k" '(org-ctrl-c-minus :wk "eval buffer")

  "h RET" '(org-meta-return :wk "org return (insert lists))")
)

(with-eval-after-load 'org
  (define-key org-mode-map (kbd "M-h") nil))
#+end_src

** Org Temo chet sheet
| Typing the below + TAB | Expands to ...                          |
|------------------------+-----------------------------------------|
| <a                     | '#+BEGIN_EXPORT ascii' … '#+END_EXPORT  |
| <c                     | '#+BEGIN_CENTER' … '#+END_CENTER'       |
| <C                     | '#+BEGIN_COMMENT' … '#+END_COMMENT'     |
| <e                     | '#+BEGIN_EXAMPLE' … '#+END_EXAMPLE'     |
| <E                     | '#+BEGIN_EXPORT' … '#+END_EXPORT'       |
| <h                     | '#+BEGIN_EXPORT html' … '#+END_EXPORT'  |
| <l                     | '#+BEGIN_EXPORT latex' … '#+END_EXPORT' |
| <q                     | '#+BEGIN_QUOTE' … '#+END_QUOTE'         |
| <s                     | '#+BEGIN_SRC' … '#+END_SRC'             |
| <v                     | '#+BEGIN_VERSE' … '#+END_VERSE'         |

** toc
#+begin_src emacs-lisp
(require 'toc-org nil t)
   (add-hook 'org-mode-hook 'toc-org-enable)
   (add-hook 'org-mode-hook 'org-indent-mode)
   ; (setq toc-org-max-depth 2)

(require 'org-bullets)
  (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))

(require 'org-bullets)
  (which-key-mode 1)

    (setq which-key-min-display-lines 13)

(require 'org-tempo)

;;(electric-indent-mode -1)
(setq org-edit-src-content-indentation 0)
#+end_src

** org babel execute
#+begin_src emacs-lisp
;; Разрешить выполнение кода в org-mode
(org-babel-do-load-languages
 'org-babel-load-languages
 '((python . t)
   (shell . t)))

(setq org-src-tab-acts-natively t)
;; Отключить запросы на подтверждение выполнения кода
(setq org-confirm-babel-evaluate nil)
#+end_src

** org agenda
#+begin_src emacs-lisp
(custom-set-variables
'(org-agenda-files
   '("~/Documents/work.org" "/home/fs/Documents/dates.org" "/home/fs/Documents/time.org")))
#+end_src

** Org Image
#+begin_src emacs-lisp
(setq org-image-actual-width '(500))
#+end_src

** org level size
#+begin_src emacs-lisp
;; Установка стилей для заголовков
(custom-set-faces
 '(org-level-1 ((t (:height 1.5 :weight bold))))
 '(org-level-2 ((t (:height 1.3 :weight bold))))
 '(org-level-3 ((t (:height 1.2))))
 '(org-level-4 ((t (:height 1.1)))))
#+end_src

** org level hide
Скрывает заголовки, у которых есть подчёркивание после звёздочек.

#+begin_src emacs-lisp
(defun my/org-hide-matching-headlines ()
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "^\\*+ _" nil t)
      (outline-hide-subtree))))

(add-hook 'org-mode-hook #'my/org-hide-matching-headlines)
#+end_src


* PROGRAMMING
** snipets
#+begin_src emacs-lisp
(use-package yasnippet
  :ensure t
  :config
  (yas-global-mode 1))
#+end_src

** python
#+begin_src emacs-lisp
(defun load-python-config ()
  (org-babel-load-file
    (expand-file-name
     "lan/python-cf.org"
     user-emacs-directory)))

(add-hook 'python-mode-hook 'load-python-config)
#+end_src

** go
#+begin_src emacs-lisp
(defun load-go-config ()
  (org-babel-load-file
    (expand-file-name
     "lan/go-cf.org"
     user-emacs-directory)))

(add-hook 'go-mode-hook 'load-go-config)
#+end_src

** Emacs-lisp
#+begin_src emacs-lisp
(use-package highlight-function-calls
  :ensure t
  :config
  (add-hook 'emacs-lisp-mode-hook 'highlight-function-calls-mode))
#+end_src

* decorations
** colorthemes
#+begin_src emacs-lisp
(custom-set-faces
;; '(line-number ((t (:foreground "white"))))               ; Цвет отображения номера строки
;; '(line-number-current-line ((t (:foreground "white"))))) ; Цвет текущей строки
;; '(org-block-background ((t (:background "#1b1b1b"))))
'(line-number ((t (:foreground "black"))))               ; Цвет отображения номера строки
'(line-number-current-line ((t (:foreground "black"))))) ; Цвет текущей строки
;; (load-theme 'doom-1337 t)
;; (load-theme 'doom-nord t)
;; (load-theme 'doom-nord-aurora t)
;; (load-theme 'doom-nord-light t)
;; (load-theme 'doom-ayu-light t)
;; (load-theme 'doom-city-lights t)
;; (load-theme 'doom-one-light t)
;; (load-theme 'doom-gruvbox-light t)
;; (load-theme 'doom-gruvbox t)
;; (load-theme 'doom-ayu-dark t)
;; (load-theme 'doom-dracula t)
;; (load-theme 'doom-tomorrow-night t)
;; (load-theme 'doom-henna t)
(load-theme 'doom-one t)
;; (load-theme 'doom-opera t)
;; (load-theme 'doom-monokai-pro t)
;; (load-theme 'doom-spacegrey t)
;; (load-theme 'doom-tokyo-night t)
;; (load-theme 'doom-xcode t)
;; (load-theme 'doom-solarized-light t)
;; (load-theme 'doom-solarized-dark t)
;; (load-theme 'solarized-gruvbox-light t)
;; (load-theme 'solarized-gruvbox-dark t)

;; (add-to-list 'custom-theme-load-path "~/.emacs.d/everforest-theme")
;; (load-theme 'everforest-hard-dark t)

;; (add-to-list 'custom-theme-load-path "~/.emacs.d/atom-one-dark-theme")
;; (load-theme 'atom-one-dark t)

;; (add-to-list 'custom-theme-load-path "~/.emacs.d/iceberg-theme.el")
;; (load-theme 'iceberg t)


;; (set-frame-parameter nil 'alpha-background 100)
;; (set-frame-parameter nil 'alpha-background 92)

(let ((al 90))  ;; Прозрачность %
  (set-frame-parameter (selected-frame) 'alpha `(,al . ,al))   ;; Прозрачность для текущего фрейма
  (add-to-list 'default-frame-alist `(alpha . (,al . ,al))))   ;; Прозрачность для всех новых фреймов

#+end_src

** diff
состоянии изменений git
#+begin_src emacs-lisp
(global-diff-hl-mode +1)
#+end_src

** fonts
#+begin_src emacs-lisp
; Makes commented text and keywords italics.
; This is working in emacsclient but not emacs.
; Your font must have an italic face available.
(set-face-attribute 'font-lock-comment-face nil
  :slant 'italic)
(set-face-attribute 'font-lock-keyword-face nil
  :slant 'italic)

; Firacode Nerd Font
; JetBrainsMonoNL Nerd Font
; CaskaydiaCove Nerd Font

(defun set-small-font-wayland ()
  (interactive)
  (set-face-attribute 'default nil
                      :font "JetBrainsMonoNL Nerd Font"
                      :height 110
                      :weight 'medium))

(defun set-small-font ()
  (interactive)
  (set-face-attribute 'default nil
                      :font "JetBrainsMonoNL Nerd Font"
                      :height 110
                      :weight 'medium))

(defun set-big-font ()
  (interactive)
  (set-face-attribute 'default nil
                      :font "JetBrainsMonoNL Nerd Font"
                      :height 130
                      :weight 'medium))

(defun set-large-font ()
  (interactive)
  (set-face-attribute 'default nil
                      :font "JetBrainsMonoNL Nerd Font"
                      :height 200
                      :weight 'medium))
;; (set-small-font-wayland)
;; (set-small-font)
(set-big-font)
(spc-leader
  "c f" '(:ignore t :wk "font")
  "c f s" '(set-small-font :wk "small font")
  "c f b" '(set-big-font :wk "big font")
  "c f l" '(set-large-font :wk "l font"))

;; This sets the default font on all graphical frames created after restarting Emacs.
;; Does the same thing as 'set-face-attribute default' above, but emacsclient fonts
;; are not right unless I also add this method of setting the default font.
(add-to-list 'default-frame-alist '(font . "JetBrainsMonoNL Nerd Font"))

;; Uncomment the following line if line spacing needs adjusting.
(setq-default line-spacing 0.12)

#+end_src

** ligature
#+begin_src emacs-lisp
(use-package ligature
  :config
  ;; Enable the "www" ligature in every possible major mode
  (ligature-set-ligatures 't '("www"))
  ;; Enable traditional ligature support in eww-mode, if the
  ;; `variable-pitch' face supports it
  (ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi"))
  ;; Enable all Cascadia Code ligatures in programming modes
  (ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
                                       ":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
                                       "!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
                                       "<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
                                       "<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
                                       "..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
                                       "~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
                                       "[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
                                       ">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
                                       "<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
                                       "##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
                                       "?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
                                       "\\\\" "://"))
  ;; Enables ligature checks globally in all buffers. You can also do it
  ;; per mode with `ligature-mode'.
  (global-ligature-mode t))
#+end_src


** icons
#+begin_src emacs-lisp
(require 'all-the-icons)
(require 'all-the-icons-dired)
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode)
#+end_src

** rainbow mode
This minor mode sets background color to strings that match color
names, e.g. #0000ff is displayed in white with a blue background.
#+begin_src emacs-lisp
(require 'rainbow-mode)
(add-hook 'org-mode-hook 'rainbow-mode)
(add-hook 'prog-mode-hook 'rainbow-mode)
#+end_src

** Nyan-mode
#+begin_src emacs-lisp
(use-package nyan-mode
  :ensure t
  :init
  :config
  (setq nyan-wavy-trail t)
  (setq nyan-animate-nyancat t)
  (nyan-mode 1)) ;; Включить анимацию
#+end_src

** evil-snipe
#+begin_src emacs-lisp
(require 'evil-snipe)
(evil-snipe-mode +1)
(evil-snipe-override-mode +1)
(setq evil-snipe-smart-case +1)
#+end_src

** org chckbox hl
#+begin_src emacs-lisp
(defface org-checkbox-done-text
     '((t (:inherit org-done)))
     "Face for the text part of a checked org-mode checkbox.")

 (font-lock-add-keywords
  'org-mode
  `(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)" 1 'org-checkbox-done-text prepend))
  'append)
#+end_src

** hl-todo
#+begin_src emacs-lisp
(require 'hl-todo)
(add-hook 'prog-mode-hook 'hl-todo-mode)
#+end_src

* Programs
** emms
#+begin_src emacs-lisp
;; Функция для отображения только названия треков в плейлисте
(defun my-emms-track-simple-description (track)
  "Return a simple description of the TRACK with only the title."
  (let ((name (emms-track-get track 'info-title)))
    (if name
        name
      (emms-track-simple-description track))))


(use-package emms
  :init
  (setq emms-track-description-function 'my-emms-track-simple-description)
  :ensure t
  :config
  (require 'emms-setup)
  (emms-all)  ;; Загружает все основные модули Emms
  (emms-default-players)  ;; Определяет плееры
  (setq emms-source-file-default-directory "~/Music/")  ;; Укажите свою папку с музыкой

  ;; Отображение текущего трека в mode-line
  (use-package emms-mode-line
    :config
    (emms-mode-line 1))

  ;; Включить отображение времени проигрывания
  (use-package emms-playing-time
    :config
    (emms-playing-time 1))

  (with-eval-after-load 'emms
    (define-key emms-playlist-mode-map (kbd "l") 'emms-seek-forward)
    (define-key emms-playlist-mode-map (kbd "h") 'emms-seek-backward)
    (define-key emms-playlist-mode-map (kbd "s") 'emms-pause)
    (define-key emms-playlist-mode-map (kbd "C-c k") 'emms-playlist-clear)

    (define-key emms-playlist-mode-map (kbd "j") 'next-line)
    (define-key emms-playlist-mode-map (kbd "C-j") 'next-line)
    (define-key emms-playlist-mode-map (kbd "k") 'previous-line)
    (define-key emms-playlist-mode-map (kbd "C-k") 'previous-line)

    (define-key emms-playlist-mode-map (kbd "C-u") 'scroll-down-command)
    (define-key emms-playlist-mode-map (kbd "C-d") 'scroll-up-command)

    (define-key emms-playlist-mode-map (kbd "d") 'emms-playlist-mode-kill-track)

    (define-key emms-playlist-mode-map (kbd "/") 'evil-search-forward)
    (define-key emms-playlist-mode-map (kbd "C-n") 'evil-search-next)
    (define-key emms-playlist-mode-map (kbd "C-p") 'evil-search-previous)
  )
)

;; Включаем Evil mode в плейлисте EMMS
(add-hook 'emms-playlist-mode-hook 'evil-normalize-keymaps)

(spc-leader
  "e" '(:ignore t :wk "music")
  "e d" '(emms-add-dired :wk "add dired tree to playlist")
  "e t" '(emms-add-directory-tree :wk "dir tree to playlist")
  "e r" '(emms :wk "emms")
  "e a" '(emms-toggle-repeat-track :wk "repeat track")
  "e s" '(emms-pause :wk "stop")
  "e k" '(emms-next :wk "next")
  "e j" '(emms-previous :wk "previous")
  ;; "e w" '(emms :wk "save playlist")
  "e i" '(emms-seek-forward :wk "seek-forward 10s")
  "e u" '(emms-seek-backward :wk "seek-backward 10s")

  "e p" '(:ignore t :wk "music playlist load/save")
  "e p s" '(emms-playlist-save :wk "save playlist")
  "e p l" '(emms-play-m3u-playlist :wk "load playlist")
)
#+end_src

** Latex (pdf)
*** Warning
#+begin_quote
PLEASE READ THIS WARNING ***********************************

The following (inessential) packages failed to install properly:

  yb-book

You can fix this by running this command:
  tlmgr update --all --reinstall-forcibly-removed
to complete the installation.

However, if the problem was a failure to download (by far the
most common cause), check that you can connect to the chosen mirror
in a browser; you may need to specify a mirror explicitly.
******************************************************************
#+end_quote

*** Install
чтобы экспорт работал кректно надо установить pygments
=pip install pygments= но для arch linux =sudo pacman -S python-pygments=

установка из стандартных репозиториев арча не дает результатов, нужно устанавливать в ручную
https://tug.org/texlive/quickinstall.html

*** setting
#+begin_src emacs-lisp
(setq org-latex-pdf-process
      '("xelatex -interaction nonstopmode %f"
        "xelatex -interaction nonstopmode %f"))

#+end_src

*** настройка каталога PATH
#+begin_src emacs-lisp
;; Указываем путь к каталогу LaTeX
(setenv "PATH" (concat "/usr/local/texlive/2024/bin/x86_64-linux:" (getenv "PATH")))
(setq exec-path (append '("/usr/local/texlive/2024/bin/x86_64-linux") exec-path))
(executable-find "mktexlsr")

(setq org-latex-compiler "xelatex")  ;; Используйте "lualatex", если хотите использовать LuaTeX
#+end_src

*** включить подсветку синтаксиса
#+begin_src emacs-lisp
;; Использовать minted для подсветки синтаксиса при экспорте в PDF через LaTeX
(setq org-latex-listings 'minted)

;; Добавить настройки minted в preamble
(setq org-latex-packages-alist '(("" "minted")))
#+end_src

*** Настройка процесса экспорта в PDF для Org Mode
#+begin_src emacs-lisp
(setq org-latex-pdf-process
      '("xelatex -interaction nonstopmode -output-directory %o %f"
        "xelatex -interaction nonstopmode -output-directory %o %f"))
#+end_src

*** Cheat sheet
**** дефолтный header
#+begin_src tex
#+LATEX_HEADER: \hypersetup{colorlinks=true, linkcolor=black}     ;; убрать красную подсветку из ссылок
#+LATEX_HEADER: \usepackage{fontspec}                             ;; подтержка русского языка
#+LATEX_HEADER: \setmainfont{Noto Sans}                           ;; шрифт
#+LATEX_CLASS_OPTIONS: [7pt]                                      ;; размер шрифта
#+end_src

**** отступы от границ
#+begin_src tex
#+LATEX_HEADER: \usepackage[a4paper, left=2cm, right=2cm, top=2.5cm, bottom=2.5cm]{geometry}
#+end_src

a4paper — формат бумаги (можно поменять на letterpaper или другой, если требуется).
left=2cm, right=2cm, top=2.5cm, bottom=2.5cm — отступы от левой, правой, верхней и нижней границы страницы, соответственно. можно изменить эти значения на нужные размеры в сантиметрах (или дюймах, используя in).

** Terminal
*** Open terminal with random buffer name
#+begin_src emacs-lisp
(defun run-buffer-random (command)
  "Open a shell and rename its buffer to shell-<randomname>."
  (let ((random-name (format "shell-%s" (make-temp-name ""))) ; Генерируем случайное имя
        (shell-buffer (funcall command))) ; Запускаем shell
    (with-current-buffer shell-buffer
      (rename-buffer random-name t)))) ; Переименовываем буфер

(defun open-eshell-on-right ()
  "Open a terminal in a new right split window with a randomly named buffer."
  (interactive)
  (let ((term-buffer (generate-new-buffer (format "eshell-%s" (make-temp-name "")))))
    (set-window-buffer (split-window-right) term-buffer)
    (select-window (get-buffer-window term-buffer))
    (eshell term-buffer)))

(defun rand-eshell ()
  (interactive)
  (run-buffer-random #'eshell)) ; Передаем функцию как объект

(defun rand-shell ()
  (interactive)
  (run-buffer-random #'vterm)) ; Передаем функцию как объект

(defun default-terminal ()
  (interactive)
  (run-buffer-random #'eshell))
#+end_src

*** scripts
**** fuzzy cd by main dirs
#+begin_src emacs-lisp
(defun counsel-find-dirs ()
  "Search directories with `find` and display results in Ivy."
  (interactive)
  (let* ((paths '("/home/fs/Desktop/pet"
                  "/home/fs/Desktop/tmp"
                  "/home/fs/Desktop/work"))
         (find-command (concat "find "
                               (mapconcat #'shell-quote-argument paths " ")
                               " -maxdepth 2 -type d ! -readable -prune -o -print"))
         (results (split-string (shell-command-to-string find-command) "\n" t)))
    (ivy-read "Select directory: " results
              :action (lambda (dir)
                        (when (file-directory-p dir)
                          (dired dir))))))
#+end_src

**** цвета
#+begin_src emacs-lisp
(add-hook 'eshell-preoutput-filter-functions
          'ansi-color-apply)

(setenv "TERM" "xterm-256color")
#+end_src

*** open terminal
#+begin_src emacs-lisp
(spc-leader
  "t" '(:ignore t :wk "terminal")
  "t e" '(rand-eshell :wk "run emacs shell")
  "t s" '(rand-shell :wk "run standart shell")
  "t t" '(open-eshell-on-right :wk "eshell on right")
)
#+end_src

*** Vterm
#+begin_src emacs-lisp
(use-package eshell-vterm
  :load-path "site-lisp/eshell-vterm"
  :demand t
  :after eshell
  :config
  (eshell-vterm-mode))
#+end_src

**** Vterm paste
#+begin_src emacs-lisp
(with-eval-after-load 'evil
  (add-hook 'vterm-mode-hook
            (lambda ()
              ;; Назначение hjkl как стрелок в normal state
              (evil-define-key 'normal vterm-mode-map
                "p" 'vterm-yank
                "h" (lambda () (interactive) (vterm-send-key "<left>"))
                "j" (lambda () (interactive) (vterm-send-key "<down>"))
                "k" (lambda () (interactive) (vterm-send-key "<up>"))
                "l" (lambda () (interactive) (vterm-send-key "<right>"))))))
#+end_src

* EXWM
** setup windows hotkey
*** ace window (для перемещения по окнам)
#+begin_src emacs-lisp
(use-package ace-window
  :ensure t
  :bind (
    ("M-s" . ace-swap-window))
  :config
  (setq aw-swap-other-window t))
#+end_src


** setup wm
#+begin_src emacs-lisp
;; (org-babel-load-file
;;     (expand-file-name
;;      "lib/ex.org"
;;      user-emacs-directory))
#+end_src

* Apps
#+begin_src emacs-lisp
(org-babel-load-file
    (expand-file-name
     "lib/app.el"
     user-emacs-directory))
#+end_src

** Text Processor
#+begin_src emacs-lisp
(org-babel-load-file
    (expand-file-name
     "lib/text-processor.el"
     user-emacs-directory))
#+end_src

** Image Processor
#+begin_src emacs-lisp
(org-babel-load-file
    (expand-file-name
     "lib/image.el"
     user-emacs-directory))
#+end_src

* scripts
** add projectile project
#+begin_src emacs-lisp
(defun create-empty-projectile-file ()
  "Create an empty .projectile file in the current directory."
  (interactive)
  (let ((projectile-file ".projectile"))
    (if (file-exists-p projectile-file)
        (message ".projectile file already exists in this directory.")
      (write-region "" nil projectile-file)
      (message ".projectile file created successfully."))))
#+end_src

** REST
#+begin_src emacs-lisp
(defun send-easy-http ()
  (interactive)
  (let (
	(output-buffer (get-buffer-create "*Rest Output*"))
	(command (concat "/home/fs/bin/http " buffer-file-name " " (projectile-project-root))))
    (save-buffer)
	(unless (get-buffer-window output-buffer)
	    (split-window-right)
	    (other-window 1)
	    (switch-to-buffer output-buffer)
	    (other-window -1))
	(with-current-buffer output-buffer
	    (js-mode)
        (erase-buffer)
        (shell-command command output-buffer)
        (goto-char (point-max)))
	(message command)))

(require 'restclient)
(add-to-list 'auto-mode-alist '("\\.http\\'" . restclient-mode))

(spc-leader
  "r" '(:ignore t :wk "rest")
  "r s" '(send-easy-http :wk "send http")
  "r a" '(create-empty-projectile-file :wk "create projectile file")
)
#+end_src

** insert some text
*** insert results output
#+begin_src emacs-lisp
(defun insert-results-output ()
  (interactive)
  (insert " :results output")
)
#+end_src

*** insert org babel tangle
#+begin_src emacs-lisp
(defun insert-org-tangle ()
  (interactive)
  (insert " :tangle change_file.ext")
)
#+end_src

*** insert latex header
#+begin_src emacs-lisp
(defun insert-latex-header ()
  (interactive)
  (insert "#+LATEX_HEADER: \\hypersetup{colorlinks=true, linkcolor=black}\n")
  (insert "#+LATEX_HEADER: \\usepackage{fontspec}\n")
  (insert "#+LATEX_HEADER: \\setmainfont{Noto Sans}\n")
  (insert "#+LATEX_CLASS_OPTIONS: [11pt]\n")
)
#+end_src

*** keybind
#+begin_src emacs-lisp
(spc-leader
  "i c" '(insert-results-output :wk " :results output")
  "i m  " '(insert-org-tangle :wk " :tangle change_file.ext")
  "i l  " '(insert-latex-header :wk "latex header")
)
#+end_src
