README.org (52670B)
1 #+TITLE: My Emacs Config
2 #+AUTHOR: Shimmy Xu
3 #+TODO: DISABLED(t) | ENABLED(d)
4 #+PROPERTY: header-args :results none
5
6 This is my humble collection of Emacs config, modeled after
7 [[https://github.com/admiralakber/simplemacs][simplemacs]], documented
8 in an hopefully understandable manner. I went from using multiple
9 =.org= files back to a single one because =org-mode= is fantastic and
10 my config is not too complicated for a single file to handle (yet).
11
12 | Module | Function |
13 |---------------+------------------------------|
14 | [[Packages]] | Package management. |
15 | [[Aesthetics]] | UI and theme. |
16 | [[Plugins]] | Larger scale packages. |
17 | [[Mode Specific]] | Settings specific to a mode. |
18 | [[Enhancements]] | Plug-and-play enhancements. |
19
20 * Packages
21 Manage my package settings.
22
23 ** Package Repositories
24 Initialize Emacs Package Manager and add repositories.
25 #+BEGIN_SRC emacs-lisp
26 (package-initialize)
27 (require 'package)
28 (let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
29 (not (gnutls-available-p))))
30 (url (concat (if no-ssl "http" "https") "://melpa.org/packages/")))
31 (add-to-list 'package-archives (cons "melpa" url) t))
32 (when (< emacs-major-version 24)
33 ;; For important compatibility libraries like cl-lib
34 (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
35 #+END_SRC
36
37 ** Setup =use-package=
38 Bootstrap =use-package= so that package requirements can be handled in separate
39 sections.
40 #+BEGIN_SRC emacs-lisp
41 (unless (package-installed-p 'use-package)
42 (package-refresh-contents)
43 (package-install 'use-package))
44 #+END_SRC
45
46 * Aesthetics
47 Mostly aesthetics and quality of life changes.
48
49 ** 80 Character Limit
50 Set =fill-column= to 80 characters.
51 #+BEGIN_SRC emacs-lisp
52 (setq-default fill-column 80)
53 #+END_SRC
54
55 Highlight portions of line over 80 characters in =prog-mode=.
56 #+BEGIN_SRC emacs-lisp
57 (require 'whitespace)
58 (setq whitespace-line-column 80)
59 (setq whitespace-style '(face empty tabs lines-tail trailing))
60 (add-hook 'prog-mode-hook 'whitespace-mode)
61 #+END_SRC
62
63 ** Auto Detect File Changes
64 Enable auto revert mode to auto-refresh when files have changed on disk.
65 #+BEGIN_SRC emacs-lisp
66 (global-auto-revert-mode t)
67 #+END_SRC
68
69 ** Color Themes
70 Install =base16-theme= and enable gruvbox dark pale.
71 #+BEGIN_SRC emacs-lisp
72 (use-package base16-theme
73 :ensure t
74 :config
75 (load-theme 'base16-gruvbox-dark-pale t))
76 #+END_SRC
77
78 ** Customize Settings in Separate File
79 Save customized settings in a separate file than =init.el=. Create the customization file if none found.
80 #+BEGIN_SRC emacs-lisp
81 (setq custom-file (expand-file-name "custom.el" user-emacs-directory))
82 (unless (file-exists-p custom-file)
83 (write-region "" "" custom-file))
84 (load custom-file)
85 #+END_SRC
86
87 ** Fcitx
88 Install fcitx support.
89 #+BEGIN_SRC emacs-lisp
90 (use-package fcitx
91 :ensure t
92 :init
93 (fcitx-aggressive-setup)
94 (setq fcitx-use-dbus t))
95 #+END_SRC
96
97 *** Daemon Support
98 If using Emacs daemon with =systemd=, remember to add to the
99 =.service= file:
100
101 #+BEGIN_SRC sh
102 Environment="LC_CTYPE=zh_CN.UTF-8" "XMODIFIERS=@im=fcitx"
103 #+END_SRC
104
105 It would also help to change the default command for =emacs= into:
106 #+BEGIN_SRC sh
107 emacsclient -c -a emacs
108 #+END_SRC
109
110 ** Font Settings
111 *** Default Fonts
112 Specify font settings.
113 #+BEGIN_SRC emacs-lisp
114 (defvar user/cjk-font "Noto Sans CJK SC"
115 "Default font for CJK characters.")
116
117 (defvar user/latin-font "Iosevka Term SS09"
118 "Default font for Latin characters.")
119
120 (defvar user/unicode-font "Symbola"
121 "Default font for Unicode characters, including emojis.")
122
123 (defvar user/font-size 17
124 "Default font size in px.")
125
126 (defvar user/standard-fontset
127 (create-fontset-from-fontset-spec standard-fontset-spec)
128 "Standard fontset for user.")
129
130 ;; Ensure user/standard-fontset gets used for new frames.
131 (add-to-list 'default-frame-alist (cons 'font user/standard-fontset))
132 (add-to-list 'initial-frame-alist (cons 'font user/standard-fontset))
133 #+END_SRC
134
135 *** CJK Font Scaling
136 Ensure CJK fonts scales correctly to twice the width of mono-space half-width
137 characters. I tried to add something similar for Unicode fonts, but found that
138 they don't have uniform width anyways (not to mention that not all of them are
139 full-width), rendering this method useless.
140
141 I think CJK fonts have less granular sizing controls, i.e. the actual glyph size
142 of size 16 and size 17 are in fact the same and only starts actually increasing
143 after we hit size 18.
144
145 #+BEGIN_SRC emacs-lisp
146 (defvar user/cjk-font-scale
147 '((16 . 1.0)
148 (17 . 1.1)
149 (18 . 1.0))
150 "Scaling factor to use for cjk font of given size.")
151
152 ;; Specify scaling factor for CJK font.
153 (setq face-font-rescale-alist
154 (list (cons user/cjk-font
155 (cdr (assoc user/font-size user/cjk-font-scale)))))
156 #+END_SRC
157
158 *** Fontset with CJK and Unicode Fallback
159 To ensure fontset gets correctly configured, I simply created one from
160 scratch. This is because =emacsclient= seems to have a different dynamic when
161 creating =startup-fontset= and no other method guarantees consistent behavior
162 between =emacs= and =emacsclient=.
163
164 Use ~C-u C-x =~ to examine the font used for a specific character and use
165 =describe-fontset= to check if our changes went through.
166
167 #+BEGIN_SRC emacs-lisp
168 ;; Enable font customization for charset 'symbols, which contains puncuation
169 ;; marks, emoji, etc.
170 (setq use-default-font-for-symbols nil)
171
172 (defun user/set-font ()
173 "Set Unicode, Latin and CJK font for user/standard-fontset."
174 ;; Unicode font.
175 (set-fontset-font user/standard-fontset 'unicode
176 (font-spec :family user/unicode-font)
177 nil 'prepend)
178 ;; Latin font.
179 ;; Only specify size here to allow text-scale-adjust work on other fonts.
180 (set-fontset-font user/standard-fontset 'latin
181 (font-spec :family user/latin-font :size user/font-size)
182 nil 'prepend)
183 ;; CJK font.
184 (dolist (charset '(kana han cjk-misc hangul kanbun bopomofo))
185 (set-fontset-font user/standard-fontset charset
186 (font-spec :family user/cjk-font)
187 nil 'prepend))
188 ;; Special settings for certain CJK puncuation marks.
189 ;; These are full-width characters but by default uses half-width glyphs.
190 (dolist (charset '((#x2018 . #x2019) ;; Curly single quotes "‘’"
191 (#x201c . #x201d))) ;; Curly double quotes "“”"
192 (set-fontset-font user/standard-fontset charset
193 (font-spec :family user/cjk-font)
194 nil 'prepend)))
195
196 ;; Apply changes.
197 (user/set-font)
198 ;; For emacsclient.
199 (add-hook 'before-make-frame-hook #'user/set-font)
200 #+END_SRC
201
202 ** Line Highlighting
203 Enable line highlighting.
204 #+BEGIN_SRC emacs-lisp
205 (global-hl-line-mode t)
206 #+END_SRC
207
208 ** Line Numbering
209 Use =display-line-numbers= instead of =linum=.
210 Enable relative line numbering, and set minimum width to 3.
211 #+BEGIN_SRC emacs-lisp
212 (setq-default display-line-numbers-type (quote relative))
213 (setq-default display-line-numbers-width 3)
214 (global-display-line-numbers-mode)
215 #+END_SRC
216
217 ** Line Wrapping
218 Enable line wrapping by default.
219 #+BEGIN_SRC emacs-lisp
220 (global-visual-line-mode t)
221 #+end_SRC
222
223 ** No Tabs
224 Use spaces for indenting.
225 #+BEGIN_SRC emacs-lisp
226 (setq-default indent-tabs-mode nil)
227 #+END_SRC
228
229 For those that uses tab, set width to 4.
230 #+BEGIN_SRC emacs-lisp
231 (setq-default tab-width 4)
232 #+END_SRC
233
234 ** Parenthesis Highlighting
235 Highlight matching parenthesis.
236 #+BEGIN_SRC emacs-lisp
237 (show-paren-mode t)
238 #+END_SRC
239
240 ** Rainbow Delimiters
241 =rainbow-delimiters= is a "rainbow parentheses"-like mode which highlights delimiters such as parentheses, brackets or braces according to their depth.
242
243 Install =rainbow-delimiters= and enable it for =prog-mode=.
244 #+BEGIN_SRC emacs-lisp
245 (use-package rainbow-delimiters
246 :ensure t
247 :init (add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
248 #+END_SRC
249
250 ** Remove Trailing Whitespace
251 Remove trailing whitespace upon saving.
252 #+BEGIN_SRC emacs-lisp
253 (add-hook 'before-save-hook 'delete-trailing-whitespace)
254 #+END_SRC
255
256 ** Save Backups Elsewhere
257 Save =*~= backups in =$(pwd)/.bak=.
258 #+BEGIN_SRC emacs-lisp
259 (setq backup-directory-alist
260 '(("." . ".bak"))
261 )
262 #+END_SRC
263
264 ** Show Column Number
265 #+BEGIN_SRC emacs-lisp
266 (setq column-number-mode t)
267 #+END_SRC
268
269 ** DISABLED Smooth Scrolling
270 *** DISABLED Sublimity
271 #+BEGIN_SRC emacs-lisp
272 (use-package sublimity
273 :ensure t
274 :config
275 (require 'sublimity-scroll)
276 (require 'sublimity-map)
277 (sublimity-global-mode))
278 #+END_SRC
279
280 *** Smooth
281 #+BEGIN_SRC emacs-lisp
282 (use-package smooth-scrolling
283 :ensure t
284 :config (smooth-scrolling-mode 1))
285 #+END_SRC
286
287 ** UI Settings
288 *** *bars
289 Hide menu, scrollbar and toolbars.
290 #+BEGIN_SRC emacs-lisp
291 (menu-bar-mode -1)
292 (scroll-bar-mode -1)
293 (tool-bar-mode -1)
294 #+END_SRC
295
296 **** New Frame Scrollbar
297 Remove scrollbar for any new frames as well, useful for =emacsclient=.
298 #+BEGIN_SRC emacs-lisp
299 (defun user/disable-scroll-bars (frame)
300 (modify-frame-parameters frame
301 '((vertical-scroll-bars . nil)
302 (horizontal-scroll-bars . nil))))
303 (add-hook 'after-make-frame-functions 'user/disable-scroll-bars)
304 #+END_SRC
305
306 *** Half screen fix
307 Fills up gap in the border when tiling Emacs to half-screen.
308 #+BEGIN_SRC emacs-lisp
309 (setq frame-resize-pixelwise t)
310 #+END_SRC
311
312 ** Zoom In
313 Use mouse wheel to adjust zoom level.
314 #+BEGIN_SRC emacs-lisp
315 (global-set-key [C-mouse-4] 'text-scale-increase)
316 (global-set-key [C-mouse-5] 'text-scale-decrease)
317 #+END_SRC
318
319 * Plugins
320 Larger scale packages that either requires more configuration, or
321 fundamentally changes how Emacs behave. Because these package
322 configurations is a lot more complex and may be spread out, any
323 subtree that depends on packages in this section will have a tag to
324 mark the dependency.
325
326 ** Ivy
327 Flexible, simple tools for minibuffer completion in Emacs.
328
329 Ivy, a generic completion mechanism for Emacs.
330 Counsel, a collection of Ivy-enhanced versions of common Emacs commands.
331 Swiper, an Ivy-enhanced alternative to isearch.
332
333 *** Installation
334 #+BEGIN_SRC emacs-lisp
335 (use-package ivy
336 :ensure t
337 :init
338 (setq enable-recursive-minibuffers t)
339 (ivy-mode 1)
340 :config
341 ;; Show recents and bookmarks in find-file.
342 (setq ivy-use-virtual-buffers t)
343 ;; Use Enter to navigate into the directory, not open it with dired.
344 (define-key ivy-minibuffer-map (kbd "C-m") 'ivy-alt-done)
345 ;; Use C-l to go back one level.
346 (define-key ivy-minibuffer-map (kbd "C-l") 'ivy-backward-delete-char)
347 :bind
348 (("C-c C-r" . ivy-resume)))
349 (use-package counsel
350 :ensure t
351 :bind
352 (("M-x" . counsel-M-x)
353 ("M-y" . counsel-yank-pop)
354 ("C-c c f" . counsel-git)
355 ("C-c c s" . counsel-git-grep)
356 ("C-x C-f" . counsel-find-file)
357 ("C-x r b" . counsel-bookmark)
358 ("C-h a" . counsel-apropos)
359 ("C-h f" . counsel-describe-function)
360 ("C-h v" . counsel-describe-variable)
361 ("C-h l" . counsel-find-library)
362 ("C-h b" . counsel-descbinds)
363 ("C-h i" . counsel-info-lookup-symbol)
364 ("<f2> u" . counsel-unicode-char)))
365 (use-package swiper
366 :ensure t
367 :bind
368 (("C-s" . swiper)))
369 #+END_SRC
370
371 *** Integration
372 Integration with =magit= and =projectile=.
373 #+BEGIN_SRC emacs-lisp
374 (setq magit-completing-read-function 'ivy-completing-read)
375 (setq projectile-completion-system 'ivy)
376 #+END_SRC
377
378 ** DISABLED Helm
379 Stolen from Admiral Akber's config.
380
381 *** Install
382 Helm is incredible, it really supercharges emacs. It's a framework for
383 incremental searching / completion / narrowing down options. Sounds
384 simple, and it is in application, and it's so worth it.
385
386 Web: [[https://emacs-helm.github.io/helm/]]
387 Git: [[https://github.com/emacs-helm/helm]]
388 #+BEGIN_SRC emacs-lisp
389 (use-package helm
390 :ensure t
391 :init (helm-mode t))
392 (require 'helm-config)
393 #+END_SRC
394
395 *** Visual customization
396 I want helm to automatically resize and appear in the current buffer
397 only.
398 #+BEGIN_SRC emacs-lisp
399 (setq helm-autoresize-mode 1)
400 (setq helm-split-window-in-side-p t)
401 #+END_SRC
402
403 *** Fuzzy matching
404 Fuzzy matching works most of the time, it does seem to have the issue
405 of only matching forward i.e. "machine snow" will not match with "snow
406 machine".
407
408 It does make it a lot easier to search through Emacs functions though
409 as you only need to remember one part of the function name.
410 #+BEGIN_SRC emacs-lisp
411 ;; Enable Fuzzy Matching
412 (setq helm-recentf-fuzzy-match t
413 helm-buffers-fuzzy-matching t
414 helm-recentf-fuzzy-match t
415 helm-buffers-fuzzy-matching t
416 helm-locate-fuzzy-match t
417 helm-apropos-fuzzy-match t
418 helm-lisp-fuzzy-completion t
419 helm-candidate-number-limit 250)
420 #+END_SRC
421
422 *** Keybindings
423 Above defaults overides such as =M-x= these are custom bindings.
424
425 **** Self help
426 The Emacs culture is to have great documentation with your functions,
427 all searchable via =apropos=. Helm provides a nice interface to this,
428 use it often.
429 #+BEGIN_SRC emacs-lisp
430 (global-set-key (kbd "C-h a") 'helm-apropos)
431 (global-set-key (kbd "C-h i") 'helm-info-emacs)
432 #+END_SRC
433
434 **** Buffers and files
435 Buffers and files are an obvious case where helm is very useful.
436 #+BEGIN_SRC emacs-lisp
437 (global-set-key (kbd "C-x b") 'helm-mini)
438 (global-set-key (kbd "C-x C-b") 'helm-buffers-list)
439 (global-set-key (kbd "M-x") 'helm-M-x)
440 (global-set-key (kbd "C-x C-f") 'helm-find-files)
441 (global-set-key (kbd "C-x C-r") 'helm-recentf)
442 (global-set-key (kbd "C-x r l") 'helm-filtered-bookmarks)
443 #+END_SRC
444
445 **** Advanced editing
446 Kill ring memory, grepping, etc, all gorgeous with helm.
447 #+BEGIN_SRC emacs-lisp
448 (global-set-key (kbd "M-y") 'helm-show-kill-ring)
449 (global-set-key (kbd "C-x c g") 'helm-do-grep)
450 (global-set-key (kbd "C-x c o") 'helm-occur)
451 #+END_SRC
452
453 **** The overloaded tab key
454 The good ol' =TAB= key is used for a lot, in this case I want to make
455 sure that when used in helm that it completes in helm, not attempting
456 to insert a snippet or something.
457 #+BEGIN_SRC emacs-lisp
458 (define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)
459 #+END_SRC
460
461 Also, the following makes sure that tab works when running in terminal
462 mode:
463 #+BEGIN_SRC emacs-lisp
464 (define-key helm-map (kbd "C-i") 'helm-execute-persistent-action)
465 #+END_SRC
466
467 This requires fixing the select other actions which IIRC is set to
468 ~C-i~ by default.
469 #+BEGIN_SRC emacs-lisp
470 (define-key helm-map (kbd "C-z") 'helm-select-action)
471 #+END_SRC
472
473 ** Company
474 Auto completion of everything with nice backends.
475
476 *** Installation
477 Install =company= and enable it globally.
478 #+BEGIN_SRC emacs-lisp
479 (use-package company
480 :ensure t
481 :init (global-company-mode))
482 #+END_SRC
483
484 *** Tweaks
485 **** Adjust Delay
486 Set delay for auto-completion. 0 would be too extreme and wastes CPU clocks apparently.
487 #+BEGIN_SRC emacs-lisp
488 (setq company-idle-delay 0.01)
489 (setq company-minimum-prefix-length 2)
490 #+END_SRC
491
492 **** Align Annotation
493 Flush annotation on candidates to the right.
494 #+BEGIN_SRC emacs-lisp
495 (setq company-tooltip-align-annotations t)
496 #+END_SRC
497
498 *** Tooltip Documentation
499 Install dependency =pos-tip=.
500 #+BEGIN_SRC emacs-lisp
501 (use-package pos-tip
502 :ensure t)
503 (require 'pos-tip)
504 #+END_SRC
505
506 Install =company-quickhelp= and set delay, FG/BG colors, max lines.
507 #+BEGIN_SRC emacs-lisp
508 (use-package company-quickhelp
509 :ensure t
510 :init
511 (company-quickhelp-mode t)
512 (setq company-quickhelp-delay 0.01)
513 (setq company-quickhelp-color-background "#262626")
514 (setq company-quickhelp-color-foreground "#ebdbb2")
515 (setq company-quickhelp-max-lines 20)
516 (setq company-quickhelp-use-propertized-text t))
517 #+END_SRC
518
519 *** Backend Configurations
520 **** =company-auctex=
521 Install =company-auctex= and add it to =company-backends=. This is for =acutex= macro completion.
522 Adding backends is handled by =company-auctex-init=.
523 #+BEGIN_SRC emacs-lisp
524 (use-package company-auctex
525 :ensure t
526 :init
527 (company-auctex-init))
528 #+END_SRC
529
530 ***** DISABLED Workaround To Enable Completion in Org Mode
531 #+BEGIN_SRC emacs-lisp
532 :config
533 (defun company-auctex-prefix (regexp)
534 "Returns the prefix for matching given REGEXP in org-mode and latex-mode."
535 (and (or (derived-mode-p 'latex-mode) (derived-mode-p 'org-mode))
536 (when (looking-back regexp)
537 (match-string-no-properties 1)))))
538 #+END_SRC
539
540 **** DISABLED =company-math=
541 Install =company-math= and add it to =company-backends=.
542 ***** Unicode Symbols
543 Enable unicode symbol backend globally.
544 #+BEGIN_SRC emacs-lisp
545 (use-package company-math
546 :ensure t)
547 ;; :init (add-to-list 'company-backends
548 ;; '(company-math-symbols-unicode)))
549 #+END_SRC
550
551 ***** Math Symbols
552 Enable math symbol backend only in =TeX-mode= and =org-mode=.
553 #+BEGIN_SRC emacs-lisp
554 (defun user/company-math-init()
555 (setq-local company-backends
556 (append '((company-math-symbols-latex
557 ;;company-math-symbols-unicode
558 company-auctex-macros
559 company-auctex-symbols
560 company-auctex-environments))
561 company-backends)))
562
563 (add-hook 'TeX-mode-hook 'user/company-math-init)
564 (add-hook 'org-mode-hook 'user/company-math-init)
565 #+END_SRC
566 **** =company-anaconda=
567 Install =company-anaconda= and add it to =company-backends=.
568 #+BEGIN_SRC emacs-lisp
569 (use-package company-anaconda
570 :ensure t
571 :init (add-to-list 'company-backends
572 'company-anaconda))
573 #+END_SRC
574
575 **** =company-go=
576 Auto complete for =go=. This relies on =gocode= to be installed using =go get=. Either install from [[https://github.com/mdempsky/gocode][github.com/mdempsky/gocode]] or [[https://github.com/stamblerre/gocode][github.com/stamblerre/gocode]] (supports go-modules).
577
578 #+BEGIN_SRC emacs-lisp
579 (use-package company-go
580 :ensure t
581 :init (add-to-list 'company-backends
582 'company-go))
583 #+END_SRC
584
585 **** =company-lsp=
586 Company completion via =company-lsp=. =lsp-mode= will add the appropriate backend.
587 #+BEGIN_SRC emacs-lisp
588 (use-package company-lsp
589 :ensure t)
590 #+END_SRC
591
592 **** =company-yasnippet=
593 Add =company-yasnippet= backend for =yasnippet= key completion.
594 #+BEGIN_SRC emacs-lisp
595 (defun user/enable-yas-for-backend (backend)
596 "Add yasnippet support for specified BACKEND."
597 (if (and (listp backend) (member 'company-yasnippet backend))
598 backend
599 (append (if (consp backend) backend (list backend))
600 '(:with company-yasnippet))))
601
602 ;; Enable for all company backends. Add to hook to prevent missed backends.
603 (add-hook 'yas-minor-mode-hook
604 (lambda()
605 (setq company-backends
606 (mapcar #'user/enable-yas-for-backend company-backends))))
607 #+END_SRC
608
609 *** =yasnippet= Conflict
610 Pressing tab with company mode conflicts with =yasnippets=, this is the only fix
611 that I found that makes everything work as expected. Make sure this is placed after backend settings.
612 #+BEGIN_SRC emacs-lisp
613 (defun user/check-expansion()
614 (save-excursion
615 (if (looking-at "\\_>") t
616 (backward-char 1)
617 (if (looking-at "\\.") t
618 (backward-char 1)
619 (if (looking-at "->") t nil)))))
620
621 (defun user/do-yas-expand()
622 (let ((yas-fallback-behavior 'return-nil))
623 (yas-expand)))
624
625 (defun user/tab-indent-or-complete()
626 (interactive)
627 (if (minibufferp)
628 (minibuffer-complete)
629 (if (or (not yas-minor-mode)
630 (null (user/do-yas-expand)))
631 (if (user/check-expansion)
632 (company-complete-common)
633 (indent-for-tab-command)))))
634
635 (global-set-key (kbd "TAB") 'user/tab-indent-or-complete)
636 #+END_SRC
637
638 ** Flycheck
639 Flycheck is a modern on-the-fly syntax checking extension for GNU
640 Emacs, intended as replacement for the older Flymake extension which
641 is part of GNU Emacs.
642
643 *** Installation
644 Install =flycheck=.
645 #+BEGIN_SRC emacs-lisp
646 (use-package flycheck
647 :ensure t
648 :init (global-flycheck-mode))
649 #+END_SRC
650
651 *** Set C++ Standard
652 Use =c++20= as the C++ standard.
653 #+BEGIN_SRC emacs-lisp
654 (add-hook 'c++-mode-hook
655 (lambda () (progn
656 (setq flycheck-cppcheck-standards '("c++20"))
657 (setq flycheck-clang-language-standard "c++20")
658 (setq flycheck-gcc-language-standard "c++20"))))
659 #+END_SRC
660
661 *** DISABLED Set Google C++ Syntax Checker
662 **** Install =flycheck-google-cpplint=
663 Add Google C++ Style checker for =flycheck= (Now deprecated, using local copy).
664 On Arch Linux, if using AUR package =cpplint=, need to modify command
665 in =flycheck-google-cpplint.el= to use =cpplint= instead of
666 =cppling.py=.
667 #+BEGIN_SRC emacs-lisp
668 (use-package flycheck-google-cpplint
669 :load-path "local/flycheck-google-cpplint/"
670 :config
671 (eval-after-load 'flycheck
672 '(progn
673 (require 'flycheck-google-cpplint)
674 ;; Add Google C++ Style checker.
675 ;; In default, syntax checked by Clang and Cppcheck.
676 ;; Use Google Checker after errors are cleared
677 (flycheck-add-next-checker 'c/c++-cppcheck
678 '(error . c/c++-googlelint)))))
679 #+END_SRC
680
681 **** Set Checker Parameters
682 Set various parameters for the checker.
683 #+BEGIN_SRC emacs-lisp
684 (custom-set-variables
685 '(flycheck-googlelint-verbose "5")
686 '(flycheck-googlelint-filter "-legal/copyright,-whitespace/braces")
687 '(flycheck-googlelint-linelength "80"))
688 #+END_SRC
689
690 *** Proselint
691 A linter for prose, checks grammar and style errors. Setting from [[https://unconj.ca/blog/linting-prose-in-emacs.html][here]].
692
693 #+BEGIN_SRC emacs-lisp
694 (flycheck-define-checker proselint
695 "A linter for prose."
696 :command ("proselint" source-inplace)
697 :error-patterns
698 ((warning line-start (file-name) ":" line ":" column ": "
699 (id (one-or-more (not (any " "))))
700 (message) line-end))
701 :modes (text-mode markdown-mode gfm-mode org-mode))
702
703 (add-to-list 'flycheck-checkers 'proselint)
704 #+END_SRC
705
706 ** Yasnippet
707 YASnippet is a template system for Emacs. It allows you to type an
708 abbreviation and automatically expand it into function templates.
709
710 *** Installation
711 Install =yasnippet=. Load =yasnippet= when =yas-minor-mode= is called
712 and add the hook for =yas-minor-mode= for programming modes. Reload
713 the snippets on start up.
714 #+BEGIN_SRC emacs-lisp
715 (require 'cl)
716 (use-package yasnippet
717 :ensure t
718 :commands (yas-minor-mode)
719 :init (yas-global-mode)
720 :config (yas-reload-all))
721 #+END_SRC
722
723 *** Install =yasnippet-snippets=
724 =yasnippet-snippets= is a collection of snippets for many langulages.
725 #+BEGIN_SRC emacs-lisp
726 (use-package yasnippet-snippets
727 :ensure t)
728 #+END_SRC
729
730 * Mode Specific
731 Settings specific to a mode or defines a new mode that often
732 specializes Emacs for a certain programming language.
733
734 ** Auctex
735 =auctex= is an extensible package for writing and formatting TEX files
736 in GNU Emacs.
737
738 *** Installation
739 Need to use =defer= as =auctex.el= does not actually provide =auctex= feature.
740 #+BEGIN_SRC emacs-lisp
741 (use-package auctex
742 :defer t
743 :ensure t)
744 #+END_SRC
745
746 *** Automatic Parsing
747 Enable =auctex= to automatically parse buffer information.
748 #+BEGIN_SRC emacs-lisp
749 (setq TeX-parse-self t)
750 (setq TeX-auto-save t)
751 (setq TeX-save-query nil)
752 #+END_SRC
753
754 *** Master File Detection
755 Let =auctex= figure out the master file for TeX document spread over many files.
756 #+BEGIN_SRC emacs-lisp
757 (setq-default TeX-master nil)
758 #+END_SRC
759
760 *** Spell Checking
761 Spell checking with =flyspell=.
762 #+BEGIN_SRC emacs-lisp
763 (add-hook 'LaTeX-mode-hook 'flyspell-mode)
764 #+END_SRC
765
766 *** Enable =reftex=
767 Turn on RefTeX Mode for all LaTeX files. This enables you to jump via table of contents.
768 The key to invoke this is ~C-c =~.
769 #+BEGIN_SRC emacs-lisp
770 (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode
771 #+END_SRC
772
773 *** Enable =LaTeX-math-mode=
774 Enable LaTeX Math mode. This allows macro insertion following ~`~.
775 Not exactly useful since we already have =company=.
776 #+BEGIN_SRC emacs-lisp
777 (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
778 #+END_SRC
779
780 **** Auto-complete Sub/Superscripts
781 Insert braces after ~_~ or ~^~.
782 #+BEGIN_SRC emacs-lisp
783 (setq TeX-electric-sub-and-superscript t)
784 #+END_SRC
785
786 ** C/C++-mode
787 *** DISABLED Default Indention
788 Set default indention level to 4 and style to "linux"(do not indent braces).
789 #+BEGIN_SRC emacs-lisp
790 (setq-default c-default-style "linux"
791 c-basic-offset 4)
792 #+END_SRC
793
794 *** Google Style
795 Google's C/C++ style for c-mode.
796 **** Installation
797 #+BEGIN_SRC emacs-lisp
798 (use-package google-c-style
799 :ensure t
800 :init
801 (add-hook 'c-mode-common-hook 'google-set-c-style)
802 (add-hook 'c-mode-common-hook 'google-make-newline-indent))
803 #+END_SRC
804
805 *** Treat =.h= as C++
806 Identify =.h= files as C++ files instead of C. To enable =c++-mode=
807 manually, type =M-x c\+\+-mode=.
808 #+BEGIN_SRC emacs-lisp
809 (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
810 #+END_SRC
811
812 *** Clang-format
813 **** Installation
814 Install and set hot keys for formatting.
815 #+BEGIN_SRC emacs-lisp
816 (use-package clang-format
817 :ensure t
818 :init
819 (global-set-key (kbd "C-c i") 'clang-format-region)
820 (global-set-key (kbd "C-c u") 'clang-format-buffer))
821 #+END_SRC
822
823 **** Set code style
824 Use Google's C++ style.
825 #+BEGIN_SRC emacs-lisp
826 (custom-set-variables '(clang-format-style "file"))
827 #+END_SRC
828
829 *** Doxygen Highlighting
830 Add highlighting for doxygen blocks.
831 #+BEGIN_SRC emacs-lisp
832 (use-package highlight-doxygen
833 :ensure t
834 :init
835 (add-hook 'c-mode-common-hook 'highlight-doxygen-mode))
836 #+END_SRC
837
838 ** CMake-mode
839 Syntax highlighting and indention for =CMakeLists.txt=.
840 #+BEGIN_SRC emacs-lisp
841 (use-package cmake-mode
842 :ensure t)
843 #+END_SRC
844
845 *** Eldoc Support
846 Eldoc for CMake.
847 #+BEGIN_SRC emacs-lisp
848 (use-package eldoc-cmake
849 :ensure t
850 :hook (cmake-mode . eldoc-cmake-enable))
851 #+END_SRC
852
853 *** Extended syntax highlighting
854 Additional syntax highlighting for CMake. For some reason manual activation is still required.
855 #+BEGIN_SRC emacs-lisp
856 (use-package cmake-font-lock
857 :ensure t
858 :init (autoload 'cmake-font-lock-activate "cmake-font-lock" nil t)
859 :hook (cmake-mode . cmake-font-lock-activate))
860 #+END_SRC
861
862 ** ESS
863 Use ESS (Emacs Speaks Statistics) for R and Julia support.
864 #+BEGIN_SRC emacs-lisp
865 (use-package ess
866 :ensure t
867 :config
868 ;; Add latex symbol completion in julia buffer mode as well.
869 (add-hook 'ess-julia-mode-hook
870 (lambda()
871 (add-hook 'completion-at-point-functions
872 'ess-julia-latexsub-completion nil 'local)))
873 (add-hook 'ess-mode-hook
874 (lambda () (ess-set-style 'RStudio)))
875 (setq tab-always-indent 'complete))
876 #+END_SRC
877
878 *** DISABLED Auto Format R Code
879 Use the =styler= R package to format buffer or region. Modeled after =yapfify=.
880 #+BEGIN_SRC emacs-lisp
881 (defun user/r-format-call-bin (input-buffer output-buffer beginning end)
882 "Format specified region in INPUT-BUFFER saving the output to OUTPUT-BUFFER.
883
884 BEGINNING and END specify region to format."
885 (with-current-buffer input-buffer
886 (write-region beginning end "r-format-temp.R"))
887 (call-process "R" nil nil nil "-e"
888 "library(styler);style_file(\"r-format-temp.R\")")
889 (with-current-buffer output-buffer
890 (insert-file-contents "r-format-temp.R" nil nil nil t))
891 (with-current-buffer input-buffer
892 (delete-region beginning end)
893 (insert-buffer-substring output-buffer))
894 (delete-file "r-format-temp.R"))
895
896 (defun user/r-format-region (beginning end)
897 "Try to r-format the current region.
898
899 Output from R is stored in *r-format*."
900 (interactive "r")
901 (let* ((original-buffer (current-buffer))
902 (original-point (point)) ; Because we are replacing text, save-excursion does not always work.
903 (buffer-windows (get-buffer-window-list original-buffer nil t))
904 (original-window-pos (mapcar 'window-start buffer-windows))
905 (tmpbuf (generate-new-buffer "*r-format*"))
906 (r-output (user/r-format-call-bin original-buffer tmpbuf beginning end)))
907 (deactivate-mark)
908 ;; Clean up tmpbuf
909 (kill-buffer tmpbuf)
910 ;; restore window to similar state
911 (goto-char original-point)
912 (mapcar* 'set-window-start buffer-windows original-window-pos)))
913
914 (defun user/r-format-buffer ()
915 "Format whole buffer."
916 (interactive)
917 (user/r-format-region (point-min) (point-max)))
918 #+END_SRC
919
920 Auto format bindings for =ess-r-mode=. Need a keybinding as auto formatting doesn't seem to work for org-mode =src= blocks.
921 #+BEGIN_SRC emacs-lisp
922 (defun user/r-format-before-save ()
923 "Runs r-format on current buffer if in ess-r-mode."
924 (interactive)
925 (when (eq major-mode 'ess-r-mode) (user/r-format-buffer)))
926
927 (add-hook 'ess-r-mode-hook
928 (lambda () (local-set-key (kbd "C-c u") 'user/r-format-buffer)))
929
930 (add-hook 'before-save-hook 'user/r-format-before-save)
931 #+END_SRC
932
933 ** Lsp-mode
934 Use Language Server Protocol (LSP) for code completion, jump to definition, etc. Check [[https://github.com/emacs-lsp/lsp-mode#supported-languages][list of language servers]] and install needed ones. Note that the Python language server also requires =autopepe8= and =pydocstyle=.
935
936 *** Installation
937 #+BEGIN_SRC emacs-lisp
938 (use-package lsp-mode
939 :ensure t
940 :init
941 ;; (add-hook 'prog-mode-hook #'lsp)
942 (setq lsp-prefer-flymake nil)
943 :config
944 (setq lsp-keymap-prefix "C-c p")
945 (add-to-list 'lsp--formatting-indent-alist
946 '(ess-r-mode . ess-indent-offset))
947 :bind-keymap
948 ("C-c p" . lsp-command-map))
949 #+END_SRC
950
951 *** Flycheck Integration
952 Flycheck integration via =lsp-ui=.
953 #+BEGIN_SRC emacs-lisp
954 (use-package lsp-ui
955 :ensure t
956 :init
957 (add-hook 'lsp-mode-hook 'lsp-ui-mode)
958 (setq lsp-ui-flycheck-enable t))
959 #+END_SRC
960
961 ** Go-mode
962 Remember to set =$GOPATH= environment variable and add =$GOPATH/bin= to =$PATH=.
963
964 *** Go-mode
965 #+BEGIN_SRC emacs-lisp
966 (use-package go-mode
967 :ensure t
968 :init
969 (add-to-list 'auto-mode-alist '("\\.go\\'" . go-mode))
970 (add-hook 'before-save-hook 'gofmt-before-save))
971 #+END_SRC
972
973 *** go-guru
974 Helpful code analysis tool, requires [[https://godoc.org/golang.org/x/tools/cmd/guru][golang.org/x/tools/cmd/guru]].
975
976 #+BEGIN_SRC emacs-lisp
977 (use-package go-guru
978 :ensure t)
979 #+END_SRC
980
981 ** Julia-mode
982 *** Julia-mode
983 Official major mode for =julia=. This is required as a dependency for =ess-julia-mode=.
984 #+BEGIN_SRC emacs-lisp
985 (use-package julia-mode
986 :ensure t)
987 #+END_SRC
988
989 *** Flycheck Support
990 Flycheck support via =flycheck-julia=. This relies on [[https://github.com/tonyhffong/Lint.jl][Lint.jl]], which doesn't have a release yet for Julia 1.0. A work around is to give the repository URL to =Pkg= instead of the package name and fix 1.0 incompatibilities as they show up.
991 #+BEGIN_SRC emacs-lisp
992 (use-package flycheck-julia
993 :ensure t
994 :init
995 (add-hook 'ess-julia-mode-hook #'flycheck-julia-setup))
996 #+END_SRC
997
998 *** Better REPL
999 This is a minor mode for interacting with a Julia REPL running inside Emacs.
1000 #+BEGIN_SRC emacs-lisp
1001 (use-package julia-repl
1002 :ensure t
1003 :init
1004 (with-eval-after-load 'julia-mode
1005 (add-hook 'flycheck-mode-hook #'flycheck-julia-setup)))
1006 #+END_SRC
1007
1008 ** Org-mode
1009 =org-mode= specific settings.
1010
1011 *** Allow Alphabetical Ordering
1012 Allows the use of "a." or "b)" in ordered lists.
1013 #+BEGIN_SRC emacs-lisp
1014 (setq org-list-allow-alphabetical t)
1015 #+END_SRC
1016
1017 *** Global Keybindings
1018 Set up keybindings for global access.
1019 #+BEGIN_SRC emacs-lisp
1020 (global-set-key "\C-cl" 'org-store-link)
1021 (global-set-key "\C-ca" 'org-agenda)
1022 (global-set-key "\C-cc" 'org-capture)
1023 (global-set-key "\C-cb" 'org-switchb)
1024 #+END_SRC
1025
1026 *** Formatting
1027 **** Emphasis Boundary Regex
1028 Allow non-ASCII characters (CJK characters for instance) to be boundaries for
1029 Org emphasis markers. This need to happen before =org-mode= is loaded.
1030 #+BEGIN_SRC emacs-lisp
1031 (use-package org
1032 :init
1033 (setq org-emphasis-regexp-components
1034 (list (concat " \t('\"{" "[:nonascii:]") ;; prematch
1035 (concat "- \t.,:!?;'\")}\\[" "[:nonascii:]") ;; postmatch
1036 " \t\r\n,\"'" ;; border
1037 "." ;; body-regexp
1038 1))) ;; newline
1039 #+END_SRC
1040
1041 **** DISABLED Set Link Format
1042 Do not collapse the links.
1043 #+BEGIN_SRC emacs-lisp
1044 (org-toggle-link-display)
1045 #+END_SRC
1046
1047 **** Subtree Indention
1048 Do not change text indention when promoting/demoting subtrees.
1049 #+BEGIN_SRC emacs-lisp
1050 (setq org-adapt-indentation nil)
1051 #+END_SRC
1052
1053 **** Truncate Lines by Default
1054 Automatically enable truncated lines when starting =org-mode=.
1055 #+BEGIN_SRC emacs-lisp
1056 (setq-default org-startup-truncated t)
1057 #+END_SRC
1058
1059 **** DISABLED Turn Off =auto-fill=
1060 Disable =auto-fill-mode= when in =org-mode=.
1061 #+BEGIN_SRC emacs-lisp
1062 (add-hook 'org-mode-hook 'turn-off-auto-fill)
1063 #+END_SRC
1064
1065 **** Display Inline Images
1066 Display inline images for =org-babel= execution results.
1067 #+BEGIN_SRC emacs-lisp
1068 (add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
1069 (add-hook 'org-mode-hook 'org-display-inline-images)
1070 #+END_SRC
1071
1072 **** Protect Folded Regions
1073 Don't allow editing of folded regions
1074 #+BEGIN_SRC emacs-lisp
1075 (setq org-catch-invisible-edits 'error)
1076 #+END_SRC
1077
1078 **** DISABLED Enforce TODO Dependencies
1079 Parent tasks should not be marked DONE until all subtasks are marked as DONE.
1080 #+BEGIN_SRC emacs-lisp
1081 (setq org-enforce-todo-dependencies t)
1082 #+END_SRC
1083
1084 **** Highlight LaTeX Related Syntax
1085 Non-nil means highlight LaTeX related syntax in the buffer. When non nil, the value should be a list containing any of the following symbols:
1086 - `latex' Highlight LaTeX snippets and environments.
1087 - `script' Highlight subscript and superscript.
1088 - `entities' Highlight entities.
1089
1090 #+BEGIN_SRC emacs-lisp
1091 (eval-after-load 'org
1092 '(setf org-highlight-latex-and-related '(latex)))
1093 #+END_SRC
1094
1095 **** Default Image Size
1096 In LaTeX export, the default image size is =width=.9\linewidth=, which is way too large. Setting this to empty allows images to retain it's original size.
1097 #+BEGIN_SRC emacs-lisp
1098 (setq org-latex-image-default-width ".6\\linewidth")
1099 #+END_SRC
1100
1101 *** Enable spell checking
1102 Spell checking with =flyspell-mode=. Would need to install dictionary lib like =aspell= in base system.
1103 #+BEGIN_SRC emacs-lisp
1104 (add-hook 'org-mode-hook 'flyspell-mode)
1105 #+END_SRC
1106
1107 *** Enable Code Evaluation
1108 Enable evaluation of various languages in org-mode.
1109 #+BEGIN_SRC emacs-lisp
1110 (defvar user/org-babel-enabled-languages
1111 '(emacs-lisp
1112 python
1113 R
1114 org)
1115 "Extra languages user can execute in org-babel code blocks.")
1116
1117 (org-babel-do-load-languages
1118 'org-babel-load-languages
1119 (mapcar
1120 (lambda (arg) (cons arg t))
1121 user/org-babel-enabled-languages))
1122 #+END_SRC
1123
1124 There is no need to confirm execution for these languages.
1125 #+BEGIN_SRC emacs-lisp
1126 (defvar user/org-babel-no-confirm-languages
1127 '(emacs-lisp
1128 python
1129 R
1130 latex-macros
1131 org)
1132 "Languages that do not user confirmation to execute")
1133
1134 (setq org-confirm-babel-evaluate
1135 (lambda (lang body)
1136 (not (member lang
1137 (mapcar (lambda (arg) (symbol-name arg))
1138 user/org-babel-no-confirm-languages)))))
1139 #+END_SRC
1140
1141 *** Exporter Backends
1142 **** HTML
1143 Do not export validation link.
1144 #+BEGIN_SRC emacs-lisp
1145 (setq org-html-validation-link nil)
1146 #+END_SRC
1147
1148 **** Markdown (Blackfriday)
1149 An Org exporter backend that exports Org to Hugo-compatible Markdown
1150 (Blackfriday) and generates the front-matter (in TOML or YAML format).
1151
1152 ***** Installation
1153 Enable =ox-hugo= as an option for exporting.
1154 #+BEGIN_SRC emacs-lisp
1155 (use-package ox-hugo
1156 :ensure t
1157 :init (with-eval-after-load 'ox (require 'ox-hugo)))
1158 #+END_SRC
1159
1160 ***** Export Key Bindings
1161 Wrap key bindings in =<kbd>=.
1162 #+BEGIN_SRC emacs-lisp
1163 (setq org-hugo-use-code-for-kbd t)
1164 #+END_SRC
1165
1166 **** Pandoc
1167 This is another exporter for org-mode that translates Org-mode file to various
1168 other formats via Pandoc.
1169
1170 ***** Installation
1171 #+BEGIN_SRC emacs-lisp
1172 (use-package ox-pandoc
1173 :ensure t)
1174 #+END_SRC
1175
1176 **** Jupyter Notebook
1177 Export backend for =.ipynb=. Package is not in MELPA yet, so using local copy. Repository is located [[https://github.com/jkitchin/ox-ipynb][here]].
1178
1179 #+BEGIN_SRC emacs-lisp
1180 (use-package ox-ipynb
1181 :load-path "local/ox-ipynb/")
1182 #+END_SRC
1183
1184 Quick and easy hack to get python source blocks to work.
1185 #+BEGIN_SRC emacs-lisp
1186 (setq ox-ipynb-kernelspecs
1187 '((ipython . (kernelspec . ((display_name . "Python 3")
1188 (language . "python")
1189 (name . "python3"))))
1190 (python . (kernelspec . ((display_name . "Python 3")
1191 (language . "python")
1192 (name . "python3"))))
1193 (R . (kernelspec . ((display_name . "R")
1194 (language . "R")
1195 (name . "ir"))))
1196 (julia . (kernelspec . ((display_name . "Julia 0.6.0")
1197 (language . "julia")
1198 (name . "julia-0.6"))))))
1199
1200 (setq ox-ipynb-language-infos
1201 '((ipython . (language_info . ((codemirror_mode . ((name . ipython)
1202 (version . 3)))
1203 (file_extension . ".py")
1204 (mimetype . "text/x-python")
1205 (name . "python")
1206 (nbconvert_exporter . "python")
1207 (pygments_lexer . "ipython3")
1208 (version . "3.5.2"))))
1209 (python . (language_info . ((codemirror_mode . ((name . ipython)
1210 (version . 3)))
1211 (file_extension . ".py")
1212 (mimetype . "text/x-python")
1213 (name . "python")
1214 (nbconvert_exporter . "python")
1215 (pygments_lexer . "ipython3")
1216 (version . "3.5.2"))))
1217 (R . (language_info . ((codemirror_mode . "r")
1218 (file_extension . ".r")
1219 (mimetype . "text/x-r-source")
1220 (name . "R")
1221 (pygments_lexer . "r")
1222 (version . "3.3.2"))))
1223 (julia . (language_info . ((codemirror_mode . "julia")
1224 (file_extension . ".jl")
1225 (mimetype . "text/x-julia")
1226 (name . "julia")
1227 (pygments_lexer . "julia")
1228 (version . "0.6.0"))))))
1229 #+END_SRC
1230
1231 **** LaTeX
1232 ***** LaTeX Macros
1233 Support LaTeX macros in both LaTeX and HTML/MathJax export. We do this by adding
1234 a dummy language to Babel. Idea comes form [[https://www.reddit.com/r/orgmode/comments/7u2n0h/tip_for_defining_latex_macros_for_use_in_both/][here]].
1235 #+BEGIN_SRC emacs-lisp
1236 (add-to-list 'org-src-lang-modes '("latex-macros" . latex))
1237
1238 (defvar org-babel-default-header-args:latex-macros
1239 '((:results . "raw")
1240 (:exports . "results")))
1241
1242 (defun user/prefix-all-lines (pre body)
1243 (with-temp-buffer
1244 (insert body)
1245 (string-insert-rectangle (point-min) (point-max) pre)
1246 (buffer-string)))
1247
1248 (defun org-babel-execute:latex-macros (body _params)
1249 (concat
1250 (user/prefix-all-lines "#+LATEX_HEADER: " body)
1251 "\n#+HTML_HEAD_EXTRA: <div style=\"display: none\"> \\(\n"
1252 (user/prefix-all-lines "#+HTML_HEAD_EXTRA: " body)
1253 "\n#+HTML_HEAD_EXTRA: \\)</div>\n"))
1254 #+END_SRC
1255
1256 ***** LaTeX Preview Scaling
1257 Default size is a bit small. Also note that the =fullpage= package can cause preview images to become really tall. Use =dvisvgm= backend for clearer image.
1258
1259 #+BEGIN_SRC emacs-lisp
1260 (plist-put org-format-latex-options :scale 1.75)
1261 (setq org-latex-create-formula-image-program 'dvisvgm)
1262 #+END_SRC
1263
1264 ***** Code Listing
1265 Use =minted= for code listings. Relies on =pygments= for syntax highlighting.
1266 #+BEGIN_SRC emacs-lisp
1267 (setq org-latex-listings 'minted)
1268 (setq org-latex-minted-options
1269 '(("frame" "single")
1270 ("fontsize" "\\scriptsize")))
1271 (add-to-list 'org-latex-packages-alist '("" "minted" nil))
1272 #+END_SRC
1273
1274 ***** SVG Support
1275 Use =svg= for supporting SVGs. Requires =inkscape= to be installed.
1276 #+BEGIN_SRC emacs-lisp
1277 (add-to-list 'org-latex-packages-alist '("" "svg" nil))
1278 #+END_SRC
1279
1280 ***** Shell Escape
1281 This is required for =minted= and =svg= to work.
1282 #+begin_src emacs-lisp
1283 (setq org-latex-pdf-process
1284 '("%latex -shell-escape -interaction nonstopmode -output-directory %o %f"
1285 "%latex -shell-escape -interaction nonstopmode -output-directory %o %f"
1286 "%latex -shell-escape -interaction nonstopmode -output-directory %o %f"))
1287 #+end_src
1288
1289 ** Python-mode
1290 Enhancements to =python-mode=.
1291
1292 *** Anaconda Mode
1293 Code navigation, documentation lookup and completion for Python.
1294 #+BEGIN_SRC emacs-lisp
1295 (use-package anaconda-mode
1296 :ensure t
1297 :init
1298 (add-hook 'python-mode-hook 'anaconda-mode)
1299 (add-hook 'python-mode-hook 'anaconda-eldoc-mode))
1300 #+END_SRC
1301
1302 *** Auto Format
1303 **** black
1304 Use =black= to auto format python buffers on save.
1305 #+BEGIN_SRC emacs-lisp
1306 (use-package blacken
1307 :ensure t
1308 :init
1309 (add-hook 'python-mode-hook 'blacken-mode))
1310 #+END_SRC
1311
1312 **** isort
1313 Use =isort= to sort imports.
1314 #+BEGIN_SRC emacs-lisp
1315 (use-package isortify
1316 :ensure t
1317 :init
1318 (add-hook 'python-mode-hook 'isortify-mode)
1319 (setq isortify-multi-line-output 3)
1320 (setq isortify-trailing-comma t)
1321 (setq isortify-line-width 88))
1322 #+END_SRC
1323
1324 Use =black=-compatible settings as recommended [[https://github.com/python/black#how-black-wraps-lines][here]]. Add missing variables to conform with =black=.
1325 #+BEGIN_SRC emacs-lisp
1326 (defcustom isortify-force-grid-wrap nil
1327 "Force from imports to be grid wrapped regardless of line length, where the value given is the number of imports allowed before wrapping occurs.")
1328
1329 (defcustom isortify-use-parentheses nil
1330 "Tells isort to use parenthesis for line continuation instead of \ for lines over the allotted line length limit.")
1331
1332 (setq isortify-force-grid-wrap 0)
1333 (setq isortify-use-parentheses t)
1334
1335 (defun isortify-call-args ()
1336 "Collect CLI arguments for isort process."
1337 (let (args)
1338 (when (string= "ipython" python-shell-interpreter)
1339 (push "--" args))
1340 (when isortify-multi-line-output
1341 (push "--multi-line" args)
1342 (push (number-to-string isortify-multi-line-output) args))
1343 (when isortify-trailing-comma
1344 (push "--trailing-comma" args))
1345 (when isortify-known-first-party
1346 (dolist (project isortify-known-first-party)
1347 (push "--project" args)
1348 (push project args)))
1349 (when isortify-known-third-party
1350 (dolist (thirdparty isortify-known-third-party)
1351 (push "--thirdparty" args)
1352 (push thirdparty args)))
1353 (when isortify-lines-after-imports
1354 (push "--lines-after-imports" args)
1355 (push (number-to-string isortify-lines-after-imports) args))
1356 (when isortify-line-width
1357 (push "--line-width" args)
1358 (push (number-to-string isortify-line-width) args))
1359 (when isortify-force-grid-wrap
1360 (push "--force-grid-wrap" args)
1361 (push (number-to-string isortify-force-grid-wrap) args))
1362 (when isortify-use-parentheses
1363 (push "--use-parentheses" args))
1364 (push "-" args)
1365 (reverse args)))
1366 #+END_SRC
1367
1368
1369 **** DISABLED yapf
1370 Use =yapf= to auto format python buffers on save.
1371 #+BEGIN_SRC emacs-lisp
1372 (use-package yapfify
1373 :ensure t
1374 :init
1375 (add-hook 'python-mode-hook 'yapf-mode))
1376 #+END_SRC
1377
1378 **** DISABLED pep8
1379 Use =py-autopep8= to auto format python buffers on save.
1380 #+BEGIN_SRC emacs-lisp
1381 (use-package py-autopep8
1382 :ensure t
1383 :init
1384 (add-hook 'python-mode-hook 'py-autopep8-enable-on-save))
1385 #+END_SRC
1386
1387 *** Syntax Checking
1388 **** Flycheck
1389 By default =flycheck= only runs one available python checker.
1390 #+BEGIN_SRC emacs-lisp
1391 (flycheck-add-next-checker 'python-flake8 'python-pylint)
1392 #+END_SRC
1393
1394 **** DISABLED pycheckers
1395 By default =flycheck= only runs one available python checker. Use
1396 =flycheck-pycheckers=.
1397 #+BEGIN_SRC emacs-lisp
1398 (use-package flycheck-pycheckers
1399 :ensure t
1400 :init
1401 (setq flycheck-pycheckers-checkers '(pylint flake8))
1402 (add-hook 'flycheck-mode-hook #'flycheck-pycheckers-setup))
1403 #+END_SRC
1404
1405 *** Python Interpretor
1406 Use =ipython= as default interpreter and disable feature warning.
1407
1408 #+BEGIN_SRC emacs-lisp
1409 (setq python-shell-interpreter "ipython"
1410 python-shell-interpreter-args "-i --simple-prompt"
1411 python-shell-prompt-detect-failure-warning nil)
1412 (add-to-list 'python-shell-completion-native-disabled-interpreters
1413 "ipython")
1414 #+END_SRC
1415
1416 ** Rust-mode
1417 A compilation of settings for programming in rust. The recommended way to
1418 install rust is via =rustup=. Remember to use =rustup add component= to install
1419 =rust-fmt=, =rust-src=, and =rls=.
1420
1421 *** Rust-mode
1422 Install =rust-mode=, use =rust-fmt= to format the code upon saving,
1423 and automatically enable =rust-mode= for =*.rs= files.
1424 #+BEGIN_SRC emacs-lisp
1425 (use-package rust-mode
1426 :ensure t
1427 :init
1428 (setq rust-format-on-save t)
1429 (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode)))
1430 #+END_SRC
1431
1432 *** Cargo Integration
1433 A minor mode for =cargo=, the package manager for rust.
1434 #+BEGIN_SRC emacs-lisp
1435 (use-package cargo
1436 :ensure t
1437 :init
1438 (add-hook 'rust-mode-hook 'cargo-minor-mode))
1439 #+END_SRC
1440
1441 *** Flycheck Support
1442 Better flycheck support via =flycheck-rust=.
1443 #+BEGIN_SRC emacs-lisp
1444 (use-package flycheck-rust
1445 :ensure t
1446 :init
1447 (with-eval-after-load 'rust-mode
1448 (add-hook 'flycheck-mode-hook #'flycheck-rust-setup)))
1449 #+END_SRC
1450
1451 *** Racer
1452 Code completion utility for rust. Provides =company= integration.
1453 #+BEGIN_SRC emacs-lisp
1454 (use-package racer
1455 :ensure t
1456 :init
1457 (add-hook 'rust-mode-hook #'racer-mode)
1458 (add-hook 'rust-mode-hook #'eldoc-mode))
1459 #+END_SRC
1460
1461 ** Zig-mode
1462 #+BEGIN_SRC emacs-lisp
1463 (use-package zig-mode
1464 :ensure t)
1465 #+END_SRC
1466
1467 * Enhancements
1468 Packages providing enhancements to Emacs interface. Mostly simple plug-and-play
1469 packages. Load enhancements in the end to prevent their dependencies getting
1470 loaded prior to their own customization.
1471
1472 ** Ace Window
1473 Prepare for the age of multi-monitor and ultra-wide.
1474 #+BEGIN_SRC emacs-lisp
1475 (use-package ace-window
1476 :ensure t
1477 :bind
1478 (("M-o" . ace-window))
1479 :init
1480 (setq aw-keys '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?0)))
1481 #+END_SRC
1482
1483 ** Avy
1484 Jump to visible text using a char-based decision tree, similar to =ace-jump=.
1485 #+BEGIN_SRC emacs-lisp
1486 (use-package avy
1487 :ensure t
1488 :init
1489 (define-prefix-command 'user/avy-prefix)
1490 (global-set-key (kbd "C-:") 'user/avy-prefix)
1491 (define-key 'user/avy-prefix (kbd "c") 'avy-goto-char)
1492 (define-key 'user/avy-prefix (kbd "C") 'avy-goto-char-2)
1493 (define-key 'user/avy-prefix (kbd "t") 'avy-goto-char-timer)
1494 (define-key 'user/avy-prefix (kbd "s") 'avy-goto-char-in-line)
1495 (define-key 'user/avy-prefix (kbd "j") 'avy-goto-line-above)
1496 (define-key 'user/avy-prefix (kbd "k") 'avy-goto-line-below)
1497 (define-key 'user/avy-prefix (kbd "l") 'avy-goto-line)
1498 (define-key 'user/avy-prefix (kbd "w") 'avy-goto-word-0)
1499 (define-key 'user/avy-prefix (kbd "W") 'avy-goto-word-1)
1500 (define-key 'user/avy-prefix (kbd "o") 'avy-org-goto-heading-timer)
1501 (define-key 'user/avy-prefix (kbd "O") 'avy-org-refile-as-child))
1502 #+END_SRC
1503
1504 ** Dashboard
1505 An extensible Emacs startup screen showing you what's most important.
1506
1507 *** Installation
1508 Change default startup screen with =dashboard=.
1509 Customize =initial-buffer-choice= to affect new frames created by =emacsclient=.
1510 Also refresh dashboard to ensure customizations take effect.
1511 #+BEGIN_SRC emacs-lisp
1512 (use-package dashboard
1513 :ensure t
1514 :config
1515 (dashboard-setup-startup-hook)
1516 (setq initial-buffer-choice (lambda()
1517 (dashboard-refresh-buffer)
1518 (get-buffer "*dashboard*"))))
1519 #+END_SRC
1520
1521 *** Customize Banner and Logo
1522 Customize banner and logo.
1523 #+BEGIN_SRC emacs-lisp
1524 (defvar user/dashboard-banner-logo-titles
1525 '("42"
1526 "9 MORE SEASONS UNTIL I GET THAT DIPPING SZECHUAN SAUCE!"
1527 "Avocado + Maple Syrup = Dragon Fruit"
1528 "Eight-Megabytes-And-Constantly-Swapping"
1529 "Enter-Meta-Alt-Control-Shift"
1530 "Execute order 66."
1531 "Greetings from Emacs!"
1532 "POLYBIUS"
1533 "Project-iM@CS"
1534 "Supervillain Repair & Restoration"
1535 "This is fine."
1536 "Weak emperors mean strong viceroys."
1537 "Wissen ist Nacht!"
1538 "Wubba Lubba Dub-Dub!"))
1539 (setq dashboard-banner-logo-title
1540 (elt user/dashboard-banner-logo-titles
1541 (random (length user/dashboard-banner-logo-titles))))
1542 (setq dashboard-startup-banner
1543 (expand-file-name "static/sxs.png" user-emacs-directory))
1544 #+END_SRC
1545
1546 *** Customize Widgets
1547 **** =dashboard-insert-configs=
1548 Create widget to display important config files. Use ~c~ to jump to this section.
1549 #+BEGIN_SRC emacs-lisp
1550 (defvar user/config-file-list
1551 (mapcar (lambda (arg) (expand-file-name arg user-emacs-directory))
1552 '("README.org"
1553 "init.el"
1554 "static/math_macros.sty")))
1555
1556 (defun user/dashboard-insert-configs (list-size)
1557 "Add a list of config files."
1558 (dashboard-insert-section
1559 "Config Files:"
1560 user/config-file-list
1561 list-size
1562 "c"
1563 `(lambda (&rest ignore) (find-file-existing ,el))
1564 (abbreviate-file-name el)))
1565
1566 (add-to-list 'dashboard-item-generators '(configs . user/dashboard-insert-configs))
1567 #+END_SRC
1568
1569 **** =dashboard-insert-init-time=
1570 Display initialization time.
1571 #+BEGIN_SRC emacs-lisp
1572 (defun user/dashboard-insert-init-time (list-size)
1573 "Displays Emacs init time."
1574 (insert (format "[Started Emacs in %s.]" (emacs-init-time))))
1575
1576 (add-to-list 'dashboard-item-generators '(init-time . user/dashboard-insert-init-time))
1577 #+END_SRC
1578
1579 **** Apply All Widgets
1580 Set items to display:
1581 #+BEGIN_SRC emacs-lisp
1582 (setq dashboard-items '((recents . 10)
1583 (bookmarks . 5)
1584 (projects . 8)
1585 (agenda . 5)
1586 ; (registers . 5)
1587 (configs)
1588 (init-time)))
1589 #+END_SRC
1590
1591 ** HTML Export
1592 Convert buffer text and decorations to HTML by =htmlize-buffer= so
1593 that people can see what I see.
1594 #+BEGIN_SRC emacs-lisp
1595 (use-package htmlize
1596 :ensure t)
1597 #+END_SRC
1598
1599 ** Keybindings
1600 *** IBuffer
1601 Use =ibuffer= instead of =list-buffer=.
1602 #+BEGIN_SRC emacs-lisp
1603 (global-set-key (kbd "C-x C-b") 'ibuffer)
1604 (autoload 'ibuffer "ibuffer" "List buffers." t)
1605 #+END_SRC
1606
1607 ** Keyfreq
1608 Records command frequency. I am planning on adjusting my keyboard
1609 layout with this information.
1610 #+BEGIN_SRC emacs-lisp
1611 (use-package keyfreq
1612 :ensure t
1613 :init
1614 (keyfreq-mode 1)
1615 (keyfreq-autosave-mode 1))
1616 #+END_SRC
1617
1618 ** Magit
1619 Install =magit= and bind =magit-status= to ~C-c g~.
1620 #+BEGIN_SRC emacs-lisp
1621 (use-package magit
1622 :ensure t
1623 :init
1624 (global-set-key (kbd "C-c g") 'magit-status))
1625 #+END_SRC
1626
1627 *** Magit annex
1628 Magit support for =git-annex=.
1629 #+BEGIN_SRC emacs-lisp
1630 (use-package magit-annex
1631 :ensure t)
1632 #+END_SRC
1633
1634 ** Projectile
1635 Projectile is a project interaction library for Emacs. Its goal is to
1636 provide a nice set of features operating on a project level without
1637 introducing external dependencies(when feasible).
1638
1639 *** Installation
1640 Install =projectile=.
1641 #+BEGIN_SRC emacs-lisp
1642 (use-package projectile
1643 :ensure t
1644 :init
1645 (projectile-mode +1))
1646 #+END_SRC
1647
1648 *** DISABLED Enable =helm= support
1649 Since I use =helm=, I need to install additional support.
1650 #+BEGIN_SRC emacs-lisp
1651 (use-package helm-projectile
1652 :ensure t
1653 :init
1654 (setq projectile-completion-system 'helm)
1655 (helm-projectile-on))
1656 #+END_SRC