prog.el 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. ;;; prog.el --- Programming modes and tools
  2. ;; Copyright © 2014–2018 Alex Kost
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;;
  8. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;;
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. (require 'al-key)
  16. ;;; Working with elisp: eldoc, edebug, debugger, …
  17. (setq eval-expression-print-length nil)
  18. (put 'advice-add 'lisp-indent-function 1)
  19. (al/bind-key* "M-v" al/pp-eval-expression)
  20. (al/bind-keys
  21. ("C-v" . al/eval-dwim)
  22. ("C-s-v" . al/pp-eval-dwim)
  23. ("C-S-v" . pp-macroexpand-last-sexp)
  24. ("C-M-v" . eval-defun)
  25. ("M-s-v" . eval-buffer)
  26. ("C-d" . elisp-slime-nav-describe-elisp-thing-at-point)
  27. ("M-d" . xref-find-definitions))
  28. (al/bind-keys
  29. :prefix-map al/doc-map
  30. :prefix-docstring "Map for documentation/finding definitions."
  31. :prefix "C-M-d"
  32. ("f" . find-function)
  33. ("v" . find-variable)
  34. ("F" . find-face-definition)
  35. ("b" . describe-personal-keybindings))
  36. (with-eval-after-load 'lisp-mode
  37. (when (require 'al-lisp nil t)
  38. (al/lisp-add-defcommand-font-lock-keywords))
  39. (defconst al/lisp-shared-keys
  40. '(("<C-M-tab>" . al/indent-sexp))
  41. "Alist of auxiliary keys for `lisp-mode-shared-map'.")
  42. (al/bind-keys-from-vars 'lisp-mode-shared-map 'al/lisp-shared-keys)
  43. (al/bind-keys-from-vars 'lisp-mode-map)
  44. (al/add-hook-maybe 'lisp-mode-hook
  45. '(al/imenu-add-sections
  46. al/lisp-add-defcommand-to-imenu))
  47. (al/modify-page-break-syntax lisp--mode-syntax-table))
  48. (with-eval-after-load 'elisp-mode
  49. (al/bind-keys-from-vars
  50. '(emacs-lisp-mode-map
  51. lisp-interaction-mode-map))
  52. (al/add-hook-maybe
  53. '(emacs-lisp-mode-hook
  54. lisp-interaction-mode-hook)
  55. '(al/imenu-add-sections
  56. al/imenu-add-use-package
  57. al/imenu-add-eval-after-load)))
  58. (with-eval-after-load 'ielm
  59. (setq ielm-prompt "EL> ")
  60. (defconst al/ielm-keys
  61. '("C-j"
  62. ("RET" . ielm-send-input))
  63. "Alist of auxiliary keys for `ielm-map'.")
  64. (al/bind-keys-from-vars 'ielm-map
  65. '(al/lisp-shared-keys al/comint-keys al/ielm-keys))
  66. (al/add-hook-maybe 'ielm-mode-hook 'al/no-truncate-lines))
  67. (with-eval-after-load 'eldoc
  68. (setq eldoc-idle-delay 0.3))
  69. (with-eval-after-load 'edebug
  70. (al/bind-keys
  71. :map edebug-mode-map
  72. ("v" . edebug-eval-expression)
  73. ("C-v" . edebug-eval-last-sexp)))
  74. (al/bind-key "C-c d" toggle-debug-on-error)
  75. (with-eval-after-load 'debug
  76. (al/bind-keys-from-vars 'debugger-mode-map 'al/button-keys t)
  77. (al/bind-keys
  78. :map debugger-mode-map
  79. ("v" . debugger-eval-expression)
  80. ("l" . debugger-toggle-locals)
  81. ("f" . debugger-list-functions)))
  82. (with-eval-after-load 'ert
  83. (defconst al/ert-results-keys
  84. '(("RET" . ert-results-describe-test-at-point)
  85. ("g" . ert-results-rerun-all-tests)
  86. ("h" . ert-results-previous-test))
  87. "Alist of auxiliary keys for `ert-results-mode-map'.")
  88. (al/bind-keys-from-vars 'ert-results-mode-map
  89. '(al/button-keys al/ert-results-keys)))
  90. (with-eval-after-load 'dash
  91. ;; Highlight `dash' keywords.
  92. (dash-enable-font-lock))
  93. (with-eval-after-load 'pp
  94. (when (require 'al-pp nil t)
  95. (advice-add 'pp-display-expression :after 'al/pp-enable-undo)))
  96. ;;; SLIME
  97. ;; Use SLIME from quicklisp.
  98. (let* ((quicklisp-dir (expand-file-name "~/.quicklisp"))
  99. (swank.txt-file (expand-file-name
  100. "dists/quicklisp/installed/systems/swank.txt"
  101. quicklisp-dir)))
  102. (al/with-check
  103. :file swank.txt-file
  104. (let* ((swank.txt (with-temp-buffer
  105. (insert-file-contents swank.txt-file)
  106. (buffer-string)))
  107. (slime-dir (file-name-directory
  108. (expand-file-name swank.txt quicklisp-dir))))
  109. (al/add-to-load-path-maybe slime-dir)
  110. (require 'slime-autoloads nil t))))
  111. (setq slime-contribs '(slime-fancy))
  112. ;; `al/slime-keys' is required for `al/erc-channel-config'
  113. (defconst al/slime-keys
  114. '(("C-v" . al/slime-eval-dwim)
  115. ("C-M-v" . slime-eval-defun)
  116. ("M-s-v" . slime-eval-buffer)
  117. ("<M-tab>" . slime-complete-symbol)
  118. ("C-d" . slime-describe-symbol)
  119. ("M-d" . slime-edit-definition)
  120. ("C-M-d" . slime-doc-map)
  121. "C-c C-d")
  122. "Alist of auxiliary keys for slime modes.")
  123. (al/bind-keys
  124. :prefix-map al/slime-map
  125. :prefix-docstring "Map for slime commands."
  126. :prefix "M-L"
  127. ("l" . slime-repl)
  128. ("M-L" . slime-repl)
  129. ("c" . al/slime-stumpwm-connect)
  130. ("d" . slime-disconnect)
  131. ("M-S" . slime)
  132. ("s" . slime-selector))
  133. (with-eval-after-load 'slime
  134. (setq
  135. inferior-lisp-program "sbcl"
  136. ;; slime-lisp-implementations
  137. ;; `((sbcl ("sbcl" "--core" ,(al/src-dir-file "sbcl-with-swank"))))
  138. ;; Do not ask about version difference.
  139. slime-protocol-version 'ignore)
  140. (defconst al/slime-xref-keys
  141. '(("." . slime-xref-prev-line)
  142. ("e" . slime-xref-next-line)
  143. ("u" . slime-goto-xref)
  144. ("d" . slime-show-xref))
  145. "Alist of auxiliary keys for `slime-xref-mode'.")
  146. (al/bind-keys-from-vars 'slime-xref-mode-map 'al/slime-xref-keys)
  147. (al/bind-keys-from-vars 'slime-parent-map
  148. '(al/free-misc-keys al/slime-keys))
  149. (al/bind-keys-from-vars '(slime-mode-map slime-editing-map)))
  150. (with-eval-after-load 'slime-repl
  151. (defconst al/slime-repl-keys
  152. '(("C-k" . al/slime-repl-kill-whole-line)
  153. ("M-." . slime-repl-previous-input)
  154. ("M-e" . slime-repl-next-input)
  155. ("M->" . slime-repl-previous-prompt)
  156. ("M-E" . slime-repl-next-prompt)
  157. ("M-r" . slime-repl-previous-matching-input))
  158. "Alist of auxiliary keys for `slime-repl-mode-map'.")
  159. (al/bind-keys-from-vars 'slime-repl-mode-map 'al/slime-repl-keys))
  160. (with-eval-after-load 'slime-autodoc
  161. ;; `slime-autodoc-mode' binds some useless keys into "C-c C-d" prefix.
  162. (al/clean-map 'slime-autodoc-mode-map)
  163. (al/bind-keys
  164. :map slime-autodoc-mode-map
  165. ("SPC" . slime-autodoc-space)))
  166. ;;; Scheme, geiser
  167. (with-eval-after-load 'scheme
  168. (when (require 'al-scheme nil t)
  169. (setq scheme-imenu-generic-expression
  170. al/scheme-imenu-generic-expression)
  171. (advice-add 'scheme-indent-function
  172. :override 'al/scheme-indent-function))
  173. (put 'plist-new 'scheme-indent-function 1)
  174. (al/modify-page-break-syntax scheme-mode-syntax-table)
  175. (al/add-hook-maybe 'scheme-mode-hook
  176. '(al/imenu-add-sections
  177. al/scheme-fix-docstring-font-lock
  178. guix-devel-mode)))
  179. (defconst al/geiser-keys
  180. '(("C-v" . al/geiser-eval-dwim)
  181. ("C-S-v" . geiser-expand-last-sexp)
  182. ("C-M-v" . geiser-eval-definition)
  183. ("M-s-v" . geiser-eval-buffer)
  184. ("C-d" . geiser-doc-symbol-at-point)
  185. ("M-d" . geiser-edit-symbol-at-point)
  186. ("C-M-d" . al/geiser-doc-map)
  187. ("C-c l" . al/geiser-add-to-load-path)
  188. ("C-c a" . geiser-autodoc-mode)
  189. ("C-c j" . switch-to-geiser-module)
  190. ("C-c C-j" . geiser-mode-switch-to-repl-and-enter))
  191. "Alist of auxiliary keys for geiser modes.")
  192. (with-eval-after-load 'geiser-mode
  193. (defvar al/geiser-doc-map)
  194. (put 'al/geiser-doc-map 'variable-documentation
  195. "Map for geiser documentation.")
  196. (define-prefix-command 'al/geiser-doc-map)
  197. (al/bind-keys
  198. :map al/geiser-doc-map
  199. ("d" . geiser-doc-symbol-at-point)
  200. ("i" . geiser-doc-look-up-manual)
  201. ("m" . geiser-doc-module)
  202. ("s" . geiser-autodoc-show)
  203. ("t" . geiser-autodoc-mode))
  204. (al/bind-keys-from-vars 'geiser-mode-map 'al/geiser-keys))
  205. (with-eval-after-load 'geiser-repl
  206. (setq
  207. geiser-repl-skip-version-check-p t
  208. geiser-repl-use-other-window t
  209. geiser-repl-history-filename (al/emacs-data-dir-file "geiser-history"))
  210. (defconst al/geiser-repl-keys
  211. '(([return] . al/geiser-repl-enter-dwim)
  212. ("C-k" . al/geiser-repl-kill-whole-line)
  213. ("C-a" . geiser-repl--bol)
  214. ("C-c C-d" . geiser-repl-exit)
  215. "C-c k")
  216. "Alist of auxiliary keys for `geiser-repl-mode'.")
  217. (al/bind-keys-from-vars 'geiser-repl-mode-map
  218. '(al/comint-keys al/geiser-keys al/geiser-repl-keys))
  219. (al/add-hook-maybe 'geiser-repl-mode-hook
  220. '(al/inhibit-field-motion
  221. al/no-syntactic-font-lock
  222. guix-build-log-minor-mode))
  223. (when (require 'al-geiser nil t)
  224. (setq geiser-repl-buffer-name-function
  225. #'al/geiser-repl-buffer-name)))
  226. (with-eval-after-load 'geiser-impl
  227. (setq-default geiser-scheme-implementation 'guile)
  228. (setq geiser-active-implementations '(guile)))
  229. (with-eval-after-load 'geiser-doc
  230. (defconst al/geiser-doc-keys
  231. '(("," . geiser-doc-previous)
  232. ("p" . geiser-doc-next)
  233. ("C-d" . al/geiser-doc-doc-symbol-at-point)
  234. ("M-d" . geiser-doc-edit-symbol-at-point))
  235. "Alist of auxiliary keys for `geiser-doc-mode'.")
  236. (al/bind-keys-from-vars 'geiser-doc-mode-map
  237. '(al/button-keys al/geiser-keys al/geiser-doc-keys)))
  238. (with-eval-after-load 'al-geiser
  239. (setq al/geiser-sockets
  240. '("~/.config/guile-daemon/run/socket")))
  241. ;;; GDB, GUD
  242. (setq gud-key-prefix (kbd "M-G"))
  243. (with-eval-after-load 'gud
  244. (defun al/gud-bind-keys ()
  245. (al/bind-keys-from-vars 'gud-mode-map 'al/comint-keys))
  246. ;; GUD binds its keys inside `gdb' and `gud-gdb' commands.
  247. (al/add-hook-maybe '(gdb-mode-hook
  248. gud-gdb-mode-hook)
  249. 'al/gud-bind-keys))
  250. ;;; Compilation, Makefile
  251. (with-eval-after-load 'make-mode
  252. (defconst al/make-keys
  253. '(("M->" . makefile-previous-dependency)
  254. ("M-E" . makefile-next-dependency))
  255. "Alist of auxiliary keys for `make-mode-map'.")
  256. (al/bind-keys-from-vars 'makefile-mode-map 'al/make-keys))
  257. (with-eval-after-load 'compile
  258. (setq
  259. ;; Don't ask, don't save.
  260. compilation-ask-about-save nil
  261. compilation-save-buffers-predicate 'ignore)
  262. (defconst al/compilation-common-keys
  263. '(("C-M-h" . compilation-previous-error)
  264. ("C-M-n" . compilation-next-error)
  265. ("C-M-." . compilation-previous-error)
  266. ("C-M-e" . compilation-next-error))
  267. "Alist of auxiliary keys that should be bound in any compilation mode.")
  268. (defconst al/compilation-keys
  269. '(("." . compilation-previous-error)
  270. ("e" . compilation-next-error)
  271. ("M-." . previous-error-no-select)
  272. ("M-e" . next-error-no-select))
  273. "Alist of auxiliary keys for compilation modes.")
  274. (defconst al/compilation-button-keys
  275. '(("u" . compile-goto-error))
  276. "Alist of auxiliary keys for `compilation-button-map'.")
  277. (al/bind-keys-from-vars 'compilation-button-map
  278. 'al/compilation-button-keys)
  279. (al/bind-keys-from-vars 'compilation-shell-minor-mode-map
  280. 'al/compilation-common-keys)
  281. (al/bind-keys-from-vars
  282. '(compilation-mode-map compilation-minor-mode-map)
  283. '(al/compilation-common-keys al/compilation-keys))
  284. ;; TODO Move it somewhere.
  285. (defun al/hl-line-mode ()
  286. (unless (memq major-mode '(grep-mode))
  287. (hl-line-mode)))
  288. (add-hook 'compilation-mode-hook 'al/hl-line-mode)
  289. (when (require 'al-compilation nil t)
  290. (al/add-hook-maybe 'compilation-finish-functions
  291. 'al/compilation-notify)))
  292. (with-eval-after-load 'al-compilation
  293. (when (require 'al-file nil t)
  294. (al/setq-file
  295. al/compilation-sound-success (al/sound-dir-file "bell.oga")
  296. al/compilation-sound-error (al/sound-dir-file "splat.wav"))))
  297. ;;; Version control
  298. (setq vc-handled-backends nil)
  299. (setq magit-auto-revert-mode nil)
  300. ;; By default, when `with-editor' library is loaded, it runs
  301. ;; "<emacsclient> --version" shell command HUNDREDS of times (for any
  302. ;; possible name of <emacsclient> executable in all dirs from PATH).
  303. ;; This happens during initializing `with-editor-emacsclient-executable'
  304. ;; variable (when `with-editor-locate-emacsclient' is called).
  305. (setq with-editor-emacsclient-executable nil)
  306. (with-eval-after-load 'with-editor
  307. (setq with-editor-emacsclient-executable
  308. (expand-file-name "emacsclient" invocation-directory)))
  309. (al/bind-keys
  310. :prefix-map al/magit-map
  311. :prefix-docstring "Map for magit and git stuff."
  312. :prefix "M-m"
  313. ("M-m" . al/magit-switch-buffer)
  314. ("b" . magit-blame-popup)
  315. ("c" . al/magit-show-commit)
  316. ("s" . magit-status)
  317. ("l" . magit-log-current)
  318. ("u" . github-browse-file))
  319. (defconst al/magit-common-keys
  320. '(("v" . magit-git-command)
  321. "M-m")
  322. "Alist of auxiliary keys that should be bound in any magit mode.")
  323. (defconst al/magit-history-keys
  324. '(("," . magit-go-backward)
  325. ("p" . magit-go-forward))
  326. "Alist of auxiliary keys for moving by magit history.")
  327. (defconst al/magit-scroll-diff-keys
  328. '(("SPC" . magit-diff-show-or-scroll-up)
  329. ("DEL" . magit-diff-show-or-scroll-down))
  330. "Alist of auxiliary keys for scrolling magit diff in other window.")
  331. (defconst al/magit-moving-keys
  332. '((">" . magit-section-up)
  333. ("." . magit-section-backward)
  334. ("e" . magit-section-forward)
  335. ("M-." . magit-section-backward-sibling)
  336. ("M-e" . magit-section-forward-sibling))
  337. "Alist of auxiliary keys for moving by magit sections.")
  338. ;; TODO Remove (it will be autoloaded in the next release after Magit 2.10.0).
  339. (al/autoload "magit-extras" ido-enter-magit-status)
  340. (with-eval-after-load 'magit
  341. (setq
  342. magit-status-buffer-name-format "*magit: %a*"
  343. magit-process-buffer-name-format "*magit-process: %a*"
  344. magit-log-buffer-name-format "*magit-log: %a*"
  345. magit-reflog-buffer-name-format "*magit-reflog: %a*"
  346. magit-refs-buffer-name-format "*magit-refs: %a*"
  347. magit-diff-buffer-name-format "*magit-diff: %a*"
  348. magit-revision-buffer-name-format "*magit-revision: %a*"
  349. magit-cherry-buffer-name-format "*magit-cherry: %a*"
  350. magit-stash-buffer-name-format "*magit-stash: %a*"
  351. magit-stashes-buffer-name-format "*magit-stashes: %a*")
  352. (setq
  353. magit-merge-arguments '("--ff-only")
  354. magit-push-always-verify t
  355. magit-branch-read-upstream-first nil)
  356. (magit-change-popup-key 'magit-branch-popup :action ?m ?R) ; rename
  357. )
  358. (with-eval-after-load 'magit-mode
  359. (setq
  360. magit-save-repository-buffers nil
  361. magit-use-sticky-arguments nil
  362. magit-uniquify-buffer-names nil)
  363. (defconst al/magit-keys
  364. '(("<backtab>" . magit-section-cycle-global)
  365. ("H-SPC" . magit-diff-show-or-scroll-up)
  366. ("M-k" . magit-copy-section-value)
  367. ("u" . magit-show-commit)
  368. ("U" . magit-unstage-file)
  369. ("E" . magit-ediff-dwim)
  370. ("C" . magit-cherry-pick-popup)
  371. ("1" . magit-section-show-level-1-all)
  372. ("2" . magit-section-show-level-2-all)
  373. ("3" . magit-section-show-level-3-all)
  374. ("4" . magit-section-show-level-4-all)
  375. "M-1" "M-2" "M-3" "M-4")
  376. "Alist of auxiliary keys for `magit-mode-map'.")
  377. (al/bind-keys-from-vars 'magit-mode-map
  378. '(al/lazy-scrolling-keys
  379. al/magit-common-keys
  380. al/magit-moving-keys
  381. al/magit-keys)))
  382. (with-eval-after-load 'magit-popup
  383. (setq
  384. magit-popup-display-buffer-action '((display-buffer-at-bottom))
  385. magit-popup-show-common-commands nil
  386. magit-popup-use-prefix-argument 'default)
  387. (defconst al/magit-popup-keys
  388. '(("DEL" . al/magit-popup-previous-or-quit)
  389. ("M-." . backward-button)
  390. ("M-e" . forward-button)
  391. ("M-h" . magit-popup-toggle-show-common-commands))
  392. "Alist of auxiliary keys for `magit-popup-mode-map'.")
  393. (al/bind-keys-from-vars 'magit-popup-mode-map
  394. 'al/magit-popup-keys
  395. t)
  396. (al/add-hook-maybe 'magit-popup-mode-hook 'al/bar-cursor-type)
  397. ;; Move away from buttons. Adding `al/beginning-of-buffer' to
  398. ;; `magit-popup-mode-hook' wouldn't work because
  399. ;; `magit-refresh-popup-buffer' is called after the mode is set.
  400. (advice-add 'magit-refresh-popup-buffer
  401. :after #'al/beginning-of-buffer))
  402. ;; `magit-log-margin' should be set before magit is loaded, as
  403. ;; the other margins are defined from this one.
  404. (setq magit-log-margin '(t age-abbreviated magit-log-margin-width t 20))
  405. (with-eval-after-load 'magit-log
  406. (setq
  407. magit-reflog-arguments '("-n99")
  408. magit-log-arguments `(,@magit-reflog-arguments "--decorate")
  409. magit-log-select-arguments magit-log-arguments)
  410. (magit-change-popup-key 'magit-log-popup :option ?G ?p) ; patch
  411. (defconst al/magit-log-select-keys
  412. '(("m" . magit-log-select-pick))
  413. "Alist of auxiliary keys for `magit-log-select-mode-map'.")
  414. (al/bind-keys-from-vars 'magit-log-mode-map
  415. '(al/magit-history-keys al/magit-scroll-diff-keys)
  416. t)
  417. (al/bind-keys-from-vars 'magit-log-select-mode-map
  418. '(al/magit-moving-keys al/magit-log-select-keys)
  419. t)
  420. (al/bind-keys-from-vars 'magit-commit-section-map
  421. 'al/magit-common-keys
  422. t))
  423. (with-eval-after-load 'magit-diff
  424. (defconst al/magit-diff-visit-keys
  425. '(("RET" . magit-diff-visit-file-worktree)
  426. ("<C-return>" . magit-diff-visit-file))
  427. "Alist of auxiliary keys for visiting files in `magit-diff-mode'.")
  428. (al/bind-keys-from-vars 'magit-diff-mode-map
  429. 'al/magit-history-keys
  430. t)
  431. (al/bind-keys-from-vars 'magit-file-section-map
  432. '(al/magit-common-keys al/magit-diff-visit-keys)
  433. t)
  434. (al/bind-keys-from-vars 'magit-hunk-section-map
  435. '(al/magit-common-keys al/magit-diff-visit-keys)
  436. t)
  437. (al/bind-keys-from-vars 'magit-staged-section-map 'al/magit-common-keys))
  438. (with-eval-after-load 'magit-sequence
  439. (magit-change-popup-key 'magit-cherry-pick-popup :action ?A ?C) ; pick
  440. (magit-change-popup-key 'magit-rebase-popup :action ?u ?r) ; upstream
  441. )
  442. (with-eval-after-load 'magit-bisect
  443. (magit-change-popup-key 'magit-bisect-popup :action ?B ?s) ; start
  444. (magit-change-popup-key 'magit-bisect-popup :action ?s ?!) ; run script
  445. (magit-change-popup-key 'magit-bisect-popup
  446. :sequence-action ?s ?!) ; run script
  447. )
  448. (with-eval-after-load 'magit-remote
  449. (magit-change-popup-key 'magit-remote-popup :action ?r ?R) ; rename
  450. (magit-change-popup-key 'magit-push-popup :action ?p ?P) ; pushRemote
  451. (magit-change-popup-key 'magit-pull-popup :action ?u ?F) ; upstream
  452. (magit-change-popup-key 'magit-fetch-popup :action ?u ?f) ; upstream
  453. )
  454. (with-eval-after-load 'magit-blame
  455. (setq magit-blame-time-format "%F")
  456. (defconst al/magit-blame-keys
  457. '(("." . magit-blame-previous-chunk)
  458. ("e" . magit-blame-next-chunk)
  459. ("M-." . magit-blame-previous-chunk-same-commit)
  460. ("M-e" . magit-blame-next-chunk-same-commit)
  461. ("M-k" . magit-blame-copy-hash))
  462. "Alist of auxiliary keys for `magit-blame-mode-map'.")
  463. (al/bind-keys-from-vars 'magit-blame-mode-map
  464. '(al/lazy-scrolling-keys al/magit-blame-keys)))
  465. (with-eval-after-load 'magit-git
  466. (setq magit-git-executable "git"))
  467. (with-eval-after-load 'git-commit
  468. (defun al/git-commit-fix-syntax ()
  469. (modify-syntax-entry ?\" "\" ")
  470. (al/no-syntactic-font-lock))
  471. (al/add-hook-maybe 'git-commit-setup-hook
  472. '(;; Not `git-commit-turn-on-flyspell' because it calls `flyspell-buffer'.
  473. flyspell-mode
  474. ;; `git-commit-setup-font-lock' spoils my `text-mode' syntax stuff.
  475. al/git-commit-fix-syntax))
  476. (defconst al/git-commit-keys
  477. '(("M->" . git-commit-prev-message)
  478. ("M-E" . git-commit-next-message)
  479. ("C-c C-a" . al/git-commit-co-authored)
  480. ("C-c C-r" . git-commit-reported)
  481. ("C-c S" . git-commit-suggested))
  482. "Alist of auxiliary keys for `git-commit-mode-map'.")
  483. (al/bind-keys-from-vars 'git-commit-mode-map 'al/git-commit-keys))
  484. (with-eval-after-load 'git-rebase
  485. (al/add-hook-maybe 'git-rebase-mode-hook 'hl-line-mode)
  486. (defconst al/git-rebase-keys
  487. '(("p" . git-rebase-pick)
  488. ("w" . git-rebase-reword)
  489. ("C-k" . git-rebase-kill-line)
  490. ("M-." . git-rebase-move-line-up)
  491. ("M-e" . git-rebase-move-line-down))
  492. "Alist of auxiliary keys for `git-rebase-mode-map'.")
  493. (al/bind-keys-from-vars 'git-rebase-mode-map 'al/git-rebase-keys))
  494. ;;; Misc settings and packages
  495. (with-eval-after-load 'xref
  496. (setq xref-backend-functions '(elisp--xref-backend))
  497. (defconst al/xref-buffer-keys
  498. '(("." . xref-prev-line)
  499. ("e" . xref-next-line)
  500. ("u" . xref-goto-xref)
  501. ("d" . xref-show-location-at-point))
  502. "Alist of auxiliary keys for `xref--xref-buffer-mode-map'.")
  503. (al/bind-keys-from-vars 'xref--xref-buffer-mode-map
  504. 'al/xref-buffer-keys))
  505. (with-eval-after-load 'prog-mode
  506. (al/add-hook-maybe 'prog-mode-hook
  507. '(hl-line-mode
  508. hl-todo-mode
  509. ;; indent-guide-mode
  510. abbrev-mode
  511. al/set-comment-column
  512. al/show-trailing-whitespace))
  513. (defconst al/prog-keys
  514. '(("<C-M-tab>" . prog-indent-sexp))
  515. "Alist of auxiliary keys for `prog-mode-map'.")
  516. (al/bind-keys-from-vars 'prog-mode-map 'al/prog-keys))
  517. (with-eval-after-load 'cc-mode
  518. (setq
  519. c-default-style
  520. '((c-mode . "stroustrup")
  521. (java-mode . "java")
  522. (awk-mode . "awk")
  523. (other . "gnu")))
  524. (defconst al/c-base-keys
  525. '(("<H-M-tab>" . c-indent-defun))
  526. "Alist of auxiliary keys for `c-mode-base-map'.")
  527. (al/bind-keys-from-vars 'c-mode-base-map
  528. '(al/prog-keys al/c-base-keys)))
  529. (with-eval-after-load 'js
  530. (defconst al/js-keys
  531. '(("M-d" . js-find-symbol)
  532. ("C-c M-v" . js-eval)
  533. ("C-M-v" . js-eval-defun))
  534. "Alist of auxiliary keys for `js-mode-map'.")
  535. (al/bind-keys-from-vars 'js-mode-map 'al/js-keys)
  536. (defun al/js-delimiter ()
  537. (setq-local al/delimiter
  538. (concat (make-string 64 ?/) "\n///")))
  539. (al/add-hook-maybe 'js-mode-hook
  540. '(al/imenu-add-js-sections al/js-delimiter)))
  541. (al/autoload "python" python-shell-switch-to-shell)
  542. (with-eval-after-load 'python
  543. (setq python-shell-interpreter "ipython")
  544. (defconst al/python-keys
  545. '(("C-v" . python-shell-send-region)
  546. ("C-M-v" . python-shell-send-defun)
  547. ("M-s-v" . python-shell-send-buffer))
  548. "Alist of auxiliary keys for `python-mode-map'.")
  549. (al/bind-keys-from-vars 'python-mode-map 'al/python-keys))
  550. ;;; prog.el ends here