Emacs Configuration

1 Introduction

My literate1 Emacs configuration. http://www.cachestocaches.com/2018/6/org-literate-programming/ describes the initial set up for this type of configuration.

I keep my ~/emacs.d free of any configuration files; it stores temporary files and packages.

Notes on Emacs' dominance, reasoning behind learning and using it.

2 Main settings (vanilla Emacs)

2.1 Better Defaults

2.1.1 Misc.

;; Quickly switch between buffers with M-space
(global-set-key (kbd "M-SPC")'quick-switch-buffer)
(global-set-key (kbd "C-C SPC") 'just-one-space)
;; switch to the most recently visited buffer without asking for confirmation
(fset 'quick-switch-buffer
      (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([24 98 return] 0 "%d")) arg)))
;; show the other buffer in the current window (and frame) instead of pulling the other frame to the front
(setq ido-default-buffer-method 0)


;; Save all with M-s
(global-set-key "\M-s" 'save-all)
;; save all without asking for confirmation for each file
(fset 'save-all
      (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ("s" 0 "%d")) arg)))

(global-set-key (kbd "C-c q") 'auto-fill-mode)
;; surround region with quotes
(global-set-key (kbd "M-\"") 'insert-pair)

;; Open current heading in a new indirect buffer (in a new window)
(fset 'new-note-window
      (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([134217848 111 114 103 45 116 114 101 101 45 116 111 45 105 110 100 105 114 101 99 116 45 98 117 102 102 101 114 return 24 111 134217848 109 97 107 101 45 102 114 101 backspace 97 109 101 45 99 111 109 109 97 110 100 return] 0 "%d")) arg)))
(global-set-key [3 116] 'new-note-window)

(setq mouse-yank-at-point t) ; paste where the cursor is
(global-set-key (kbd "C-c o") 'occur)
(global-subword-mode 1)                           ; Iterate through CamelCase words
(save-place-mode 1)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "M-z") 'zap-up-to-char)
(show-paren-mode 1)
(size-indication-mode t)
(setq echo-keystrokes 0.1
      use-dialog-box nil
      visible-bell t)
;; don't show the default startup window
(setq inhibit-startup-screen t)
;; quick command to kill the current buffer
(global-set-key (kbd "C-x k") 'kill-this-buffer)
;;follow the symbolic links without asking every time
(setq vc-follow-symlinks t)
;;truncate lines
(set-default 'truncate-lines t)
;;line highlighting
(global-hl-line-mode 1)
;; Auto Saves
(setq make-backup-files nil) ; stop creating ~ files
(setq backup-by-copying t)

(defalias 'yes-or-no-p 'y-or-n-p) ; type y or n instead of yes or no

(setq  scroll-conservatively most-positive-fixnum)

(setq scroll-margin 2 )
(add-hook 'focus-out-hook #'garbage-collect) ;Garbage-collect on focus-out, Emacs should feel snappier.

(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)

(setq initial-major-mode 'org-mode) ; scratch is in org-mode
(setq initial-scratch-message nil) ; remove the initial message
(setq  column-number-mode t)

(setq-default indicate-empty-lines t) 
(when (not indicate-empty-lines)
  (toggle-indicate-empty-lines))
(setq-default tab-width 8)

2.1.2 start an emacs server if not already started

(require 'server)
(unless (server-running-p)
  (server-start))

2.1.3 Reindent the whole buffer with alt-shift-q

(defun reindent-whole-buffer ()
  "Reindent the whole buffer."
  (interactive)
  (indent-region (point-min)
                 (point-max)))
(global-set-key (kbd "M-Q") 'reindent-whole-buffer)

2.1.4 Simplified window switching commands

(global-set-key (kbd "M-o") 'other-window)
(global-set-key (kbd "M-0") 'delete-window)
(global-set-key (kbd "M-1") 'delete-other-windows)

2.1.5 split window with other buffer instead of the same buffer

(eval-when-compile (require 'cl))

(defun split-window-func-with-other-buffer (split-function)
  (lexical-let ((s-f split-function))
    (lambda ()
      (interactive)
      (funcall s-f)
      (set-window-buffer (next-window) (other-buffer)))))

(global-set-key "\M-2" (split-window-func-with-other-buffer 'split-window-vertically))
(global-set-key "\M-3" (split-window-func-with-other-buffer 'split-window-horizontally))

2.2 Look and Feel

2.2.1 UI elements

(menu-bar-mode -1)
(when (fboundp 'tool-bar-mode)
  (tool-bar-mode -1))
(when (fboundp 'scroll-bar-mode)
  (scroll-bar-mode -1))
(when (fboundp 'horizontal-scroll-bar-mode)
  (horizontal-scroll-bar-mode -1))

2.2.2 Font

(add-to-list 'default-frame-alist
             '(font . "Envy Code R 12"))
;; '(font . "DejaVu Sans Mono 14"))

2.2.3 Colors

(setq frame-background-mode 'dark)  ; no colors in terminal version:
(setq custom-safe-themes t)         ; don't bother me if I'm testing a custom theme

2.3 Spellcheck

(dolist (hook '(text-mode-hook))
  (add-hook hook (lambda () (flyspell-mode 1))))
;; (setq ‘flyspell-issue-message-flag’ nil)
(add-hook 'org-mode-hook 'turn-on-flyspell)
(add-hook 'markdown-mode-hook 'flyspell-mode)
(add-hook 'text-mode-hook 'flyspell-mode)
(add-hook 'prog-mode-hook 'flyspell-prog-mode)

;; (add-hook 'prog-mode-hook 'flyspell-prog-mode) ;; fix for ispell if it is using aspell
(setq ispell-program-name "aspell")
(setq ispell-list-command "--list")

2.4 Ido

(require 'ido)
(ido-mode 'buffers)

2.5 Quickly copy a line or multiple

(defun quick-copy-line ()
  "Copy the whole line that point is on and move to the beginning of the next line.
    Consecutive calls to this command append each line to the
    kill-ring."
  (interactive)
  (let ((beg (line-beginning-position 1))
        (end (line-beginning-position 2)))
    (if (eq last-command 'quick-copy-line)
        (kill-append (buffer-substring beg end) (< end beg))
      (kill-new (buffer-substring beg end))))
  (beginning-of-line 2))
(global-unset-key (kbd "C-t"))
(define-key global-map (kbd "C-t") 'quick-copy-line)

2.6 Misc.

(setq x-stretch-cursor t) ; make cursor the width of the character it is under (i.e. full width of a TAB)
(setq tab-always-indent 'complete) ; make tab do completion
(global-set-key [f1] 'shell) ; bind f1 to shell

3 Languages

3.1 LaTEX

(use-package tex

  :ensure auctex)

(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)

(add-hook 'LaTeX-mode-hook (lambda ()
                             (TeX-fold-mode 1)))

(setq TeX-view-program-selection '((output-pdf "Zathura")))

;; surround selection with $ instead of parenthesis in AucTeX
(defun insert-dolla-dolla-bills-yall (&optional arg)
  (interactive "P")
  (insert-pair arg ?\$ ?\$))
(add-hook 'LaTeX-mode-hook
          (lambda () (local-set-key (kbd "M-(") #'insert-dolla-dolla-bills-yall)))

;; update the pdf output of a latex document without asking which program to use and whether to save the file
(fset 'render-latex
      (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([3 3 121 return] 0 "%d")) arg)))

(add-hook 'LaTeX-mode-hook
          (lambda () (local-set-key (kbd "C-c r") #'render-latex)))

3.2 C

(setq-default c-basic-offset 8)
(setq c-default-style "linux")
;; (add-hook 'c-mode-common-hook '(lambda () (c-toggle-auto-state 1)))
;; (add-hook 'c-mode-common-hook '(lambda () (c-toggle-hungry-state 1)))

3.3 Go

(use-package go-mode)

4 Org Mode

4.1 Org Capture

;; org capture setup
(setq org-capture-templates
      '(
        ("t" "Full task capture" entry (file+headline "~/docs/tasks.gpg" "INBOX")
         "* TODO %?\n%iAdded: %u")

        ("v" "Simple capture template" entry (file "~/docs/notes.gpg")
         "* %?\n%iAdded: %u")

        ("s" "Journal entry with date, scheduled" entry (file+datetree+prompt "~/docs/journal.gpg")
         "* %^{Title}\n<%(org-read-date nil nil org-read-date-final-answer)>\n%i\n%?\n")))

(define-key global-map (kbd "C-c c") 'org-task-capture)
(defun org-task-capture ()
  "Capture a task with my full task template."
  (interactive)
  (org-capture nil "t"))

(define-key global-map (kbd "C-c v") 'org-simple-capture)
(defun org-simple-capture ()
  "Capture something with my simple capture template."
  (interactive)
  (org-capture nil "v"))

(define-key global-map (kbd "C-c s") 'org-journal-capture)
(defun org-journal-capture ()
  "Capture something with my journal capture template."
  (interactive)
  (org-capture nil "s"))

4.2 Org Agenda

(global-set-key "\C-ca" 'org-agenda)
(setq org-agenda-show-all-dates nil)
(setq org-agenda-skip-scheduled-if-done t)
(setq org-agenda-use-tag-inheritance t)
(setq org-archive-location "~/docs/archive.gpg::")
(setq org-catch-invisible-edits (quote error))
(setq org-cycle-separator-lines 0)
(defun daily-agenda ()
  "Show my normal, customized agenda view."
  (interactive)
  (org-agenda nil "x"))
(define-key global-map (kbd "C-c x") 'daily-agenda)

(defun today-agenda ()
  "Show today's tasks"
  (interactive)
  (org-agenda nil "j"))
(define-key global-map (kbd "C-c j") 'today-agenda)
(setq org-agenda-start-with-follow-mode nil)

4.3 Agenda Window settings

(setq split-height-threshold 40) ; nil
(setq split-width-threshold nil) ; 100
(setq org-agenda-window-setup 'reorganize-frame)
(setq org-agenda-restore-windows-after-quit t)
(setq org-agenda-window-frame-fractions '(1.0 . 1.0))

4.4 Misc. Org Settings

(setq org-log-done t)
(setq org-refile-use-outline-path 'file)
(setq org-refile-targets
      (quote
       ((org-agenda-files :maxlevel . 4)
        ("~/docs/notes.gpg" :maxlevel . 4))))
(setq org-todo-keywords
      '((sequence "TODO" "WAITING" "|" "DONE" "CANCELLED")))
(setq org-deadline-warning-days 30)
(setq org-edit-src-content-indentation 0)
(setq org-agenda-skip-deadline-prewarning-if-scheduled t)
;; indenting, etc works on source code blocks
(setq org-src-tab-acts-natively t)
(define-key global-map (kbd "C-c l") 'org-store-link)
(setq org-goto-interface (quote outline-path-completion))
(setq org-preview-latex-image-directory "~/.emacs.d/ltximg/")
(setq org-refile-allow-creating-parent-nodes (quote confirm))
(setq org-time-stamp-custom-formats (quote (" %B %d, %Y " . "<%m/%d/%y %a %H:%M>"))) ; human-readable dates
(setq org-hide-emphasis-markers t) ; don't show surrounding markup

4.5 Export

(setq org-html-htmlize-output-type 'css) ; default: 'inline-css
(setq org-export-headline-levels 10)
(setq org-export-with-section-numbers t)
(setq org-export-with-tags (quote not-in-toc))
;; (defun my-org-inline-css-hook (exporter)
;;   "Insert custom inline css"
;;   (when (eq exporter 'html)
;;     (let ((my-pre-bg (face-background 'default)))
;;       (setq org-html-head-include-default-style nil)
;; (setq org-html-head
;;       (format "<style type=\"text/css\">\n pre.src { background-color: %s;}</style>\n"a my-pre-bg)))))

;; (add-hook 'org-export-before-processing-hook 'my-org-inline-css-hook)
(setq org-html-head-include-scripts nil)
(setq org-html-head
      "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/>
               <link rel=\"stylesheet\" type=\"text/css\" href=\"org.css\"/>
<script src=\"./media/sidenotes.js\"> </script>
      <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">
      <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
      ")

(setq org-html-postamble nil)

4.6 Tags

(setq org-tag-alist '(
                      (:startgroup . nil)
                      ("fast" . ?f)                      
                      ("busywork" . ?b)
                      ("difficult" . ?d)
                      (:endgroup . nil)
                      ("hobby" . ?h)                      
                      ("cockroach" . ?c)
                      (:startgroup . nil)
                      ("export" . ?e)
                      ("noexport" . ?n)
                      (:endgroup . nil)
                      (:startgroup . nil)
                      ("important" . ?i)
                      ("queue" . ?u)
                      ("3" . ?3)
                      (:endgroup . nil)))

4.7 Org Autolist

(use-package org-autolist)
(add-hook 'org-mode-hook (lambda () (org-autolist-mode)))
(require 'org-autolist)

5 Encryption/Privacy

(define-minor-mode sensitive-mode
  "For sensitive files like password lists.
It disables backup creation and auto saving.

With no argument, this command toggles the mode.
Non-null prefix argument turns on the mode.
Null prefix argument turns off the mode."
  ;; The initial value.
  nil
  ;; The indicator for the mode line.
  " Sensitive"
  ;; The minor mode bindings.
  nil
  (if (symbol-value sensitive-mode)
      (progn
        ;; disable backups
        (set (make-local-variable 'backup-inhibited) t) 
        ;; disable auto-save
        (if auto-save-default
            (auto-save-mode -1)))
                                        ;resort to default value of backup-inhibited
    (kill-local-variable 'backup-inhibited)
                                        ;resort to default auto save setting
    (if auto-save-default
        (auto-save-mode 1))))

(setq auto-mode-alist
      (append '(("\\.gpg$" . sensitive-mode))
              auto-mode-alist))


(setf epa-pinentry-mode 'loopback)

;; Mutt settings
(add-to-list 'auto-mode-alist '("/neomutt" . mail-mode))
(add-hook 'mail-mode-hook 'turn-on-auto-fill)

6 Useful Packages

6.0.1 Themes

(use-package zenburn-theme)
(use-package modus-operandi-theme)
(use-package modus-vivendi-theme)
(use-package hc-zenburn-theme)
(load-theme 'zenburn t)

6.1 Smartparens

(use-package smartparens)
(require 'smartparens-config)
(smartparens-global-mode t)

6.2 Symbol Overlay (highlighting stuff)

(global-set-key (kbd "M-i") 'symbol-overlay-put)
(global-set-key (kbd "M-n") 'symbol-overlay-switch-forward)
(global-set-key (kbd "M-p") 'symbol-overlay-switch-backward)
(global-set-key (kbd "<f7>") 'symbol-overlay-mode)
(global-set-key (kbd "<f8>") 'symbol-overlay-remove-all)

6.3 HTMLize (for Org Export code blocks)

(use-package htmlize)

6.4 Hideshow-org for code folding

(add-to-list 'load-path "~/.lisp/hideshow-org")
(require 'hideshow-org)
(add-hook 'prog-mode-hook 'hs-minor-mode)
(add-hook 'prog-mode-hook 'hs-org/minor-mode)

6.5 org-ref

(use-package org-ref)
(setq reftex-default-bibliography '("~/docs/references.bib"))
(setq org-ref-default-bibliography '("~/docs/references.bib")
      org-ref-pdf-directory "~/docs/reading/papers")
(setq org-latex-pdf-process (list "rubber --pdf %f" "rubber --clean %f"))

6.6 Org-cliplink

(use-package org-cliplink)

6.7 Undo Tree Mode

(use-package undo-tree)

6.8 Persistent scratch buffer

(use-package persistent-scratch)
(persistent-scratch-setup-default)

6.9 Yasnippet

(use-package yasnippet)
(use-package yasnippet-snippets)
(yas-global-mode 1)

6.10 Bug Hunter

(use-package bug-hunter)

6.11 Writegood mode

(use-package writegood-mode)
(require 'writegood-mode)
(global-set-key "\C-cg" 'writegood-mode)

6.12 Magit

;; (use-package magit)
;; (global-set-key (kbd "C-x g") 'magit-status)

6.13 Smex, a slightly better M-x

(use-package smex)
(global-set-key (kbd "M-x") 'smex)
(global-set-key (kbd "M-X") 'smex-major-mode-commands)
;; This is your old M-x.
(global-set-key (kbd "C-c C-c M-x") 'execute-extended-command)

6.14 Keyfreq: record how often I use commands and keystrokes

(use-package keyfreq)
(keyfreq-mode 1)
(keyfreq-autosave-mode 1)
(setq keyfreq-file "~/docs/emacs.keyfreq")

Footnotes:

1

see (wikipedia link). Description of literate programming meme vs. reality; my conclusion that it's still a useful technique