source: dotfiles/emacs/.emacs.d/.emacs-config.org@ fe2941b

Last change on this file since fe2941b was fe2941b, checked in by Mikhail Kirillov <w96k@…>, on Aug 29, 2024 at 8:43:49 PM

Remove delete-selection-mode

  • Property mode set to 100644
File size: 52.6 KB
RevLine 
[3600aa2]1#+TITLE: Конфигурация Emacs
[1c49a32]2#+AUTHOR: Кириллов <w96k.dev> Михаил
[e915268]3#+OPTIONS: toc:nil
4#+PROPERTY: header-args:elisp :results silent
[3600aa2]5#+STARTUP: showeverything
[e915268]6
[128f35c]7* Вклады
[8e15ad4]8Конфигурация составлена из моего кода, а также кода из конфигураций
9других людей. Их настолько, что все перечислять я не смогу, но оставлю
10интересные конфигурации других людей, в которые я время от времени
11заглядываю.
12
13* Лицензия
14Я выступаю против копирайта и интеллектуальной собственности в целом,
15поэтому стараюсь копирайт избегать. По этой причине свой код
16распространяю на правах общественного достояния вашей страны. Для этого
17используется лицензия [[https://creativecommons.org/publicdomain/zero/1.0/][CC0]]. Если кратко, то можете использовать без
18ограничений вплоть до полной приватизации всего контента. К сожалению за
19чужие сниппеты не могу ручаться, они распространяются по своим лицензиям
20и я их не указывал, впрочем всё равно никто это не проверяет и я бы не
21стал напрягаться из-за авторских прав на конфигурацию текстового
22редактора.
[fe668ae]23
[9691479]24* О конфигурации
[8e15ad4]25Минимальная конфигурация Emacs. Пакеты ставлю через Guix или package.el
26(elpa и melpa), для разделения ответственности использую грамотное
27программирование при помощи org-mode.
[4b9efc5]28
29Версия Emacs 28+.
[cd4bc41]30- В Guix пакет ~emacs-next~
31- В FreeBSD пакет ~emacs-devel~
32- В Ubuntu [[https://launchpad.net/~kelleyk/+archive/ubuntu/emacs][PPA emacs28]] и пакет ~emacs28-native~
[8658e39]33
[51683a8]34Из программирования поддерживаются /C/, Java, /Python/, /Common Lisp /
[455c59b]35Scheme/, Haskell, Idris, Ocaml, /Ruby/, PHP, /SML/, SQL, Erlang,
36редактирование веб-шаблонов и различных форматов конфигураций. Какие-то
37языки в лучшей мере настроены, какие-то хуже, но есть почти все
38плюс-минус популярные.
[51683a8]39
[455c59b]40Для систем контроля версий использую встроенный /VC/ и в некоторых случаях
41/Magit/. Для входа в виртуальные среды используется Direnv.
[b4442d3]42
43Для ведения заметок использую методологию Zettelkasten при помощи
[51683a8]44org-roam. Для доступа к оффлайн википедии и другим ресурсам Kiwix
45клиент, который стучится на сервер, который стоит дома.
[b4442d3]46
[66375ed]47Для коммуникаций клиент для Telegram /telega/, для IRC /erc/ и электронной
[51683a8]48почты /gnus/, для Mastodon mastodon.el.
49
50Для системного администрирования имеют пакеты для работы с Debian,
51NixOS, Guix. Также есть поддержка Docker, Docker-compose: можно
52запускать/стопать контейнеры, а также залетать в них через TRAMP.
[66375ed]53
[ecd7710]54Для установки необходимо установить пакеты Emacs из ~../../guix/user.scm~
[bb02749]55и выполнить tangle файла при помощи /M-x org-babel-tangle-file/. В
56дальнейшем для развёртывания конфигурации можно использовать /M-x
57config-tangle/ или /M-x config-load/.
[128f35c]58
[51683a8]59Данная конфигурация доступна также в сети интернет по адресу, но так как
60сайт обновляется нечасто, то там может лежать старая версия:
61https://w96k.dev/emacs.html
62
63Исходники конфигурации лежат на Sourcehut:
64https://git.sr.ht/~w96k/dotfiles/tree/master/item/emacs
[128f35c]65
66Распространяется на условиях свободной лицензии [[https://gnu.org/licenses/gpl-3.0.ru.html][GNU GPL v3]],
67реиспользование одобряется пока распространяется под той же лицензией.
68
[337b6de]69* Пакеты
[4b9efc5]70Данная конфигурация использует следующие пакеты:
[7b7467e]71
72- Avy :: Прыжки по тексту
73- Anaconda :: Поддержка Python
74- Auctex :: Поддержка Tex и LaTeX
75- Browse Kill Ring :: Обзор буфера обмена
76- Haskell Mode :: Поддержка языка Haskell
77- Idris Mode :: Поддержка языка Idris
78- Magit :: Интерфейс к git
79- Gitpatch :: Создание патчей
80- Goto Cgh :: Переход к последнему изменению в буфере
81- Debbuge :: Интерфейс debbugs (репорт багов Debian)
82- Deft :: Полнотекстовый поиск
83- Direnv :: Изменение окружения при "входе" в директорию
84- Docker и Docker Compose :: Моды для поддержки контейнерных технологий
85- Exec Path From Shell :: Синхронизация PATH переменной из шелла
86- Expand Region :: Семантическое расширение выделения на курсоре
87- Robe :: Прыжки по определениям Ruby
88- Geiser :: Repl для языка Scheme
89- Guix :: Интерфейс к Guix
90- Org Roam :: Zettelkasten заметки в org-mode
91- Gnuplot :: Программное рисование графиков
92- Nix Mode :: Поддержка языка Nix
93- Pdf Tools :: Рендер PDF файлов в Emacs
94- PHP Mode :: Поддержка языка PHP
95- Kiwix :: Чтение скачанных архивов веб-страниц
96- SML Mode :: Поддержка языка Standard ML
97- Sly/Slime :: REPL языка Common Lisp
98- Simple HTTPD :: HTTP Сервер на elisp
99- Telega :: Интерфейс к Telegram
100- Treemacs :: Сайдбар для навигации по проекту
101- Undo Tree :: Визуализация дерева отмен
102- Yasnippet и Yasnippet Snippets :: Сниппеты для текстов и ЯПов
103- Web Mode :: Поддержка шаблонов HTML и прочего
[4b9efc5]104
[bb02749]105Следующий блок нужен для тех, кто хочет использовать встроенный пакетный
106менеджер. Я использую Guix для большей части взаимодействий со сторонним
107кодом.
[43feba7]108#+begin_src elisp :tangle nil
[4b9efc5]109 (require 'package)
[8217b6f]110
111 (setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
112 ("melpa" . "http://melpa.org/packages/")))
113
114 (when (< emacs-major-version 27)
115 (package-initialize))
116
117 (require 'gnutls)
[4b9efc5]118
[6782e9b]119 (progn
[5acd0cd]120 (package-refresh-contents)
121 (package-install 'avy)
[6782e9b]122 (package-install 'php-mode)
123 (package-install 'phps-mode)
[5acd0cd]124 ;; (package-install 'anzu)
125 (package-install 'anaconda-mode)
126 (package-install 'auctex)
[6782e9b]127 ;; (package-install 'rmsbolt)
[0d11196]128 ;; (package-install 'beginend)
[3600aa2]129 ;; (package-install 'composer)
[5acd0cd]130 (package-install 'cinspect)
131 (package-install 'debian-el)
132 (package-install 'dpkg-dev-el)
133 (package-install 'edebug-inline-result)
134 ;;(package-install 'haskell-mode)
135 ;;(package-install 'idris-mode)
136 (package-install 'magit)
[86d2deb]137 (package-install 'git-timemachine)
[5acd0cd]138 (package-install 'git-dwim)
139 (package-install 'gitpatch)
140 (package-install 'goto-chg)
141 (package-install 'debbugs)
142 ;;(package-install 'deft)
[0d11196]143 ;; (package-install 'direnv)
[5acd0cd]144 (package-install 'dumb-jump)
145 (package-install 'docker)
146 (package-install 'docker-cli)
147 (package-install 'docker-tramp)
[feecad1]148 (package-install 'docker-compose-mode)
149 (package-install 'org-sql)
[5acd0cd]150 ;;(package-install 'eglot)
[0d11196]151 ;; (package-install 'eglot-java)
152 ;; (package-install 'mastodon)
153 ;; (package-install 'exec-path-from-shell)
[5acd0cd]154 (package-install 'expand-region)
[0d11196]155 ;; (package-install 'flymake-php)
[864b0b5]156 (package-install 'flycheck)
157 (package-install 'flycheck-phpstan)
[6782e9b]158 (package-install 'phpactor)
[5acd0cd]159 ;;(package-install 'robe)
160 (package-install 'geiser)
161 (package-install 'geiser-guile)
162 (package-install 'guix)
[0d11196]163 ;; (package-install 'git-gutter)
164 ;; (package-install 'gnuplot)
[5acd0cd]165 ;;(package-install 'swiper)
166 ;;(package-install 'sqlite3)
167 (package-install 'org-roam)
[3600aa2]168 ;; (package-install 'org-roam-ui)
[0d11196]169 ;; (package-install 'org-download)
170 ;; (package-install 'org-babel-eval-in-repl)
[8217b6f]171 ;;(package-install 'ob-php)
[0d11196]172 ;; (package-install 'on-screen)
[5acd0cd]173 ;;(package-install 'nix-mode)
174 (package-install 'pdf-tools)
175 ;;(package-install 'phpactor)
176 ;; (package-install 'company-quickhelp)
[8217b6f]177 ;;(package-install 'ac-php)
[5acd0cd]178 (package-install 'php-mode)
179 (package-install 'php-quickhelp)
180 (package-install 'phan)
[8217b6f]181 ;;(package-install 'php-cs-fixer)
[5acd0cd]182 ;; (package-install 'company-php)
[8217b6f]183 ;;(package-install 'php-eldoc)
184 ;;(package-install 'phps-mode)
[5acd0cd]185 (package-install 'realgud)
[6782e9b]186 ;; (package-install 'realgud-xdebug)
[0d11196]187 ;; (package-install 'kiwix)
[5acd0cd]188 ;;(package-install 'sml-mode)
189 (package-install 'sly)
190 (package-install 'simple-httpd)
191 (package-install 'sudo-edit)
[8217b6f]192 ;;(package-install 'treemacs)
[5acd0cd]193 (package-install 'undo-tree)
[0d11196]194 ;; (package-install 'yasnippet)
195 ;; (package-install 'yasnippet-snippets)
196 ;; (package-install 'vimrc-mode)
197 ;; (package-install 'flymake-phpcs)
198 ;; (package-install 'flymake-phpstan)
199 ;; (package-install 'no-littering)
[5acd0cd]200 (package-install 'web-mode)
[0d11196]201 ;; (package-install 'which-key)
202 ;; (package-install 'reverse-im)
[5acd0cd]203 (package-install 'imenu-list)
[0d11196]204 ;; (package-install 'isearch-mb)
[5acd0cd]205 (package-install 'visual-fill-column)
[0d11196]206 ;; (package-install 'browse-kill-ring)
[864b0b5]207 (package-install 'corfu)
[0d11196]208 ;; (package-install 'inf-ruby)
[5acd0cd]209 (package-install 'yaml-mode)
[0d11196]210 ;; (package-install 'geben)
[5acd0cd]211 (package-install 'link-hint)
[877bb6c]212 (package-install 'whole-line-or-region)
[864b0b5]213 (package-install 'quickrun)
[0d11196]214 ;; (package-install 'psysh)
215 ;; (package-install 'restclient)
[6782e9b]216 )
[4b9efc5]217#+end_src
218
[426ea33]219*** Ручная компиляция
220#+begin_src elisp :tangle nil :results nil
[3aaa66b]221 ;; (native-compile-async "~/.emacs.d/elpa/" 'recursively)
[426ea33]222 (native-compile-async "~/.guix-profile/share/emacs/site-lisp" 'recursively)
[28061ac]223
224 ;; block until native compilation has finished
225 (while (or comp-files-queue
[3aaa66b]226 (> (comp-async-runnings) 0))
[426ea33]227#+end_src
228
[8658e39]229** Отключаем ненужные загрузки
[6650241]230#+begin_src emacs-lisp :tangle nil
[8658e39]231 ;; Disable guix autoloading and x resources loading
[b968867]232 (setq site-run-file nil)
[8658e39]233#+end_src
234
[3ec75a9]235** EXWM
236
[6782e9b]237#+begin_src emacs-lisp :tangle nil
[3ec75a9]238 (require 'exwm)
239 (require 'exwm-config)
240 (exwm-config-example)
241#+end_src
242
243
[a649060]244** Редакируем GUI
[bb02749]245Удаляем ненужные бары, меняем шрифт и модлайн. Использую дефолтный для
[d652ebb]246шрифт DeJavu или недефолтный Agave, так как он является одним из самых интернациональных
[b009e0c]247шрифтов по количеству доступных символов после Unifont. Unifont я не
248стал использовать, потому что иксы замыливают этот пиксельный шрифт, что
249делает его использование крайне неприятным.
[be6d215]250
[3ec75a9]251#+begin_src emacs-lisp :tangle nil
[be6d215]252 ;; Change mode-line-modes to show only major mode
253 (defvar mode-line-major-mode
254 (let ((recursive-edit-help-echo "Recursive edit, type C-M-c to get out"))
255 (list (propertize "%[" 'help-echo recursive-edit-help-echo)
256 `(:propertize ("" mode-name)
257 help-echo "Major mode\n\
258 mouse-1: Display major mode menu\n\
259 mouse-2: Show help for major mode\n\
260 mouse-3: Toggle minor modes"
261 mouse-face mode-line-highlight
262 local-map ,mode-line-major-mode-keymap)
263 '("" mode-line-process)
264 (propertize "%n" 'help-echo "mouse-2: Remove narrowing from buffer"
265 'mouse-face 'mode-line-highlight
266 'local-map (make-mode-line-mouse-map
267 'mouse-2 #'mode-line-widen))
268 (propertize "%]" 'help-echo recursive-edit-help-echo)
269 " "))
270 "Mode line construct for displaying major and minor modes.")
271
272 (put 'mode-line-major-mode 'risky-local-variable t)
273
274 ;; Change mode-line-format
275 (setq-default mode-line-format
276 '("%e"
277 mode-line-front-space
278 mode-line-mule-info
279
280 mode-line-client
281 mode-line-modified
282 mode-line-remote
283 mode-line-frame-identification
284 ;; long-path
285 mode-line-buffer-identification
286 mode-line-misc-info
287 " "
288 mode-line-major-mode
289 " "
290 vc-mode
291 " "
292
293 mode-line-position
294 mode-line-end-spaces
295 ))
[864b0b5]296#+end_src
297
298
299#+begin_src emacs-lisp :tangle nil
300 ;; Do not resize the frame at this early stage.
301 (setq frame-inhibit-implied-resize t)
302 (setq use-dialog-box nil)
303
304 ;;; Disable some gui
305 (scroll-bar-mode -1)
306 (tool-bar-mode -1)
307 (menu-bar-mode -1)
308 ;;(tooltip-mode -1)
[be6d215]309
310 ;;; Changing emacs default setting through customize
311 (custom-set-variables
312 '(fill-column 72)
313 '(git-gutter:added-sign " ")
314 '(git-gutter:deleted-sign " ")
315 '(git-gutter:modified-sign " ")
316 '(git-gutter:unchanged-sign " ")
[212c521]317 '(lsp-headerline-breadcrumb-enable nil)
[01298cc]318 '(scroll-bar-mode 'nil)
[be6d215]319 '(scroll-bar-adjust-thumb-portion nil)
320 '(tool-bar-position 'bottom)
321 '(tool-bar-style 'both-horiz))
322
323 (custom-set-faces
[43227a2]324 '(default ((t (:height 140 :family "Jetbrains Mono" :embolden t))))
[2c99b46]325 '(region ((t (:background "gray85"))))
[4deaed7]326 '(mode-line ((t (:background "grey70" :foreground "grey10"))))
[51683a8]327 '(mode-line-inactive ((t (:inherit mode-line :background "grey90" :foreground "grey20" :box (:line-width (-2 . -2) :color "grey85") :weight light))))
328 '(mode-line-buffer-id ((t (:weight bold))))
329 '(mode-line-emphasis ((t (:weight bold))))
[be6d215]330 '(lsp-modeline-code-actions-face ((t :inherit mode-line :height 100)))
331 '(tool-bar ((t (:background "grey80" :foreground "grey10"))))
332 '(fill-column-indicator ((t (:foreground "grey95"))))
[2c99b46]333 '(hl-line ((t (:background "gray95"))))
[805d49d]334 '(fringe ((t (:background "grey87"))))
[179eabdf]335 '(header-line ((t (:inherit mode-line :background "grey90"))))
336 '(vertical-border ((t (:foreground "grey90"))))
337 '(window-divider ((t (:foreground "gray90")))))
[be6d215]338
339 (set-fringe-style (cons 7 7))
340
341 (defun switch-gui ()
342 "Disable/enable menu-bar and tool-bar."
343 (interactive)
344 (if menu-bar-mode
345 (progn
346 (menu-bar-mode -1)
347 (tool-bar-mode -1)
348 (scroll-bar-mode -1))
349 (progn
350 (menu-bar-mode 1)
351 (tool-bar-mode 1)
352 (scroll-bar-mode 1))))
353
354 (defun switch-scroll-bar ()
355 "Disable/enable scroll-bar."
356 (interactive)
357 (if scroll-bar-mode
358 (scroll-bar-mode -1)
359 (scroll-bar-mode)))
360
361 (define-key global-map (kbd "<f5>") 'switch-gui)
362 (define-key global-map (kbd "<f8>") 'switch-scroll-bar)
363
364 (provide 'early-init)
365 ;;; early-init.el ends here
[8658e39]366#+end_src
[68658dc]367
[8658e39]368** Инициализируем остальной конфиг
[b009e0c]369Следующие блоки кода выводят в файл init.el.
[8658e39]370#+begin_src emacs-lisp :tangle init.el
[128f35c]371 ;; -*- lexical-binding: t -*-
[b968867]372
[8658e39]373 ;; Show/Hide errors
374 ;; (setq debug-on-error nil)
375 ;; (setq debug-on-quit nil)
[b968867]376
[7d46d84]377 (require 'package)
[6782e9b]378 (package-initialize)
[7d46d84]379
[b968867]380 (defun package-loaded? (string)
[455c59b]381 (if (or (cl-member string package-activated-list :test #'string=)
382 (ignore-errors (load (concat string "-autoloads"))))
383 t
[1fe3822]384 (progn
385 (message (concat "Package " string " is not loaded"))
[455c59b]386 nil)))
[b968867]387
[8658e39]388 ;; Timer
389 (add-hook 'emacs-startup-hook
390 (lambda ()
391 (message
392 "Emacs ready in %s with %d garbage collections."
393 (format "%.2f seconds"
394 (float-time
395 (time-subtract after-init-time before-init-time)))
396 gcs-done)))
[b968867]397
[8658e39]398 ;; Dont ask when following symlinks
399 (setq vc-follow-symlinks t)
[b968867]400
[128f35c]401 ;; Load your custom settings
[8658e39]402 (setq custom-file "~/.emacs.d/custom-settings.el")
403 (load custom-file t)
404#+end_src
[68658dc]405
[f61bcc6]406* Meta
407** Обо мне
[128f35c]408#+BEGIN_SRC emacs-lisp :tangle init.el
[8658e39]409 ;; Information about me
410 (setq user-full-name "Mikhail Kirillov"
[0d11196]411 user-mail-address "w96k@runbox.com")
[8658e39]412#+END_SRC
[68658dc]413
[23f3d53]414** Конфигурация
[bb02749]415Базовые функции для манипулирования конфигом в дальнейшем, чтобы не
416приходилось танглить вручную.
[23f3d53]417#+BEGIN_SRC emacs-lisp :tangle init.el
[254aa1d]418 (setq config-dotfiles-path "/home/w96k/projects/dotfiles/emacs/.emacs.d/"
[23f3d53]419 config-path "~/.emacs.d/"
420 config-name ".emacs-config.org")
421
422 (defun config-visit ()
423 (interactive)
424 (find-file (concat config-path config-name)))
425
426 (defun config-tangle ()
427 (interactive)
428 (org-babel-tangle-file (concat config-dotfiles-path config-name))
429 ;; Configuration stored in another directory,
430 ;; so I need to move files .emacs.d manually
[3ec75a9]431 ;; (rename-file (concat config-dotfiles-path "early-init.el") config-path t)
[74b40da]432 (rename-file (concat config-dotfiles-path "init.el") config-path t))
[3ec75a9]433
[23f3d53]434 (defun config-load ()
435 (interactive)
436 (org-babel-load-file (concat config-dotfiles-path config-name) t))
437
438#+END_SRC
[426ea33]439
[f61bcc6]440* Внешний вид
[68658dc]441
[2865cf4]442** Отображение номера строк и пробелов
[bb02749]443Изначально они отключены, но можно вызвать по клавише F7.
[128f35c]444#+BEGIN_SRC emacs-lisp :tangle init.el
[8658e39]445 (define-key global-map
446 (kbd "<f7>") 'global-display-line-numbers-mode)
[0d11196]447
[8658e39]448 (define-key global-map
449 (kbd "<f6>") 'whitespace-mode)
450#+END_SRC
[68658dc]451
[68217df]452* Редактирование
[0d64484]453** Файловый менеджер
[128f35c]454#+BEGIN_SRC emacs-lisp :tangle init.el
[8658e39]455 ;; Show files in KiB
[e915268]456 (setq dired-listing-switches "-hlap"
457 dired-kill-when-opening-new-dired-buffer t)
458
[8e15ad4]459 (customize-set-variable 'global-auto-revert-non-file-buffers t)
460 (global-auto-revert-mode 1)
[8658e39]461#+END_SRC
[68658dc]462
[0979ded]463** Линтер
[52f2a29]464Использую встроенный Flymake и Flycheck
465*** Flymake
[43feba7]466#+BEGIN_SRC emacs-lisp :tangle nil
[e915268]467 ;;(add-hook 'prog-mode-hook 'flymake-mode)
[52f2a29]468
[6188d2e]469 (require 'psalm)
470
[8658e39]471 (define-prefix-command 'flymake-map)
[569fe43]472 (global-set-key (kbd "C-q") 'flymake-map)
[8658e39]473 (define-key flymake-map (kbd "n") 'flymake-goto-next-error)
474 (define-key flymake-map (kbd "p") 'flymake-goto-prev-error)
475 (define-key flymake-map (kbd "l") 'flymake-show-diagnostics-buffer)
476 (define-key flymake-map (kbd "e") 'flymake-show-diagnostic)
477#+END_SRC
[0979ded]478
[52f2a29]479*** Flycheck
[3ec75a9]480#+BEGIN_SRC emacs-lisp :tangle nil
[74bc208]481 ;; (require 'psalm)
[6188d2e]482
[b968867]483 (when (package-loaded? "flycheck")
[6188d2e]484
485 (defun flycheck-phanclient-start-daemon ()
486 "Start the phan daemon"
487 (interactive)
488 (let* ((default-directory (php-project-get-root-dir))
489 (phan-executable (or flycheck-phanclient--phan-executable
490 (if (file-exists-p "vendor/bin/phan")
491 (concat default-directory "vendor/bin/phan")
492 (executable-find "phan"))))
493 (cmd (list phan-executable "--daemonize-tcp-port" "4846" "--quick")))
494 (apply #'start-process "PhanDaemon" "*phan daemon*" cmd)))
495
496 (flycheck-define-checker php-phanclient
[74bc208]497 "Phan"
[6188d2e]498 :command ("phan_client" "-l" source-original "-f" source)
499 :error-patterns
500 ((warning line-start (or "Parse" "Fatal" "syntax" "Phan") " error" (any ":" ",") " " (message) " in " (file-name) " on line " line line-end))
501 :modes (php-mode php+-mode))
502
503 (add-to-list 'flycheck-checkers 'php-phanclient)
504
[74bc208]505 (flycheck-add-next-checker 'php '(warning . php-phanclient))
[6188d2e]506
507 (add-hook 'prog-mode-hook 'flycheck-mode))
[52f2a29]508#+END_SRC
509
[0d64484]510** Дерево проекта
[bb02749]511Возможно в дальнейшем откажусь от этого пакета, так как по факту им
512пользуюсь нечасто. Он предоставляет дерево проектов, как в IDE.
[1e08614]513#+BEGIN_SRC emacs-lisp :tangle nil
[8c09fc7]514 (when (package-loaded? "treemacs")
515 (progn
516 (setq treemacs-width 50
517 treemacs-show-cursor t
518 treemacs-position 'right
519 treemacs-indentation 1
520 treemacs-tag-follow-mode t
521 treemacs-fringe-indicator-mode nil)
522
523 (define-key global-map
524 (kbd "C-x C-d") 'treemacs)))
[8658e39]525#+END_SRC
[68658dc]526
[3cb0c7b]527** Дерево imenu
528#+begin_src emacs-lisp :tangle init.el
[3ec75a9]529 ;; (when (package-loaded? "imenu-list")
530 (setq imenu-list-focus-after-activation nil
531 imenu-list-auto-resize nil
532 imenu-list-mode-line-format '()
533 imenu-list-size 0.4)
534 (global-set-key (kbd "C-x C-d") #'imenu-list-smart-toggle)
535 ;; )
[3cb0c7b]536#+end_src
537
[58d51ef]538** Better Isearch
[0d11196]539#+begin_src emacs-lisp :tangle nil
[58d51ef]540 (when (package-loaded? "isearch-mb")
[455c59b]541 (progn
542 (isearch-mb-mode t)
543 (global-set-key (kbd "C-s") 'isearch-forward-regexp)
544 (global-set-key (kbd "C-r") 'isearch-backward-regexp)))
[58d51ef]545#+end_src
546
[f61bcc6]547** Система контроля версий
[bb02749]548Модуль VC + Magit.
[70a99de]549
[a9e4461]550| Operation | VC | Magit |
551|----------------+-----------------------------------------+----------------------|
552| Project status | project-vc-dir (C-x p v) | magit-status (C-x g) |
553| Pull | vc-update (F, in my case) | magit-pull (F p) |
554| New branch | vc-retrieve-tag (C-u B s) | magit-branch (b c) |
555| Commit | vc-next-action (C-x v v) | magit-commit (c c) |
556| Rebase | shell-command (M-!) + git rebase master | magit-rebase (r p) |
557| Push | vc-push (P or C-u P) | magit-push (P p) |
558| Stash | mu-vc-git-stash (z) | magit-stash (z) |
559| Log | vc-print-root-log (L) | magit-log (l l) |
560https://www.manueluberti.eu//emacs/2021/11/27/vc/
561
[128f35c]562#+BEGIN_SRC emacs-lisp :tangle init.el
[4d3a58c]563 (setq vc-command-messages t)
564
565 (global-set-key "\C-xvB" 'git-branch-next-action)
566
567 ;; Use magit only when built-in VC fails
568 (when (package-loaded? "magit")
569 (progn
570 (setq magit-refresh-status-buffer nil)
571 (global-set-key (kbd "C-x g") 'magit-status)))
[86d2deb]572
573 (package-loaded? "git-timemachine")
[8658e39]574#+END_SRC
[68658dc]575
[f61bcc6]576** Прыжки
[128f35c]577#+BEGIN_SRC emacs-lisp :tangle init.el
[8c09fc7]578 (when (package-loaded? "avy")
579 (progn
580 (define-key global-map (kbd "M-s M-s") 'avy-goto-char)
581 (define-key global-map (kbd "M-s s") 'avy-goto-char)
582 (define-key global-map (kbd "M-s g") 'avy-goto-line)
583 (define-key global-map (kbd "M-s l") 'avy-goto-char-in-line)
584 (define-key global-map (kbd "M-s M-l") 'avy-goto-char-in-line)
585
586 ;; Rewrite default bind to avy
587 (define-key global-map (kbd "M-g g") 'avy-goto-line)
588 (define-key global-map (kbd "M-g M-g") 'avy-goto-line)))
[b5a6b99]589
[fc3e186]590 (when (package-loaded? "link-hint")
591 (progn
592 (define-key global-map (kbd "M-s j") 'link-hint-open-link)))
593
[8658e39]594 ;; Прыжок на последнее изменение
[8c09fc7]595 (when (package-loaded? "goto-chg")
596 (progn
597 (setq glc-default-span 2)
598 (define-key global-map (kbd "C-z") 'goto-last-change)
599 (define-key global-map (kbd "M-z") 'goto-last-change-reverse)))
[d100c77]600
[8658e39]601 ;; Dumb Jump
[8c09fc7]602 (when (package-loaded? "dumb-jump")
603 (progn
604 (define-key global-map (kbd "C-.") 'dumb-jump-go)))
[d100c77]605
[8658e39]606#+END_SRC
[68658dc]607
[0979ded]608** Проекты
[8658e39]609Использую встроенный project.el
610I use built-in project.el
[d1eb4b0]611** Ограничение ширины строки
[128f35c]612#+BEGIN_SRC emacs-lisp :tangle init.el
[8c09fc7]613 (when (package-loaded? "visual-fill-column")
614 (progn
615 ;;; Column width limit highlighter
616 (add-hook 'prog-mode-hook 'display-fill-column-indicator-mode)
617
618 ;;; Set column width to 79 according to pep8 for python
619 (add-hook 'python-mode-hook
620 (lambda () (set-fill-column 79)))))
[8658e39]621#+END_SRC
[68658dc]622
[f61bcc6]623** Подсвечивание парных скобок
[9691479]624** Ввод парных скобок и кавычек (electric)
[128f35c]625#+BEGIN_SRC emacs-lisp :tangle init.el
[8658e39]626 ;;; Input of pair delimiters
627 (electric-pair-mode)
628 (add-hook 'prog-mode-hook 'electric-pair-mode)
[6650241]629 ;; (add-hook 'prog-mode-hook 'rainbow-identifiers-mode)
[8658e39]630#+END_SRC
[68658dc]631
[68217df]632** Kill-ring
[0d11196]633#+BEGIN_SRC emacs-lisp :tangle nil
[8c09fc7]634 (when (package-loaded? "browse-kill-ring")
635 (define-key global-map (kbd "C-M-y") 'browse-kill-ring))
[8658e39]636#+END_SRC
[68658dc]637
[3aa3dbc]638** Tags
[8658e39]639Для прыжков и поиска функций/классов и т.д.
[0d11196]640#+BEGIN_SRC emacs-lisp :tangle nil
[8658e39]641 (setq path-to-ctags "~/.guix-profile/bin/ctags")
642
643 (defun tags-create (dir-name)
644 "Create tags file."
645 (interactive "DDirectory: ")
646 (shell-command
647 (format "%s -f TAGS -e -R %s" path-to-ctags
648 (directory-file-name dir-name))))
649
650 (defun tags-create-python (dir-name)
651 "Create tags with python interpreter"
652 (interactive "DDirectory: ")
653 (shell-command
654 (format "%s -f TAGS -e -R --fields=+l --languages=python --python-kinds=-iv $(python -c \"import os, sys; print(' '.join('{}'.format(d) for d in sys.path if os.path.isdir(d)))\") %s" path-to-ctags
[ca768b6]655 (directory-file-name dir-name))))
[8658e39]656#+END_SRC
[68658dc]657
[8b20cb2]658** Дополнение
[d000862]659** Дебаггер
[3ec75a9]660#+begin_src emacs-lisp :tangle nil
[d000862]661 (when (package-loaded? "realgud")
662 (load "~/.emacs.d/site-lisp/realgud-xdebug/realgud-xdebug.el"))
663#+end_src
664
[3ec75a9]665#+begin_src emacs-lisp :tangle nil
[864b0b5]666 (when (package-loaded? "geben")
667 (setq geben-dbgp-default-port 9003))
668#+end_src
669
[07d6016]670*** Автодополнение кода и документация
671По большей части я использую дефолтный Completion Buffer и Corfu
[3ec75a9]672#+begin_src elisp :tangle nil
[09e91e8]673 (when (package-loaded? "corfu")
674 (progn
675 (setq corfu-preview-current 'nil
676 corfu-popupinfo-delay t)
677 (corfu-mode 1)
678 (corfu-popupinfo-mode 1)
679 (defun show-default-completion-buffer ()
680 (interactive)
681 (corfu-quit)
[279dc2a]682 (corfu-mode -1)
[09e91e8]683 (completion-at-point)
684 (corfu-mode 1)
685 (corfu-popupinfo-mode 1))
686 (define-key corfu-map (kbd "M-TAB") 'show-default-completion-buffer)
687 (define-key corfu-map (kbd "TAB") 'show-default-completion-buffer)
688 (define-key corfu-map (kbd "C-M-i") 'show-default-completion-buffer)
689 (corfu-mode -1)
690 (add-hook 'prog-mode-hook 'corfu-mode)
[d881dae]691
[09e91e8]692 (defun corfu-send-shell (&rest _)
693 "Send completion candidate when inside comint/eshell."
694 (cond
695 ((and (derived-mode-p 'eshell-mode) (fboundp 'eshell-send-input))
696 (eshell-send-input))
697 ((and (derived-mode-p 'comint-mode) (fboundp 'comint-send-input))
698 (comint-send-input))))
[d881dae]699
[09e91e8]700 (advice-add #'corfu-insert :after #'corfu-send-shell)
701
702 (add-hook 'eshell-mode-hook 'corfu-mode)))
[d881dae]703
[951b531]704#+end_src
[41796cb]705*** Модификация дефолта
[3ec75a9]706#+BEGIN_SRC emacs-lisp :tangle nil
[58d51ef]707 (setq completion-styles '(basic partial-completion substring flex emacs22)
708 completion-ignore-case t
709 read-buffer-completion-ignore-case t
[1fe3822]710 read-file-name-completion-ignore-case t)
[41796cb]711#+END_SRC
[bf3cbfb]712*** Агрессивный дефолтный комплит
[e915268]713#+BEGIN_SRC emacs-lisp :tangle nil
[ff56340]714 (setq aggressive-completion-delay 0.5)
[bf3cbfb]715 (aggressive-completion-mode t)
716#+END_SRC
[32f04fb]717** Полнотекстовый поиск
[8658e39]718Для выхода из поиска -- C-c C-q
[ab9549b]719#+begin_src emacs-lisp :tangle nil
[8658e39]720 (load "deft-autoloads")
721
722 (define-key global-map
723 (kbd "C-c n s") 'deft)
724
725 (setq deft-recursive t
726 deft-use-filter-string-for-filename t
727 deft-default-extension "org md"
[5acd0cd]728 deft-directory "~/projects/at-w96k/content/digarden")
[8658e39]729#+end_src
[68658dc]730
[62b2200]731** Визуализирование откатов
[8658e39]732При помощи пакета undo-tree
[4f6c5c4]733#+begin_src emacs-lisp :tangle init.el
[8c09fc7]734 (when (package-loaded? "undo-tree")
735 (progn
[43feba7]736 (add-hook 'prog-mode-hook #'undo-tree-mode)
[2f85958]737 (add-hook 'org-mode-hook #'undo-tree-mode)
[8c09fc7]738 (setq undo-tree-auto-save-history nil)))
[8658e39]739#+end_src
[62b2200]740
[f67dddc]741** Сниппеты
[1e08614]742#+begin_src emacs-lisp :tangle nil
[8c09fc7]743 (when (package-loaded? "yasnippet")
744 (progn
745 (add-hook 'prog-mode-hook #'yas-minor-mode)))
[8658e39]746#+end_src
[68658dc]747
[09d671c]748** Клиент LSP
[6782e9b]749#+begin_src emacs-lisp :tangle init.el
750 ;; (with-eval-after-load 'eglot
751 ;; (add-to-list 'eglot-server-programs '((php-mode phps-mode) . ("~/projects/phpactor/bin/phpactor" "language-server" "-vvv")))
752 ;; (add-to-list 'eglot-server-programs '((php-mode phps-mode) . ("intelephense" "--stdio")))
[09e91e8]753
[6782e9b]754 ;; ;; No event buffers, disable providers cause a lot of hover traffic. Shutdown unused servers.
755 ;; (setq eglot-events-buffer-size 0
756 ;; eglot-ignored-server-capabilities '(:hoverProvider
757 ;; :documentHighlightProvider)
758 ;; eglot-autoshutdown t))
[09e91e8]759
760 ;; Show all of the available eldoc information when we want it. This way Flymake errors
761 ;; don't just get clobbered by docstrings.
762 (add-hook 'eglot-managed-mode-hook
763 (lambda ()
764 "Make sure Eldoc will show us all of the feedback at point."
765 (setq-local eldoc-documentation-strategy
766 #'eldoc-documentation-compose)))
[8658e39]767#+end_src
[09e91e8]768
[f63641c]769** Линтеры
[3ec75a9]770#+begin_src emacs-lisp :tangle nil
[864b0b5]771 (defun my-php-mode-setup ()
772 "My PHP-mode hook."
773 (require 'flycheck-phpstan)
774 (flycheck-mode t))
775
776 (add-hook 'php-mode-hook 'my-php-mode-setup)
777#+end_src
778
[0d11196]779#+BEGIN_SRC emacs-lisp :tangle nil
[09e91e8]780 ;; (add-hook 'php-mode-hook 'flymake-php-load)
781 ;; (add-hook 'php-mode-hook 'flymake-phpstan-turn-on)
782
783 ;; (require 'flycheck-phpstan)
784
[e915268]785
786 ;;(add-to-list 'auto-mode-alist '("\\.\\(php\\|phtml\\)\\'" . phps-mode))
787
[8c09fc7]788 ;; (phps-mode-flycheck-setup)
[e915268]789
[8c09fc7]790 ;; (setq phps-mode-async-process t)
791 ;; (setq phps-mode-async-process-using-async-el t)
[f63641c]792#+END_SRC
[e915268]793
[d43c749]794** Выделение
795#+BEGIN_SRC emacs-lisp :tangle init.el
[8c09fc7]796 (when (package-loaded? "expand-region")
797 (global-set-key (kbd "C-=") 'er/expand-region))
[d43c749]798#+END_SRC
799
[8b20cb2]800** Сессия
[0d11196]801#+BEGIN_SRC emacs-lisp :tangle nil
802 (desktop-save-mode 1)
[8b20cb2]803#+END_SRC
[e2cb5ad]804** Скроллинг
805#+BEGIN_SRC emacs-lisp :tangle init.el
806 (setq scroll-margin 0)
807#+END_SRC
[41796cb]808** Поиск
[34558f1]809*** Isearch
810#+begin_src emacs-lisp :tangle init.el
811 (with-eval-after-load 'isearch
812 (define-key isearch-mode-map "\C-h" 'isearch-delete-char)
813 (define-key isearch-mode-map "\C-ch" 'isearch-help-for-help))
814#+end_src
815
[ca768b6]816*** Подсчёт кандидатов
[1e08614]817#+BEGIN_SRC emacs-lisp :tangle nil
[ca768b6]818(global-anzu-mode t)
819#+END_SRC
820*** Swiper (не используется)
[054e643]821#+BEGIN_SRC emacs-lisp :result nil :tangle nil
[41796cb]822 (load "swiper-autoloads")
823 (global-set-key (kbd "C-s") 'swiper)
824
825 (setq swiper-include-line-number-in-search t
826 swiper-use-visual-line t
827 swiper-stay-on-quit t)
828#+END_SRC
[c39a878]829** Подсказка биндов
830Пакет Which-key
[1f45158]831#+begin_src elisp :tangle nil
[c39a878]832 (load "which-key-autoloads")
833 (which-key-setup-side-window-right)
834 (which-key-mode)
835
[ece4aba]836 (setq which-key-side-window-max-width 0.5
[c39a878]837 which-key-show-remaining-keys t
838 which-key-max-display-columns 50
[fd65e09]839 which-key-max-description-length 35
[c39a878]840 which-key-sort-order 'which-key-local-then-key-order
[fd65e09]841 which-key-idle-delay 0.25)
[c39a878]842#+end_src
843
[8f5263a]844** Права суперпользователя
845Sudo-edit
[b968867]846#+begin_src emacs-lisp
847 (package-loaded? "sudo-edit")
848#+end_src
849
[a649060]850** Промежуточный код
851Показывает собранное состояние будь то собранный куски на ассемблере
852или байт-код при помощи пакета RMSbolt.
[6782e9b]853#+begin_src emacs-lisp :tangle nil
[a649060]854 (add-hook 'prog-mode-hook 'rmsbolt-mode)
855#+end_src
[8f5263a]856
[864b0b5]857** Быстрый запуск программы
[7f6d0e1]858#+begin_src emacs-lisp :tangle nil
859 ;; (when (package-loaded? "quickrun")
860 ;; (define-key global-map (kbd "C-c C-c") 'quickrun))
[864b0b5]861#+end_src
862
863
[f61bcc6]864* Языки программирования
[9989e84]865** Common Lisp
866*** REPL
[3ec75a9]867#+BEGIN_SRC emacs-lisp :tangle nil
[cfa5680]868 (load "sly-autoloads")
869
870 (setq sly-lisp-implementations
871 '((clisp ("clisp"))
872 (cmucl ("cmucl" "-quiet"))
873 (sbcl ("/opt/sbcl/bin/sbcl") :coding-system utf-8-unix)))
[8658e39]874#+END_SRC
[68658dc]875
[7da2cd2]876** Erlang
[3ec75a9]877#+BEGIN_SRC emacs-lisp :tangle nil
[c0d8364]878 (load "erlang-autoloads")
[8658e39]879#+END_SRC
[559d5be]880
881** Ruby
[0d11196]882#+BEGIN_SRC emacs-lisp :tangle nil
[8c09fc7]883 (when (package-loaded? "inf-ruby")
884 (add-hook 'ruby-mode-hook 'inf-ruby-minor-mode))
885
886 (when (package-loaded? "inf-ruby")
887 (add-hook 'ruby-mode-hook 'robe-mode))
[8658e39]888#+END_SRC
[68658dc]889
[b38b2f3]890** Scheme
[128f35c]891#+BEGIN_SRC emacs-lisp :tangle init.el
[4deaed7]892 (setq geiser-active-implementations '("guile"))
[8658e39]893#+END_SRC
[68658dc]894
[559d5be]895** Python
[c3f858e]896*** Автодополнение и линт
[3ec75a9]897#+BEGIN_SRC emacs-lisp :tangle nil
[8c09fc7]898 (when (package-loaded? "anaconda-mode")
899 (progn
900 (add-hook 'python-mode-hook 'anaconda-mode)
[4f6c5c4]901 (add-hook 'python-mode-hook 'anaconda-eldoc-mode)))
[c3f858e]902
[bf3e737]903 ;; (when (load "flymake" t)
904 ;; (defun flymake-pylint-init ()
905 ;; (let* ((temp-file (flymake-init-create-temp-buffer-copy
906 ;; 'flymake-create-temp-inplace))
907 ;; (local-file (file-relative-name
908 ;; temp-file
909 ;; (file-name-directory buffer-file-name))))
910 ;; (list "epylint" (list local-file))))
911
912 ;; (add-to-list 'flymake-allowed-file-name-masks
913 ;; '("\\.py\\'" flymake-pylint-init)))
914
915 ;; (add-hook 'python-mode-hook 'flymake-mode)
[8658e39]916#+END_SRC
[c3f858e]917*** Прыжки в функции стандартной библиотеки на си
[37c47af]918** SML
[ab9549b]919#+BEGIN_SRC emacs-lisp :tangle nil
[8658e39]920 (add-hook 'sml-mode-hook 'sml-mode)
921#+END_SRC
[68658dc]922
[4ece9d5]923** PHP
[e741bd8]924*** PHP-Mode
[56a7a86]925Необходимо скачать и распаковать мануал PHP (в формате html) в
926директорию ~~/.emacs.d/php-manual/~.
[3ec75a9]927#+begin_src emacs-lisp :tangle nil
[8c09fc7]928 ;; (add-to-list 'load-path "~/.emacs.d/site-lisp/realgud-xdebug/")
929 ;; (require 'realgud-xdebug)
[e915268]930
[864b0b5]931 ;; (defun init-php-mode ()
932 ;; (eglot-ensure))
[6782e9b]933
[09e91e8]934 (with-eval-after-load 'php-mode
[6782e9b]935
[09e91e8]936 ;; (add-hook 'php-mode-hook #'init-php-mode)
937 )
938
[37e7af8]939 (when (package-loaded? "php-mode")
[b968867]940 (progn
941 (add-hook 'php-mode-hook 'php-enable-symfony2-coding-style)
[864b0b5]942 (setq lsp-intelephense-php-version "8.1.16")
[6782e9b]943 (defvar phpactor-executable "~/.bin/phpactor")
[864b0b5]944 (custom-set-variables '(lsp-phpactor-path "~/usr/local/bin/phpactor"))
[be6d215]945
946 (add-hook 'php-mode-hook
947 '(lambda ()
[864b0b5]948 ;; (require 'yasnippet)
949 ;; (require 'yasnippet-snippets)
[56a7a86]950
951 (set-fill-column 120)
952
[09e91e8]953 ;; (make-local-variable 'eldoc-documentation-function)
954 ;; (setq eldoc-documentation-function
955 ;; 'phpactor-hover)
[864b0b5]956 ;; (yas-minor-mode t)
[1a961f6]957 (define-key php-mode-map (kbd "C-c h") 'php-quickhelp-at-point)))
[be6d215]958
[b968867]959 (setq php-manual-path
[864b0b5]960 "~/php/php-manual/"
961 php-quickhelp-dir "~/php/php-manual/"
[b968867]962 php-quickhelp--dest "~/.emacs.d/php-manual/php_manual_en.json")
963
964
[be6d215]965 ;; (add-hook 'php-mode-hook
966 ;; '(lambda ()
967 ;; ;; (auto-complete-mode t)
[43749e5]968
[be6d215]969 ;; ;; (require 'ac-php)
970 ;; (require 'php-quickhelp)
971 ;; (require 'company)
972 ;; (company-mode t)
973 ;; (require 'company-php)
974 ;; (require 'company-quickhelp)
[951b531]975
[be6d215]976 ;; (require 'yasnippet)
977 ;; (require 'yasnippet-snippets)
[951b531]978
[be6d215]979 ;; (set (make-local-variable 'company-backends)
980 ;; '((company-ac-php-backend company-dabbrev-code)
981 ;; php-quickhelp-company-php
982 ;; company-capf company-files))
[951b531]983
[be6d215]984 ;; (company-quickhelp-mode t)
[951b531]985
[be6d215]986 ;; (define-key php-mode-map (kbd "C-M-i") 'company-complete)
987 ;; (define-key company-mode-map (kbd "M-TAB") 'company-complete)
[951b531]988
[be6d215]989 ;; ;; (setq ac-sources '(ac-source-php php-quickhelp-company-php))
990 ;; ;; (setq eldoc-documentation-function
991 ;; ;; 'php-quickhelp-eldoc-func)
[b7d25b5]992
[be6d215]993 ;; (yas-minor-mode t)
[b7d25b5]994
[be6d215]995 ;; ;; (define-key php-mode-map (kbd "C-M-i") 'auto-complete)
996 ;; ;; (define-key ac-mode-map (kbd "M-TAB") 'auto-complete)
[b7d25b5]997
[be6d215]998 ;; (define-key php-mode-map (kbd "C-c H")
999 ;; 'php-local-manual-search)
1000
1001 ;; (define-key php-mode-map (kbd "C-c h") 'php-quickhelp-at-point)
1002 ;; (define-key company-mode-map (kbd "C-c h") 'php-quickhelp-at-point)
[b7d25b5]1003
[be6d215]1004 ;; ;; (define-key php-mode-map (kbd "C-c t") 'ac-php-show-tip)
[b7d25b5]1005
[be6d215]1006 ;; ;; Jump to definition (optional)
1007 ;; (define-key php-mode-map
1008 ;; (kbd "M-.") 'ac-php-find-symbol-at-point)
[43749e5]1009
[be6d215]1010 ;; ;; Return back (optional)
1011 ;; (define-key php-mode-map
1012 ;; (kbd "M-,") 'ac-php-location-stack-back)))
1013 ))
[4ece9d5]1014#+end_src
1015
[e741bd8]1016*** Composer
[6782e9b]1017#+begin_src emacs-lisp :tangle init.el
1018 (setq composer-executable-bin "~/.bin/composer")
1019#+end_src
1020
[e741bd8]1021*** Flymake PHP
1022*** REPL
1023*** LSP сервер
1024PHPactor
[43749e5]1025#+begin_src emacs-lisp :tangle nil
[6782e9b]1026 (setq phpactor-executable "~/.bin/phpactor")
1027 (custom-set-variables '(lsp-phpactor-path "~/.bin/phpactor"))
1028
1029 (use-package phpactor :ensure t)
1030 (use-package company-phpactor :ensure t)
1031
1032
1033
1034 ;; (with-eval-after-load 'php-mode
1035 ;; (define-key php-mode-map (kbd "M-.") #'phpactor-goto-definition)
1036 ;; (define-key php-mode-map (kbd "M-?") #'phpactor-find-references))
[e741bd8]1037#+end_src
1038
[af9ef4a]1039*** Transient меню
[c39a878]1040#+begin_src emacs-lisp :tangle nil
[d100c77]1041 (require 'transient)
[f63641c]1042 (define-transient-command php-menu ()
[d100c77]1043 "Php"
1044 [["Class"
1045 ("cc" "Copy" phpactor-copy-class)
1046 ("cn" "New" phpactor-create-new-class)
1047 ("cr" "Move" phpactor-move-class)
1048 ("ci" "Inflect" phpactor-inflect-class)
1049 ("n" "Namespace" phpactor-fix-namespace)]
1050 ["Properties"
1051 ("a" "Accessor" phpactor-generate-accessors)
1052 ("pc" "Constructor" phpactor-complete-constructor)
1053 ("pm" "Add missing props" phpactor-complete-properties)
1054 ("r" "Rename var locally" phpactor-rename-variable-local)
1055 ("R" "Rename var in file" phpactor-rename-variable-file)]
1056 ["Extract"
1057 ("ec" "constant" phpactor-extract-constant)
1058 ("ee" "expression" phpactor-extract-expression)
1059 ("em" "method" phpactor-extract-method)]
1060 ["Methods"
1061 ("i" "Implement Contracts" phpactor-implement-contracts)
1062 ("m" "Generate method" phpactor-generate-method)]
1063 ["Navigate"
1064 ("x" "List refs" phpactor-list-references)
1065 ("X" "Replace refs" phpactor-replace-references)
1066 ("." "Goto def" phpactor-goto-definition)]
1067 ["Phpactor"
1068 ("s" "Status" phpactor-status)
1069 ("u" "Install" phpactor-install-or-update)]])
[af9ef4a]1070#+end_src
[d06a87f]1071* Языки декларирования
1072** SQL
[7f6d0e1]1073 to install lsp-server called sqls
[93c87eb]1074https://emacs-lsp.github.io/lsp-mode/page/lsp-sqls/
[0d11196]1075#+BEGIN_SRC emacs-lisp :tangle nil
[8658e39]1076 ;; Empty for now (was using emacsql)
[b08cfaa]1077 (setq lsp-sqls-server "~/go/bin/sqls")
[313ec50]1078
[ee24a4b]1079 ;; (setq lsp-sqls-workspace-config-path nil)
[313ec50]1080
1081 (setq lsp-sqls-connections
[ee24a4b]1082 '(((driver . "mysql") (dataSourceName . "dbuser:mangoworms@tcp(localhost:3306)/profile24"))))
[8658e39]1083#+END_SRC
[f63641c]1084
[a198d42]1085The main way to interact with SQL is using org-mode
[0d11196]1086#+begin_src emacs-lisp :tangle nil
[a198d42]1087 (when (package-loaded? "org-sql")
1088 (setq org-sql-files "~/projects/profile24/org"))
[313ec50]1089
[acdb8ab]1090 (add-hook 'sql-interactive-mode-hook
[8faea87]1091 (lambda ()
[e6b57ae]1092 (sql-connect "profile24")
[8faea87]1093 (toggle-truncate-lines t)))
[acdb8ab]1094
[313ec50]1095 (setq sql-connection-alist
[ee24a4b]1096 '((profile24
1097 (sql-product 'mysql)
1098 (sql-server "localhost")
1099 (sql-user "dbuser")
[0d11196]1100 (sql-password "123456")
1101 (sql-database "testdb")
[ee24a4b]1102 (sql-port 3306))))
[a198d42]1103#+end_src
1104
1105
[f61bcc6]1106** Веб шаблоны
1107*** Web-mode
[128f35c]1108#+BEGIN_SRC emacs-lisp :tangle init.el
[13a1472]1109 (when (package-loaded? "web-mode")
1110 (progn
1111
1112 (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
1113 (add-to-list 'auto-mode-alist '("\\.twig.html\\'" . web-mode))
1114
1115 (setq web-mode-markup-indent-offset 2)
1116 (setq web-mode-enable-auto-pairing t)
1117 (setq web-mode-enable-css-colorization t)
1118 (setq web-mode-enable-block-face t)
[0d11196]1119 (setq web-mode-enable-current-element-highlight t)))
[8658e39]1120#+END_SRC
[68658dc]1121
[e53abd3]1122** Org
1123*** Org-mode
[128f35c]1124#+BEGIN_SRC emacs-lisp :tangle init.el
[8917c4b]1125 (org-babel-do-load-languages
1126 'org-babel-load-languages
1127 '((R . t)
1128 (ditaa . t)
1129 (dot . t)
[8c09fc7]1130 ;; (php . t)
[8917c4b]1131 (emacs-lisp . t)
1132 (gnuplot . t)
1133 (haskell . nil)
1134 (latex . t)
[9fa5ad7]1135 ;;(ledger . t)
[8917c4b]1136 (ocaml . nil)
1137 (octave . t)
1138 (python . t)
1139 (ruby . t)
1140 (screen . nil)
[9fa5ad7]1141 (shell . t)
[a198d42]1142 (sql . t)
[3600aa2]1143 (js . t)))
[c39a878]1144
[ee24a4b]1145 (defun org-babel-edit-prep:sql (babel-info)
1146 (setq-local buffer-file-name (->> babel-info caddr (alist-get :tangle)))
1147 (setq-local lsp-buffer-uri (->> babel-info caddr (alist-get :tangle) lsp--path-to-uri))
1148 (setq-local lsp-headerline-breadcrumb-enable nil)
1149 (lsp))
1150
[c39a878]1151 (global-set-key (kbd "C-c l") 'org-store-link)
1152 (global-set-key (kbd "C-c a") 'org-agenda)
1153 (global-set-key (kbd "C-c c") 'org-capture)
1154 ;; (global-set-key (kbd "M-f") 'org-metaright)
1155 ;; (global-set-key (kbd "M-b") 'org-metaleft)
1156 ;; (global-set-key (kbd "M-p") 'org-metaup)
1157 ;; (global-set-key (kbd "M-n") 'org-metadown)
1158
[8217b6f]1159 (setq org-default-notes-file "~/Documents/todo.org"
[877bb6c]1160 system-time-locale "C"
[c39a878]1161 org-use-speed-commands t
1162 org-adapt-indentation nil
1163 org-return-follows-link t
[7f6d0e1]1164 org-agenda-include-diary t
[ea0b945]1165 org-display-remote-inline-images 'download
[7f6d0e1]1166 org-agenda-start-with-log-mode t
[edf34a3]1167 org-image-actual-width (list 400)
[c39a878]1168 org-hide-emphasis-markers t
1169 org-outline-path-complete-in-steps nil
1170 org-src-tab-acts-natively t
[09e91e8]1171 org-id-track-globally t
[c39a878]1172 org-confirm-babel-evaluate nil)
1173
1174 (setq org-todo-keywords
1175 (quote ((sequence "TODO(t)"
[254aa1d]1176 "MIGRATE(m)"
[c39a878]1177 "IN PROGRESS(p)"
1178 "DONE(d)")
[7f6d0e1]1179 (sequence "BLOCKED(w@/!)"
[c39a878]1180 "HOLD(h@/!)" "|"
1181 "CANCELLED(c@/!)"
1182 "PHONE"
[7f6d0e1]1183 "MEETING"
1184 "NEED CLARIFICATION(t)"
1185 ))))
[c39a878]1186 (setq org-todo-keyword-faces
1187 (quote (("TODO" :foreground "red" :weight bold)
1188 ("NEXT" :foreground "blue" :weight bold)
1189 ("DONE" :foreground "forest green" :weight bold)
1190 ("WAITING" :foreground "orange" :weight bold)
1191 ("HOLD" :foreground "magenta" :weight bold)
1192 ("CANCELLED" :foreground "forest green" :weight bold)
1193 ("MEETING" :foreground "forest cyan" :weight bold)
1194 ("PHONE" :foreground "blue" :weight bold))))
[8658e39]1195#+END_SRC
[68658dc]1196
[d3c0bac]1197*** Org-ref (не используется)
[279ad2f]1198
[d3c0bac]1199#+begin_src emacs-lisp :tangle nil
[8658e39]1200 (load "org-ref-autoloads")
1201
1202 (setq reftex-default-bibliography '("~/Documents/bibliography/references.bib"))
1203
1204 ;; see org-ref for use of these variables
1205 (setq org-ref-bibliography-notes "~/Documents/bibliography/notes.org"
1206 org-ref-default-bibliography '("~/Documents/Bibliography/references.bib")
1207 org-ref-pdf-directory "~/Documents/bibliography/bibtex-pdfs/")
1208#+end_src
[e53abd3]1209
[d61c4ab]1210*** Org-roam
[d652ebb]1211#+begin_src emacs-lisp :tangle init.el
[b968867]1212 (when (package-loaded? "org-roam")
1213 (progn
[6782e9b]1214 (setq org-roam-directory (file-truename "~/Zettelkasten")
[b968867]1215 org-roam-v2-ack t
1216 org-roam-completion-everywhere t
[09e91e8]1217 org-roam-index-file (concat org-roam-directory "/20210409054712-жизнь.org")
1218 org-roam-dailies-directory (concat org-roam-directory "journals/"))
[b968867]1219
[09e91e8]1220 (org-roam-db-autosync-mode t)
[395b6b5]1221
[b968867]1222 (defun org-roam-jump-to-index ()
1223 "Stub of recreating the function from V1"
1224 (interactive)
1225 (let
1226 ((org-roam-index org-roam-index-file))
1227 (find-file org-roam-index)))
[f63641c]1228
[b968867]1229 (define-key global-map
[09e91e8]1230 (kbd "C-c n l") 'org-roam-node-insert)
[b968867]1231 (define-key global-map
[09e91e8]1232 (kbd "C-c n f") 'org-roam-node-find)
[b968867]1233 (define-key global-map
[09e91e8]1234 (kbd "C-c n b") 'org-roam-buffer-toggle)
[b968867]1235 (define-key global-map
[09e91e8]1236 (kbd "C-c n t t") 'org-roam-tag-add)
[b968867]1237 (define-key global-map
[09e91e8]1238 (kbd "C-c n t r") 'org-roam-tag-remove)
[b968867]1239 (define-key global-map
[09e91e8]1240 (kbd "C-c n i") 'org-roam-jump-to-index)
[b968867]1241 (define-key global-map
[09e91e8]1242 (kbd "C-c n g") 'org-roam-graph)
[b968867]1243 (define-key global-map
[09e91e8]1244 (kbd "C-c n d") 'org-roam-db-build-cache)
[b968867]1245 (define-key global-map
[09e91e8]1246 (kbd "C-c n r") 'org-roam-node-random)
[b968867]1247 (define-key global-map
[09e91e8]1248 (kbd "C-c n j") 'org-roam-dailies-find-date)))
[d652ebb]1249
1250 (customize-set-variable 'org-link-descriptive t)
[8658e39]1251#+end_src
[d61c4ab]1252
[3a19ca7]1253*** Агенда и Capture
[5223c47]1254#+begin_src emacs-lisp :tangle init.el
[cc591cc]1255 (add-to-list 'org-agenda-files
[06e472a]1256 "~/Documents/todo.org")
[3a19ca7]1257
1258 (setq org-directory "~/Documents"
[93c87eb]1259 org-default-notes-file (concat org-directory "/todo.org"))
[cc591cc]1260#+end_src
1261
[2bb7684]1262** YAML
1263#+begin_src emacs-lisp
1264 (package-loaded? "yaml-mode")
1265#+end_src
1266
[f61bcc6]1267* Коммуникации
[7f6d0e1]1268** Gnus
1269#+begin_src emacs-lisp :tangle init.el
1270
1271#+end_src
1272
[f61892c]1273** Telega
[3ec75a9]1274#+BEGIN_SRC emacs-lisp :tangle init.el
[b968867]1275 (when (package-loaded? "telega")
1276 (setq telega-filter-custom-show-folders t
1277 telega-chat-fill-column 40
1278 telega-root-fill-column 60
1279 telega-url-shorten-use-images t)
[f63641c]1280
[b968867]1281 (define-key global-map (kbd "C-c t") telega-prefix-map))
[8658e39]1282#+END_SRC
[68658dc]1283
[1c49a32]1284** Mastodon
[0d11196]1285#+begin_src emacs-lisp :tangle nil
[b968867]1286 (when (package-loaded? "mastodon")
1287 (setq mastodon-active-user "w96k"
1288 mastodon-instance-url "https://fosstodon.org/"))
[1c49a32]1289#+end_src
1290
[254aa1d]1291** LLM
1292#+begin_src emacs-lisp
1293
1294#+end_src
1295
1296
[7700e58]1297* Наука
[f61bcc6]1298* Разное
[d184fc7]1299
1300** Минорные твики дефолтного имакса
[8e15ad4]1301*** Короткие ответы на вопросы
[0d11196]1302#+begin_src emacs-lisp :tangle init.el
[8e15ad4]1303 (if (boundp 'use-short-answers)
1304 (setq use-short-answers t)
1305 (advice-add 'yes-or-no-p :override #'y-or-n-p))
1306#+end_src
1307
1308*** Не сохранять дубликаты в killring
1309
[d80bfc6]1310*** Подсвечивать текущую строку
[0d11196]1311#+begin_src emacs-lisp :tangle nil
[d80bfc6]1312 (global-hl-line-mode 1)
1313#+end_src
1314
[f38167b]1315*** Открывать список буферов в отдельном фрейме
[6cab673]1316#+begin_src emacs-lisp :tangle nil
[f38167b]1317 (add-to-list 'special-display-buffer-names "*Buffer List*")
[395b6b5]1318 (setq Buffer-menu-files-only t)
1319#+end_src
1320
[d184fc7]1321*** Автодополнение в echo при M-x и других командах
[3ec75a9]1322#+begin_src emacs-lisp :tangle init.el
[ec71c8e]1323 (icomplete-mode 1)
[d184fc7]1324#+end_src
1325*** Проверять орфографию
1326#+begin_src emacs-lisp :tangle init.el
1327 (flyspell-mode 1)
[ec71c8e]1328#+end_src
1329
[f61bcc6]1330*** Не спрашивать о несуществующих буферах
[128f35c]1331#+BEGIN_SRC emacs-lisp :tangle init.el
[8658e39]1332 (setq-default confirm-nonexistent-file-or-buffer t)
1333#+END_SRC
[68658dc]1334
[373ed2d]1335*** Переключение буферов
[0d11196]1336#+BEGIN_SRC emacs-lisp :tangle init.el
[373ed2d]1337 (global-set-key (kbd "M-o") 'mode-line-other-buffer)
1338#+END_SRC
[ef88711]1339
[01e632c]1340*** Минорные твики
1341#+begin_src emacs-lisp :tangle init.el
[0d11196]1342 ;; (setq redisplay-dont-pause t)
[3aaa66b]1343
1344 (setq select-enable-clipboard t
1345 select-enable-primary t)
1346
[2107e51]1347 (setq completions-detailed nil)
[3aaa66b]1348
1349 (setq kill-buffer-delete-auto-save-files t)
1350 (setq next-error-message-highlight t)
1351
1352 (setq mode-line-compact 'long)
1353
[2107e51]1354 (setq completions-group t)
1355
[01e632c]1356 ;;(set-frame-parameter nil 'internal-border-width 0)
1357
1358 ;; (set-window-buffer nil (current-buffer))
1359
[0d11196]1360 (setq default-directory "~/"
[01e632c]1361 delete-seleciton-mode t
1362 inhibit-startup-message t
1363 initial-scratch-message nil
1364 custom-safe-themes t
1365 delete-old-versions t
1366 confirm-kill-processes nil
1367 enable-local-variables t)
1368#+end_src
1369
[e93b7a8]1370*** Shell
[128f35c]1371#+begin_src emacs-lisp :tangle init.el
[8658e39]1372 (setq ansi-color-for-comint-mode t)
1373 (setq shell-command-prompt-show-cwd t)
1374#+end_src
[68658dc]1375
[f61bcc6]1376*** Переменная PATH в eshell
[0d11196]1377#+BEGIN_SRC emacs-lisp :tangle nil
[6eb7430]1378 (setq exec-path-from-shell-variables
1379 '("PATH" "MANPATH"))
1380
[f63641c]1381 (when (and (memq window-system '(mac ns x))
1382 (not (eq system-type 'berkeley-unix)))
1383 (exec-path-from-shell-initialize))
[8658e39]1384#+END_SRC
[68658dc]1385
[f61bcc6]1386*** Отображение номера колонки
[128f35c]1387#+BEGIN_SRC emacs-lisp :tangle init.el
[8658e39]1388 (column-number-mode)
1389#+END_SRC
[68658dc]1390
[cc8263e]1391*** nobreak символы
[128f35c]1392#+BEGIN_SRC emacs-lisp :tangle init.el
[8658e39]1393 (setq nobreak-char-display nil)
1394#+END_SRC
[68658dc]1395
[2a1b24a]1396*** Меню
[3176064]1397*** Сохранять временные файлы не в той же директории
[128f35c]1398#+BEGIN_SRC emacs-lisp :tangle init.el
[3aaa66b]1399 (defvar backup-dir "~/.emacs.d/backups/")
1400
[8658e39]1401 (setq
1402 backup-by-copying t
1403 backup-directory-alist
[0d11196]1404 '(("~/.emacs.d/backups/"))
[e915268]1405 version-control nil)
[8658e39]1406#+END_SRC
[68658dc]1407
[1e93232]1408*** Календарь
[8658e39]1409Делаем начало недели в понедельник.
[128f35c]1410#+BEGIN_SRC emacs-lisp :tangle init.el
[8658e39]1411 (setq calendar-week-start-day 1)
1412#+END_SRC
[68658dc]1413
[30915d2]1414*** Вернуться в предыдущий буфер
[2107e51]1415#+BEGIN_SRC emacs-lisp :tangle nil
[30915d2]1416 (define-key global-map (kbd "C-q C-q") 'previous-buffer)
1417 (define-key global-map (kbd "C-S-q C-S-q") 'next-buffer)
1418#+END_SRC
[bbdcdf6]1419*** Смена раскладки (EN / RU) и поддержка биндов на других языках
1420Работает на C-\
[c39a878]1421#+begin_src elisp :tangle init.el
[bbdcdf6]1422 (set-input-method "russian-computer")
1423 (toggle-input-method)
1424#+end_src
1425
[41a06b7]1426*** Требовать создания последней пустой строки
1427#+begin_src emacs-lisp :tangle init.el
1428 (setq require-final-newline t)
1429#+end_src
1430
[e915268]1431*** Стирать текст на C-h как в Bash
[34558f1]1432И переназначаем старые бинды
[be6d215]1433#+begin_src emacs-lisp :tangle nil
[e915268]1434 (define-key global-map (kbd "C-h") 'delete-backward-char)
1435 (define-key global-map (kbd "C-c h") 'help-command)
1436#+end_src
1437
[499be9d]1438*** Поддержка CamelCase в навигации
1439#+begin_src emacs-lisp :tangle init.el
1440 (global-subword-mode 1)
1441#+end_src
1442
[797073d]1443*** Kills
[0901186]1444#+begin_src emacs-lisp :tangle init.el
[797073d]1445 (define-key global-map (kbd "C-k") 'kill-region)
[877bb6c]1446
1447 (when (package-loaded? "whole-line-or-region")
1448 (whole-line-or-region-global-mode))
1449
[797073d]1450 (define-key global-map (kbd "C-w") 'backward-kill-word)
1451#+end_src
1452
[499be9d]1453
[3d43263]1454** Браузер
[3ec75a9]1455#+begin_src emacs-lisp :tangle nil
[864b0b5]1456 (setq browse-url-browser-function #'eww-browse-url)
1457
[8658e39]1458 (add-hook 'eww-mode-hook
1459 (lambda ()
1460 (set-fill-column 80)
1461 (display-fill-column-indicator-mode)
1462 (visual-fill-column-mode)))
1463#+end_src
[68658dc]1464
[e915268]1465** Tramp
[43feba7]1466#+begin_src emacs-lisp :tangle nil
[0d11196]1467 (add-to-list 'tramp-remote-path 'tramp-own-remote-path)
[e915268]1468#+end_src
1469
[b737271]1470** Docker
[b968867]1471#+begin_src emacs-lisp :tangle init.el
1472 (package-loaded? "docker")
[2bb7684]1473 (package-loaded? "docker-compose-mode")
[b968867]1474#+end_src
[4bde91a]1475** Debian
1476Инструменты для работы с пакетным менеджером Debian'а apt'ом и смежными
1477инструментами.
[8c09fc7]1478#+begin_src elisp :tangle nil
[4bde91a]1479 (load "debian-el-autoloads")
1480 (load "dpkg-dev-el-autoloads")
1481#+end_src
1482
[a5e2104]1483** Guix
1484#+begin_src emacs-lisp :tangle init.el
[27ebe67]1485 (package-loaded? "geiser-guile")
1486
[a5e2104]1487 (package-loaded? "guix")
[96b30c6]1488
[27ebe67]1489 (setq geiser-guile-binary "guile")
1490
[96b30c6]1491 (with-eval-after-load 'geiser-guile
[27ebe67]1492 (progn
[debf2d6]1493 (add-to-list 'geiser-guile-load-path "~/projects/guix/")))
[96b30c6]1494
[debf2d6]1495 (let ((guix-copyright "~/projects/guix/etc/copyright.el"))
1496 (if (file-exists-p guix-copyright)
1497 (load-file "~/projects/guix/etc/copyright.el")))
[96b30c6]1498
1499 (setq copyright-names-regexp
[27ebe67]1500 (format "%s <%s>" user-full-name user-mail-address))
[a5e2104]1501#+end_src
1502
[212c521]1503** Nix
[0d11196]1504#+begin_src emacs-lisp :tangle nil
[212c521]1505 (package-loaded? "nix")
1506#+end_src
[68658dc]1507
[fcd469c]1508** Direnv
[0d11196]1509#+BEGIN_SRC emacs-lisp :tangle nil
[8c09fc7]1510 (when (package-loaded? "direnv")
1511 (direnv-mode))
[8658e39]1512#+END_SRC
[68658dc]1513
[f61bcc6]1514** Баг-трекеры
1515*** Debbugs
1516** PDF
[68658dc]1517
[25269dd]1518** Увеличение/уменьшение шрифта
[8c09fc7]1519#+BEGIN_SRC emacs-lisp :tangle nil
[8658e39]1520 (defun zoom-in ()
1521 (interactive)
1522 (let ((x (+ (face-attribute 'default :height)
1523 10)))
1524 (set-face-attribute 'default nil :height x)
1525 (set-face-attribute 'mode-line nil :height x)
1526 (set-face-attribute 'mode-line-inactive nil :height x)
1527 (set-face-attribute 'mode-line-position-face nil :height x)))
1528
1529 (defun zoom-out ()
1530 (interactive)
1531 (let ((x (- (face-attribute 'default :height)
1532 10)))
1533 (set-face-attribute 'default nil :height x)
1534 (set-face-attribute 'mode-line nil :height x)
1535 (set-face-attribute 'mode-line-inactive nil :height x)
1536 (set-face-attribute 'mode-line-position-face nil :height x)))
1537
1538 (define-key global-map (kbd "C-=") 'zoom-in)
[ec5c135]1539 (define-key global-map (kbd "C-+") 'zoom-out)
[8658e39]1540
1541#+END_SRC
[25b6477]1542
[1e08614]1543** Автокомплит у yes-or-no
[688b524]1544** Полный экран
1545Открывать Emacs на полный экран
[6650241]1546#+begin_src emacs-lisp :tangle nil
[688b524]1547 (add-to-list 'default-frame-alist '(fullscreen . maximized))
1548#+end_src
1549
[c39a878]1550** Фуллскрин
1551Отображать ровно столько строчек, сколько вмещает экран.
1552
1553Не работает с native-comp.
1554
[1e08614]1555#+begin_src elisp :tangle nil
[c39a878]1556 (toggle-frame-fullscreen)
[dbba6d8]1557
1558 (defun fullscreen ()
1559 "Fullscreen."
1560 (interactive)
1561 (x-send-client-message nil 0 nil "_NET_WM_STATE" 32
1562 ;; if first parameter is '1', can't toggle fullscreen status
1563 '(1 "_NET_WM_STATE_FULLSCREEN" 0)))
[c39a878]1564#+end_src
[5acd0cd]1565** Удаление буфера и файла
1566#+begin_src elisp :tangle init.el
1567 (defun delete-file-and-buffer ()
1568 "Kill the current buffer and deletes the file it is visiting."
1569 (interactive)
1570 (let ((filename (buffer-file-name)))
1571 (if filename
1572 (if (y-or-n-p (concat "Do you really want to delete file " filename " ?"))
1573 (progn
1574 (delete-file filename)
1575 (message "Deleted file %s." filename)
1576 (kill-buffer)))
1577 (message "Not a file visiting buffer!"))))
1578#+end_src
[d652ebb]1579
1580** Длинные строки
[3ec75a9]1581#+begin_src emacs-lisp :tangle nil
[d652ebb]1582 ;; Better support for files with long lines
1583 (setq-default bidi-paragraph-direction 'left-to-right)
1584 (setq-default bidi-inhibit-bpa t)
1585 (global-so-long-mode 1)
1586#+end_src
1587
1588** Make shebang (#!) file executable when saved
1589#+begin_src emacs-lisp :tangle init.el
1590 (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
1591#+end_src
1592
1593** Enable savehist-mode for command history
1594#+begin_src emacs-lisp :tangle init.el
1595 (savehist-mode 1)
1596#+end_src
[7f6d0e1]1597
1598** Ignore case sensitive in completions, search and etc
1599#+begin_src emacs-lisp :tangle init.el
1600 (setq completion-ignore-case t)
1601#+end_src
Note: See TracBrowser for help on using the repository browser.