You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

721 lines
20 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. #+TITLE: Emacs Configuration
  2. #+AUTHOR: Marc Pohling
  3. * Personal Information
  4. #+begin_src emacs-lisp
  5. (setq user-full-name "Marc Pohling"
  6. user-mail-address "marc.pohling@googlemail.com")
  7. #+end_src
  8. * Update config in a running config
  9. Two options:
  10. - reload the open file: M-x load-file, then press twice to accept
  11. the default filename, which is the currently opened
  12. - Point at the end of any sexp and press C-x C-e
  13. * Customize settings
  14. Move the customize settings to its own file, instead of saving
  15. customize settings in [[file:init.el][init.el]].
  16. #+begin_src emacs-lisp
  17. (setq custom-file (expand-file-name "custom.el" user-emacs-directory))
  18. (load custom-file)
  19. #+end_src
  20. * Theme
  21. ** Font
  22. #+begin_src emacs-lisp
  23. (set-face-attribute 'default nil :font "Hack-12")
  24. #+end_src
  25. ** Material Theme
  26. The [[https://github.com/cpaulik/emacs-material-theme][Material Theme]] comes in a dark and a light variant. Not too dark
  27. to be strenious though.
  28. #+begin_src emacs-lisp
  29. (use-package material-theme
  30. :if (window-system)
  31. :defer t
  32. :ensure t
  33. ;; :init
  34. ;; (load-theme 'material t)
  35. )
  36. #+end_src
  37. ** Apropospriate Theme
  38. Variants dark and light
  39. #+begin_src emacs-lisp
  40. (use-package apropospriate-theme
  41. :if (window-system)
  42. :defer t
  43. :ensure t
  44. :init
  45. (load-theme 'apropospriate-dark t)
  46. )
  47. #+end_src
  48. * Sane defaults
  49. Sources for this section include [[https://github.com/magnars/.emacs.d/blob/master/settings/sane-defaults.el][Magnars Sveen]] and [[http://pages.sachachua.com/.emacs.d/Sacha.html][Sacha Chua]]
  50. These functions are useful. Activate them.
  51. #+begin_src emacs-lisp
  52. (put 'downcase-region 'disabled nil)
  53. (put 'upcase-region 'disabled nil)
  54. (put 'narrow-to-region 'disabled nil)
  55. (put 'dired-find-alternate-file 'disabled nil)
  56. #+end_src
  57. Answering just 'y' or 'n' should be enough.
  58. #+begin_src emacs-lisp
  59. (defalias 'yes-or-no-p 'y-or-n-p)
  60. #+end_src
  61. Keep all backup and auto-save files in one directory
  62. #+begin_src emacs-lisp
  63. (setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
  64. (setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))
  65. #+end_src
  66. UTF-8 please
  67. #+begin_src emacs-lisp
  68. (setq locale-coding-system 'utf-8)
  69. (set-terminal-coding-system 'utf-8)
  70. (set-keyboard-coding-system 'utf-8)
  71. (set-selection-coding-system 'utf-8)
  72. (prefer-coding-system 'utf-8)
  73. #+end_src
  74. Avoid tabs in place of multiple spaces (they look bad in TeX)
  75. and show empty lines
  76. #+begin_src emacs-lisp
  77. (setq-default indent-tabs-mode nil)
  78. (setq-default indicate-empty-lines t)
  79. #+end_src
  80. Turn off blinking cursor
  81. #+begin_src emacs-lisp
  82. (blink-cursor-mode -1)
  83. #+end_src
  84. Don't count two spaces after a period as the end of a sentence.
  85. Just one space is needed
  86. #+begin_src emacs-lisp
  87. (setq sentence-end-double-space nil)
  88. #+end_src
  89. Delete the region when typing, just like as we expect nowadays.
  90. #+begin_src emacs-lisp
  91. (delete-selection-mode t)
  92. #+end_src
  93. Auto-indent when pressing RET, just new-line when C-j
  94. #+begin_src emacs-lisp
  95. (define-key global-map (kbd "RET") 'newline-and-indent)
  96. (define-key global-map (kbd "C-j") 'newline)
  97. #+end_src
  98. Various stuff
  99. #+begin_src emacs-lisp
  100. (show-paren-mode t)
  101. (column-number-mode t)
  102. (global-visual-line-mode)
  103. (diminish 'visual-line-mode)
  104. (setq uniquify-buffer-name-style 'forward)
  105. #+end_src
  106. * List buffers
  107. Ibuffer is the improved version of list-buffers.
  108. Make ibuffer the default buffer lister. [[http://ergoemacs.org/emacs/emacs_buffer_management.html][Source]]
  109. #+begin_src emacs-lisp
  110. (defalias 'list-buffers 'ibuffer)
  111. #+end_src
  112. Also auto refresh dired, but be quiet about it. [[http://whattheemacsd.com/sane-defaults.el-01.html][Source]]
  113. #+begin_src emacs-lisp
  114. (add-hook 'dired-mode-hook 'auto-revert-mode)
  115. (setq global-auto-revert-non-file-buffers t)
  116. (setq auto-revert-verbose nil)
  117. #+end_src
  118. * Org Mode
  119. ** Installation
  120. Although org mode ships with Emacs, the latest version can be installed externally. The configuration here follows the [[http://orgmode.org/elpa.html][Org mode ELPA Installation instructions.]]
  121. Added a hook to complete org functions, company-capf is necessary for this
  122. #+begin_src emacs-lisp
  123. (use-package org
  124. :ensure org-plus-contrib
  125. :init
  126. (add-hook 'org-mode-hook
  127. (lambda ()
  128. (add-to-list 'company-backends 'company-capf)
  129. (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t)
  130. (company-mode t)))
  131. )
  132. #+end_src
  133. To avoid problems executing source blocks out of the box. [[https://emacs.stackexchange.com/a/28604][Others have the same problem, too]]. The solution is to remove the .elc files form the package directory:
  134. #+begin_src sh:
  135. var ORG_DIR=(let* ((org-v (cadr (split-string (org-version nil t) "@"))) (len (length org-v))) (substring org-v 1 (- len 2)))
  136. rm ${ORG_DIR}/*.elc
  137. #+end_src
  138. *** Org key bindings
  139. Set up some global key bindings that integrate with Org mode features
  140. #+begin_src emacs-lisp
  141. (bind-key "C-c l" 'org-store-link)
  142. (bind-key "C-c c" 'org-capture)
  143. (bind-key "C-c a" 'org-agenda)
  144. #+end_src
  145. Org overwrites RET and C-j, so I need to disable the rebinds
  146. #+begin_src emacs-lisp
  147. (define-key org-mode-map (kbd "RET") nil) ;;org-return
  148. (define-key org-mode-map (kbd "C-j") nil) ;;org-return-indent
  149. #+end_src
  150. *** Org agenda
  151. For a more detailed example [[https://github.com/sachac/.emacs.d/blob/83d21e473368adb1f63e582a6595450fcd0e787c/Sacha.org#org-agenda][see here]].
  152. #+begin_src emacs-lisp
  153. (setq org-agenda-files
  154. (delq nil
  155. (mapcar (lambda (x) (and (file-exists-p x) x))
  156. '("~/Archiv/Dokumente/Agenda"))
  157. )
  158. )
  159. #+end_src
  160. *** Org capture
  161. #+begin_src emacs-lisp
  162. (bind-key "C-c c" 'org-capture)
  163. (setq org-default-notes-file "~/Archiv/Dokumente/Notizen/notes.org")
  164. #+end_src
  165. ** Org Setup
  166. Speed commands are a nice and quick way to perform certain actions while at the beginning of a heading. It's not activated by default.
  167. See the doc for speed keys by checking out the documentation for speed keys in Org mode.
  168. #+begin_src emacs-lisp
  169. (setq org-use-speed-commands t)
  170. (setq org-image-actual-width 550)
  171. (setq org-highlight-latex-and-related '(latex script entities))
  172. #+end_src
  173. ** Org tags
  174. The default value is -77, which is weird for smaller width windows. I'd rather have the tags align horizontally with the header.
  175. 45 is a good column number to do that.
  176. #+begin_src emacs-lisp
  177. (setq org-tags-column 45)
  178. #+end_src
  179. ** Org babel languages
  180. #+begin_src emacs-lisp
  181. (org-babel-do-load-languages
  182. 'org-babel-load-languages
  183. '((python . t)
  184. (C . t)
  185. (calc . t)
  186. (latex . t)
  187. (java . t)
  188. (ruby . t)
  189. (lisp . t)
  190. (scheme . t)
  191. (shell . t)
  192. (sqlite . t)
  193. (js . t)))
  194. (defun my-org-confirm-babel-evaluate (lang body)
  195. "Do not confirm evaluation for these languages."
  196. (not (or (string= lang "C")
  197. (string= lang "java")
  198. (string= lang "python")
  199. (string= lang "emacs-lisp")
  200. (string= lang "sqlite"))))
  201. (setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)
  202. #+end_src
  203. ** Org babel/source blocks
  204. I like to have source blocks properly syntax highlighted and with the editing popup window staying within the same window so all the windows don't jump around. Also, having the top and bottom trailing lines in the block is a waste of space, so we can remove them
  205. I noticed that fontification doesn't work with markdown mode when the block is indented after editing it in the org src buffer - the leading #s for headers don't get fontified properly because they apppear as Org comments. Setting ~org-src-preserve-identation~ makes things consistent as it doesn't pad source blocks with leading spaces
  206. #+begin_src emacs-lisp
  207. (setq org-src-fontify-natively t
  208. org-src-window-setup 'current-window
  209. org-src-strip-leading-and-trailing-blank-lines t
  210. org-src-preserve-indentation t
  211. org-src-tab-acts-natively t)
  212. #+end_src
  213. * which-key
  214. Greatly increases discovery of functions!
  215. Click [[https://github.com/justbur/emacs-which-key][here]] for source and more info.
  216. Info in Emacs: M-x customize-group which-key
  217. #+begin_src emacs-lisp
  218. (use-package which-key
  219. :ensure t
  220. :diminish which-key-mode
  221. :config
  222. (which-key-mode)
  223. (which-key-setup-side-window-right-bottom)
  224. (which-key-setup-minibuffer)
  225. (setq which-key-idle-delay 0.5)
  226. )
  227. #+end_src
  228. * Ido (currently inactive)
  229. better completion
  230. begin_src emacs-lisp
  231. (use-package ido
  232. :init
  233. (setq ido-enable-flex-matching t)
  234. (setq ido-everywhere t)
  235. (ido-mode t)
  236. (use-package ido-vertical-mode
  237. :ensure t
  238. :defer t
  239. :init
  240. (ido-vertical-mode 1)
  241. (setq ido-vertical-define-keys 'C-n-and-C-p-only)
  242. )
  243. )
  244. end_src
  245. * ivy / counsel / swiper
  246. Flx is required for fuzzy-matching
  247. Is it really necessary?
  248. begin_src emacs-lisp
  249. (use-package flx)
  250. end_src
  251. Ivy displays a window with suggestions for hotkeys and M-x
  252. #+begin_src emacs-lisp
  253. (use-package ivy
  254. :ensure t
  255. :diminish
  256. (ivy-mode . "") ;; does not display ivy in the mode line
  257. :init
  258. (ivy-mode 1)
  259. :bind
  260. ("C-c C-r" . ivy-resume)
  261. :config
  262. (setq ivy-use-virtual-buffers t) ;; recent files and bookmarks in ivy-switch-buffer
  263. (setq ivy-height 20) ;; height of ivy window
  264. (setq ivy-count-format "%d/%d") ;; current and total number
  265. (setq ivy-re-builders-alist ;; regex replaces spaces with *
  266. '((t . ivy--regex-plus)))
  267. )
  268. #+end_src
  269. Counsel replaces:
  270. - M-x
  271. - C-x C-f find-file
  272. - C-c h f describe-function
  273. - C-c h v describe-variable
  274. - M-i imenu
  275. The find-file replacement is nicer to navigate
  276. #+begin_src emacs-lisp
  277. (use-package counsel
  278. :ensure t
  279. :bind* ;; load counsel when pressed
  280. (("M-x" . counsel-M-x)
  281. ("C-x C-f" . counsel-find-file)
  282. ("C-c h f" . counsel-describe-function)
  283. ("C-c h v" . counsel-describe-variable)
  284. ("M-i" . counsel-imenu)
  285. )
  286. )
  287. #+end_src
  288. Swiper ivy-enhances isearch
  289. #+begin_src emacs-lisp
  290. (use-package swiper
  291. :ensure t
  292. :bind
  293. (("C-s" . swiper)
  294. ("C-c C-r" . ivy-resume)
  295. )
  296. )
  297. #+end_src
  298. * Recentf
  299. Requires counsel
  300. #+begin_src emacs-lisp
  301. (use-package recentf
  302. :bind ("C-x C-r" . counsel-recentf)
  303. :config
  304. (recentf-mode t)
  305. (setq recentf-max-saved-items 200)
  306. )
  307. #+end_src
  308. * Programming
  309. ** Common things
  310. List of plugins and settings which are shared between the language plugins
  311. Highlight whitespaces, tabs, empty lines.
  312. #+begin_src emacs-lisp
  313. (use-package whitespace
  314. :demand t
  315. :ensure nil
  316. :init
  317. (dolist (hook '(prog-mode-hook
  318. text-mode-hook
  319. conf-mode-hook))
  320. (add-hook hook #'whitespace-mode))
  321. ;; :hook ;;not working in use-package 2.3
  322. ;; ((prog-mode . whitespace-turn-on)
  323. ;; (text-mode . whitespace-turn-on))
  324. :config
  325. (setq-default whitespace-style '(face empty tab trailing))
  326. )
  327. #+end_src
  328. Disable Eldoc, it interferes with flycheck
  329. #+begin_src emacs-lisp
  330. (use-package eldoc
  331. :ensure nil
  332. :config
  333. (global-eldoc-mode -1)
  334. )
  335. #+end_src
  336. Colorize colors as text with their value
  337. #+begin_src emacs-lisp
  338. (use-package rainbow-mode
  339. :ensure t
  340. :init
  341. (add-hook 'prog-mode-hook 'rainbow-mode t)
  342. ;; :hook prog-mode ;; not working in use-package 2.3
  343. :config
  344. (setq-default rainbow-x-colors-major-mode-list '())
  345. )
  346. #+end_src
  347. ** Company Mode
  348. Complete Anything!
  349. Activate company and make it react nearly instantly
  350. #+begin_src emacs-lisp
  351. (use-package company
  352. :ensure t
  353. :config
  354. (setq-default company-minimum-prefix-length 1
  355. company-tooltip-align-annotation t
  356. company-tooltop-flip-when-above t
  357. company-show-numbers t
  358. company-idle-delay 0.1)
  359. )
  360. #+end_src
  361. *** Company backend hooks
  362. Backend configuration for python-mode
  363. Common backends are:
  364. - company-files: files & directory
  365. - company-keywords: keywords
  366. - company-capf: ??
  367. - company-abbrev: ??
  368. - company-dabbrev: dynamic abbreviations
  369. - company-ispell: ??
  370. #+begin_src emacs-lisp
  371. (defun company/python-mode-hook()
  372. (set (make-local-variable 'company-backends)
  373. '((company-jedi company-dabbrev) company-capf company-files))
  374. (company-mode t)
  375. )
  376. #+end_src
  377. Backend configuration for lisp-mode
  378. #+begin_src emacs-lisp
  379. (defun company/elisp-mode-hook()
  380. (set (make-local-variable 'company-backends)
  381. '((company-elisp company-dabbrev) company-capf company-files))
  382. (company-mode t)
  383. )
  384. #+end_src
  385. *** Misc Company packages
  386. Addon to sort suggestions by usage
  387. #+begin_src emacs-lisp
  388. (use-package company-statistics
  389. :ensure t
  390. :after company
  391. :config
  392. (company-statistics-mode 1)
  393. )
  394. #+end_src
  395. Get a popup with documentation of the completion candidate.
  396. For the popups the package pos-tip.el is used and automatically installed.
  397. [[https://github.com/expez/company-quickhelp][Company Quickhelp]]
  398. [[https://www.emacswiki.org/emacs/PosTip][See here for Pos-Tip details]]
  399. #+begin_src emacs-lisp
  400. (use-package company-quickhelp
  401. :ensure t
  402. :after company
  403. :config
  404. (company-quickhelp-mode 1)
  405. )
  406. #+end_src
  407. Maybe add [[https://github.com/hlissner/emacs-company-dict][company-dict]]? It's a dictionary based on major modes, plus it has Yasnippet integration.
  408. ** Projectile
  409. Brings search functions on project level
  410. #+begin_src emacs-lisp
  411. (use-package projectile
  412. :ensure t
  413. :defer t
  414. :bind
  415. (("C-c p p" . projectile-switch-project)
  416. ("C-c p s s" . projectile-ag))
  417. :init
  418. (setq-default
  419. projectile-cache-file (expand-file-name ".projectile-cache" user-emacs-directory)
  420. projectile-known-projects-file (expand-file-name
  421. ".projectile-bookmarks" user-emacs-directory))
  422. :config
  423. (projectile-mode t)
  424. (setq-default
  425. projectile-completion-system 'ivy
  426. projectile-enable-caching t
  427. projectile-mode-line '(:eval (projectile-project-name)))
  428. )
  429. #+end_src
  430. ** Lisp
  431. #+begin_src emacs-lisp
  432. (add-hook 'emacs-lisp-mode-hook 'company/elisp-mode-hook)
  433. #+end_src
  434. ** Python
  435. Systemwide following packages need to be installed:
  436. - venv
  437. The virtual environments need to have following modules installed:
  438. - jedi
  439. - epc
  440. - pylint
  441. #+begin_src emacs-lisp
  442. (use-package flycheck
  443. :ensure t
  444. :init
  445. (add-hook 'after-init-hook #'global-flycheck-mode)
  446. (add-hook 'python-mode-hook (lambda ()
  447. (semantic-mode 1)
  448. (flycheck-select-checker 'python-pylint)))
  449. )
  450. #+end_src
  451. Automatically start python-mode when opening a .py-file.
  452. Not sure if python.el is better than python-mode.el.
  453. See [[https://github.com/jorgenschaefer/elpy/issues/887][here]] for info about ~python-shell-completion-native-enable~.
  454. The custom function is to run inferiour processes (do I really need that?), see [[https://emacs.stackexchange.com/questions/16361/how-to-automatically-run-inferior-process-when-loading-major-mode][here]].
  455. Also limit the completion backends to those which make sense in Python.
  456. #+begin_src emacs-lisp
  457. (use-package python
  458. :mode ("\\.py\\'" . python-mode)
  459. :interpreter ("python" . python-mode)
  460. :init
  461. (add-hook 'python-mode-hook 'company/python-mode-hook)
  462. :config
  463. (setq python-shell-completion-native-enable nil)
  464. )
  465. #+end_src
  466. Jedi is a backend for python autocompletion and needs to be installed on the server:
  467. - pip install jedi
  468. Code checks need to be installed, too:
  469. - pip install flake8
  470. #+begin_src emacs-lisp
  471. (use-package company-jedi
  472. :defer t
  473. ;; :after company
  474. :ensure t
  475. :config
  476. (setq jedi:environment-virtualenv (list (expand-file-name "~/Archiv/Programmierprojekte/Python/virtualenv/")))
  477. (setq jedi:python-environment-directory (list (expand-file-name "~/Archiv/Programmierprojekte/Python/virtualenv/")))
  478. (add-hook 'python-mode-hook 'jedi:setup)
  479. (setq jedi:complete-on-dot t)
  480. (setq jedi:use-shortcuts t)
  481. ;; (add-hook 'python-mode-hook 'company/python-mode-hook)
  482. )
  483. #+end_src
  484. A wrapper to handle virtual environments.
  485. I strongly recommend to install virtual environments on the terminal, not through this wrapper, but changing venvs is fine.
  486. TODO: automatically start an inferior python process or switch to it if already created
  487. #+begin_src emacs-lisp
  488. (use-package pyvenv
  489. :ensure t
  490. :init
  491. (setenv "WORKON_HOME" (expand-file-name "~/Archiv/Programmierprojekte/Python/virtualenv/"))
  492. :config
  493. (pyvenv-mode t)
  494. (defun my/post-activate-hook()
  495. (setq jedi:environment-root pyvenv-virtual-env)
  496. (setq jedi:environment-virtualenv pyvenv-virtual-env)
  497. (setq jedi:tooltip-method '(nil)) ;; variants: nil or pos-tip and/or popup
  498. (setq python-shell-virtualenv-root pyvenv-virtual-env)
  499. ;; default traceback, other option M-x jedi:toggle-log-traceback
  500. ;; traceback is in jedi:pop-to-epc-buffer
  501. (jedi:setup)
  502. (company/python-mode-hook)
  503. (setq jedi:server-args '("--log-traceback")))
  504. ;; (add-to-list 'company-backends 'company-jedi)
  505. ;; (add-to-list 'company-backends 'company-anaconda)
  506. ;; (lambda ()
  507. ;; (set (make-local-variable 'company-backends)
  508. ;; '((company-jedi company-dabbrev) company-capf company-files)))
  509. ;; (setq flycheck-checker 'python-pylint))
  510. ;; (flycheck-select-checker 'python-pylint))
  511. ;; (setq flycheck-checker 'python-flake8)
  512. (add-hook 'pyvenv-post-activate-hooks 'my/post-activate-hook)
  513. )
  514. #+end_src
  515. I want Emacs to automatically start the proper virtual environment.
  516. Required is a .python-version file with, content in the first line being /path/to/virtualenv/
  517. [[https://github.com/marcwebbie/auto-virtualenv][Github source]]
  518. Depends on pyvenv
  519. #+begin_src emacs-lisp
  520. (use-package auto-virtualenv
  521. :ensure t
  522. ;; :after pyvenv
  523. ;; :defer t
  524. :init
  525. (add-hook 'python-mode-hook 'auto-virtualenv-set-virtualenv)
  526. ;; activate on changing buffers
  527. ;; (add-hook 'window-configuration-change-hook 'auto-virtualenv-set-virtualenv)
  528. ;; activate on focus in
  529. ;; (add-hook 'focus-in-hook 'auto-virtualenv-set-virtualenv)
  530. )
  531. #+end_src
  532. Anaconda test
  533. begin_src emacs-lisp
  534. (use-package anaconda-mode
  535. :ensure t
  536. :defer t
  537. :init
  538. (add-hook 'python-mode-hook 'anaconda-mode)
  539. ;; (add-hook 'python-mode-hook 'anaconda-eldoc-mode)
  540. :config
  541. (setq anaconda-eldoc-mode 1)
  542. )
  543. end_src
  544. begin_src emacs-lisp
  545. (use-package company-anaconda
  546. :ensure t
  547. :defer t
  548. :init
  549. (defun my/company-anaconda-hook()
  550. (add-to-list 'company-backends 'company-anaconda))
  551. (add-hook 'python-mode-hook 'my/company-anaconda-hook)
  552. )
  553. end_src
  554. * Hydra
  555. Hydra allows grouping of commands
  556. #+begin_src emacs-lisp
  557. (use-package hydra
  558. :ensure t
  559. :bind
  560. ("C-c f" . hydra-flycheck/body)
  561. :config
  562. (setq-default hydra-default-hint nil)
  563. )
  564. #+end_src
  565. ** Hydra Flycheck
  566. Flycheck is necessary, obviously
  567. #+begin_src emacs-lisp
  568. (defhydra hydra-flycheck (:color blue)
  569. "
  570. ^
  571. ^Flycheck^ ^Errors^ ^Checker^
  572. ^────────^──────────^──────^────────────^───────^───────────
  573. _q_ quit _<_ previous _?_ describe
  574. _m_ manual _>_ next _d_ disable
  575. _v_ verify setup _f_ check _s_ select
  576. ^^ ^^ ^^
  577. "
  578. ("q" nil)
  579. ("<" flycheck-previous-error :color red)
  580. (">" flycheck-next-error :color red)
  581. ("?" flycheck-describe-checker)
  582. ("d" flycheck-disable-checker)
  583. ("f" flycheck-buffer)
  584. ("m" flycheck-manual)
  585. ("s" flycheck-select-checker)
  586. ("v" flycheck-verify-setup)
  587. )
  588. #+end_src
  589. * Quality of Life