dotfiles/.emacs.d/emacs.org

1453 lines
43 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#+TITLE: Emacs Configuration
#+STARTUP: indent
* Startup
** Disable the emacs startup screen.
#+name: startup
#+BEGIN_SRC emacs-lisp
(setq inhibit-startup-screen +1)
#+END_SRC
* UI
** Powerline
Make the mode line prettier.
#+name: look-and-feel
#+BEGIN_SRC emacs-lisp
(use-package powerline
:ensure t
:config
(powerline-default-theme))
#+END_SRC
** Nyan-mode
Visualize the current position within the buffer in the modeline with nyancat!
#+name: look-and-feel
#+BEGIN_SRC emacs-lisp
(use-package nyan-mode
:ensure t
:config
(nyan-mode)
(nyan-start-animation))
#+END_SRC
** Display Time & Battery Status
#+name: look-and-feel
#+BEGIN_SRC emacs-lisp
(setq battery-mode-line-format
"[%b%p%%%% (%t)]")
(display-battery-mode t)
(display-time-mode t)
#+END_SRC
** Theme
#+name: look-and-feel
#+BEGIN_SRC emacs-lisp
(use-package moe-theme
:ensure t
:config
(setq moe-theme-resize-markdown-title '(1.5 1.4 1.3 1.2 1.0 1.0))
(setq moe-theme-resize-org-title '(1.5 1.4 1.3 1.2 1.1 1.0 1.0 1.0 1.0))
(setq moe-theme-resize-rst-title '(1.5 1.4 1.3 1.2 1.1 1.0))
(setq moe-theme-highlight-buffer-id t)
(moe-theme-set-color 'cyan)
(powerline-moe-theme)
(moe-light))
#+END_SRC
** Major mode icons
Display major-mode names as icons in the mode line when possible.
#+name: look-and-feel
#+BEGIN_SRC emacs-lisp
(use-package mode-icons
:ensure t
:defer 5
:config (mode-icons-mode))
#+END_SRC
** Which-Key
Display key binding completions after a delay.
#+name: look-and-feel
#+BEGIN_SRC emacs-lisp
(use-package which-key
:ensure t
:diminish which-key-mode
:config
(which-key-setup-side-window-right-bottom)
(which-key-mode))
#+END_SRC
** Helm
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package helm
:ensure t
:diminish helm-mode
:bind (("M-x" . helm-M-x)
("M-y" . helm-show-kill-ring)
("C-x b" . helm-mini)
("C-x C-b" . helm-buffers-list)
("C-x C-f" . helm-find-files)
("C-x C-r" . helm-recentf)
("C-x c o" . helm-occur))
:config (progn
(require 'helm-config)
(helm-mode 1)
(add-hook 'eshell-mode-hook
(lambda ()
(define-key eshell-mode-map (kbd "TAB") 'helm-esh-pcomplete)
(define-key eshell-mode-map (kbd "C-c C-l") 'helm-eshell-history)))))
#+END_SRC
*** helm-descbinds
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package helm-descbinds
:ensure t
:bind (("C-h b" . helm-descbinds)
("C-h w" . helm-descbinds)))
#+END_SRC
*** helm-ag
Helm search plugin for [[Ag%20(The%20Silver%20Searcher)][Ag (The Silver Searcher)]]
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package helm-ag
:ensure t
:commands (helm-ag))
#+END_SRC
*** helm-flyspell
#+name: packages
#+begin_src emacs-lisp
(use-package helm-flyspell
:ensure t
:commands helm-flyspell-correct
:init (eval-after-load 'flyspell
'(define-key flyspell-mode-map (kbd "C-;") 'helm-flyspell-correct)))
#+end_src
*** helm-swoop
Replace isearch-forward with helm-swoop for a nicer experience.
#+BEGIN_NOTES
Quite usefully, using prefix arguments expands the lines of context
shown around the search results.
#+END_NOTES
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package helm-swoop
:ensure t
:commands (helm-swoop)
:bind (("C-s" . helm-swoop))
:config
;; Defaults to (lambda () (thing-at-point 'symbol)).
;; Setting it to return nil, as I find it tends to be more annoying than useful.
(setq helm-swoop-pre-input-function (lambda () nil))
;; Enable syntax highlighting. It makes it easier for my eyes to
;; parse the results, and doesn't seem to slow things down
;; measurably.
(setq helm-swoop-speed-or-color t)
)
#+END_SRC
** Undo-Tree
Visualize and traverse undo history as a directed graph.
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package undo-tree
:ensure t
:diminish undo-tree-mode
:config (global-undo-tree-mode))
#+END_SRC
** Multiple Cursors
#+name: look-and-feel
#+BEGIN_SRC emacs-lisp
(use-package multiple-cursors
:bind (("C-S-c C-S-c" . mc/edit-lines)
("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-c C-<" . mc/mark-all-like-this)
("C-M->" . mc/mark-more-like-this-extended)))
#+END_SRC
* Coding
** Languages
*** Lisps
#+name: lisps
| Mode | Description |
|------------+---------------------------|
| lisp | Common Lisp |
| emacs-lisp | Emacs Lisp |
| scheme | Scheme |
| lfe | Lisp-Flavored Erlang |
| clojure | Clojure |
| hy | Hy (Lisp-flavored Python) |
#+name: programming
#+BEGIN_SRC emacs-lisp :noweb yes
;; SLIME
(if (file-exists-p "~/quicklisp/slime-helper.el")
(load (expand-file-name "~/quicklisp/slime-helper.el")))
(setq inferior-lisp-program "clisp")
(use-package paredit
:ensure t
:commands (paredit-mode)
:diminish " ")
(use-package rainbow-identifiers
:ensure t
:commands (rainbow-identifiers-mode))
(use-package rainbow-delimiters
:ensure t
:commands (rainbow-delimiters-mode))
(let ((lisp-mode-hooks
(mapcar (lambda (lisp)
(intern (concat lisp "-mode-hook")))
(mapcar 'car (cddr '<<lisps()>>)))))
(mapc (lambda (hook)
(message (format "Installing LISP mode hook for %S" hook))
(add-hook hook (lambda ()
(show-paren-mode t)
(electric-indent-mode t)
(paredit-mode t)
(rainbow-delimiters-mode t)
(rainbow-identifiers-mode t))))
(cons 'eval-expression-minibuffer-setup-hook
lisp-mode-hooks)))
#+END_SRC
**** Lisp-Flavored Erlang
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package lfe-mode
:ensure t
:mode "\\.lfe$")
#+END_SRC
**** Clojure
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package clojure-mode
:ensure t
:mode (("\\.clj[sx]?$" . clojure-mode)
("\\.edn$" . clojure-mode)))
#+END_SRC
***** Cider
Communicates with the clojure REPL.
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package cider
:ensure t
:commands (cider-jack-in cider)
:config (setq org-babel-clojure-backend 'cider))
#+END_SRC
**** Hy
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package hy-mode
:ensure t
:mode "\\.hy$")
#+END_SRC
*** Erlang
A distributed, fault-tolerant functional language.
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package erlang
:ensure t
:mode ("\.[eh]rl$" . erlang-mode)
:config (add-hook 'erlang-mode-hook
(lambda ()
(setq inferior-erlang-machine-options '("-sname" "emacs"
"-hidden")))))
#+END_SRC
*** Elixir
Ruby-flavoured Erlang.
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package elixir-mode
:ensure t
:mode "\\.exs?$")
(use-package alchemist
:ensure t
:after elixir-mode)
(use-package ob-elixir
:ensure t
:after ob)
#+END_SRC
*** Haskell
A strongly typed, pure functional language.
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package haskell-mode
:ensure t
:mode "\.hs$")
(use-package hi2
:ensure t
:commands turn-on-hi2
:init (add-hook 'haskell-mode-hook 'turn-on-hi2))
#+END_SRC
*** Elm
A functional, reactive language for the web that compiles to
JavaScript.
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package elm-mode
:ensure t
:mode "\.elm$"
:config
(add-hook 'elm-mode-hook #'elm-oracle-setup-completion)
(add-to-list 'company-backends 'company-elm))
#+END_SRC
*** Idris
A functional language with dependent types.
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package idris-mode
:ensure t
:mode "\.idr$")
#+END_SRC
*** Web
**** HTML
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package web-mode
:ensure t
:mode "\\.html?$")
#+END_SRC
**** SCSS
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package scss-mode
:ensure t
:mode "\\.scss$"
:config (add-hook 'scss-mode-hook
(lambda ()
"Customize SCSS indentation"
(setq css-indent-offset 2))))
#+END_SRC
*** JavaScript
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package js2-mode
:ensure t
:mode ".js$")
#+END_SRC
*** PHP
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package php-mode
:ensure t
:mode (("\\.php$" . php-mode)
("\\.inc$" . php-mode))
:config (add-hook 'php-mode-hook (lambda ()
"Customize PHP indentation"
(c-set-offset 'arglist-cont-nonempty 'c-lineup-arglist)
(c-set-offset 'substatement-open 0)
(c-set-offset 'case-label '+))))
#+END_SRC
*** Python
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package python-mode
:ensure t
:mode "\.py$")
#+END_SRC
**** Elpy
Full functionality requires a number of python packages to be
installed:
#+BEGIN_SRC sh :exports code
# Either of these
pip install rope
pip install jedi
# flake8 for code checks
pip install flake8
# importmagic for automatic imports
pip install importmagic
# and autopep8 for automatic PEP8 formatting
pip install autopep8
# and yapf for code formatting
pip install yapf
#+END_SRC
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package elpy
:ensure t
:after python
:config (elpy-enable))
#+END_SRC
**** Cython
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package cython-mode
:ensure t
:mode "\.pyx$")
#+END_SRC
**** Company-Jedi
Configure jedi and company-mode to provide auto-completion for python.
#+name: programming
#+begin_src emacs-lisp
(use-package jedi
:ensure t
:commands jedi:setup
:config (progn
(setq jedi:use-shortcuts t)
(jedi:install-server)))
(use-package pungi
:ensure t
:commands pungi:setup-jedi
:init (add-hook #'python-mode-hook
(lambda ()
(when buffer-file-name
#'pungi:setup-jedi))))
(use-package company-jedi
:ensure t
:config (progn
(defun my/enable-company-jedi ()
(when buffer-file-name
(add-to-list 'company-backends 'company-jedi)))
(add-hook #'python-mode-hook
#'my/enable-company-jedi)))
#+end_src
*** Ruby
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package rvm
:ensure t
:commands (rvm-use
rvm-use-default))
#+END_SRC
*** Yaml
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package yaml-mode
:ensure t
:mode "\.yml$")
#+END_SRC
*** Docker
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package dockerfile-mode
:ensure t
:mode "^Dockerfile$")
#+END_SRC
*** Graphviz
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package graphviz-dot-mode
:ensure t
:mode "\.dot$"
:config
(setq graphviz-dot-indent-width 2))
#+END_SRC
*** Gnuplot
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package gnuplot
:ensure t)
#+END_SRC
*** PlantUML
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package plantuml-mode
:ensure t
:mode "\\.plantuml\\'"
:commands plantuml-mode)
#+END_SRC
Don't forget to configure =org-plantuml-jar-path= and
=plantuml-jar-path= to point to a version of plantuml.jar on your
system.
** Tools
*** EditorConfig
Editor-agnostic coding style configuration.
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package editorconfig
:ensure t
:diminish editorconfig-mode
:config
(editorconfig-mode 1))
#+END_SRC
*** Projectile
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package projectile
:ensure t
:defer t
:diminish " 📁"
:config
(projectile-mode t))
(use-package helm-projectile
:ensure t
:after (helm projectile)
:config (helm-projectile-on))
#+END_SRC
*** Autocomplete
**** Company
Install and configure Company for auto-completion.
#+name: autocomplete
#+BEGIN_SRC emacs-lisp
(use-package company
:ensure t
:commands (company-mode)
:config (progn
(add-hook 'prog-mode-hook 'company-mode)
(bind-key "C-n" #'company-select-next company-active-map)
(bind-key "C-p" #'company-select-previous company-active-map)))
#+END_SRC
**** Auto-Complete
Not using this for auto-completion anymore, but several packages
require it.
#+name: autocomplete
#+begin_src emacs-lisp
(use-package auto-complete
:ensure t
:defer t)
#+end_src
*** Flycheck
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package flycheck
:ensure t
:diminish ""
:init
(add-hook 'after-init-hook #'global-flycheck-mode))
#+END_SRC
*** Web Mode
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package web-mode
:ensure t
:mode ("\\.html$" . web-mode)
:config (add-hook 'web-mode-hook (lambda ()
(setq web-mode-markup-indent-offset 4)
(setq web-mode-css-indent-offset 4)
(setq web-mode-code-indent-offset 4))))
#+END_SRC
*** Skewer
Live web development in Emacs.
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package skewer-mode
:ensure t
:commands (run-skewer
skewer-mode
skewer-css-mode
skewer-html-mode)
:init (progn (add-hook 'js2-mode-hook 'skewer-mode)
(add-hook 'css-mode-hook 'skewer-css-mode)
(add-hook 'html-mode-hook 'skewer-html-mode)))
#+END_SRC
*** Yasnippet
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package yasnippet
:ensure t
:defer t
:diminish yas-minor-mode
:config (yas-global-mode 1))
#+END_SRC
*** Ag (The Silver Searcher)
This is a code searching tool that replaces =ack=, and is an order of
magnitude faster.
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package ag
:ensure t
:commands (ag))
#+END_SRC
*** Expand Region
Increase selected region by semantic units.
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package expand-region
:ensure t
:bind (("C-=" . er/expand-region)))
#+END_SRC
*** Nameless
Hide package namespaces in emacs-lisp code.
#+BEGIN_SRC emacs-lisp
(use-package nameless
:ensure t
:commands nameless-mode-from-hook
:init
(add-hook 'emacs-lisp-mode-hook #'nameless-mode-from-hook)
:config
(setq nameless-private-prefix t))
#+END_SRC
** Libraries
*** Dash
A modern list api for Emacs. No 'cl required.
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package dash
:ensure t
:config (dash-enable-font-lock))
#+END_SRC
*** Stream
Lazy sequences in Emacs (compatible with seq.el).
#+name: programming
#+BEGIN_SRC emacs-lisp
(use-package stream
:ensure t
:if (version<= "25.1" emacs-version)
:defer t)
#+END_SRC
* Writing
** Style
*** End sentences with a single space
#+name: packages
#+BEGIN_SRC emacs-lisp
(setq sentence-end-double-space nil)
#+END_SRC
** Formats
*** Org
**** Modules
#+name: org-module-table
| org-habit |
#+name: packages
#+BEGIN_SRC emacs-lisp :noweb yes
(let ((modules (mapcar (lambda (m) (intern (car m)))
'<<org-module-table()>>)))
(mapcar (lambda (m) (add-to-list 'org-modules m))
modules))
(org-load-modules-maybe t)
#+END_SRC
**** Tasks
***** Enforce dependencies
Require child tasks and checkboxes to be done before a parent task can
be marked done.
#+BEGIN_SRC emacs-lisp
(setq
org-enforce-todo-dependencies t
org-enforce-todo-checkbox-dependencies t)
#+END_SRC
***** Keep logs in their own drawer
#+name: packages
#+BEGIN_SRC emacs-lisp
(setq org-log-into-drawer t)
#+END_SRC
***** Log completion
#+name: packages
#+BEGIN_SRC emacs-lisp
(setq org-log-done 'time)
#+END_SRC
***** Habits
Shift the consistency graph over a bit to make room for task
names.
#+name: packages
#+BEGIN_SRC emacs-lisp
(setq org-habit-graph-column 70)
(setq org-habit-show-habits-only-for-today nil)
#+END_SRC
**** Refiling
#+BEGIN_SRC emacs-lisp
(setq org-refile-targets '((org-agenda-files . (:maxlevel . 6))))
#+END_SRC
**** Babel
***** Syntax highlighting
#+name: packages
#+BEGIN_SRC emacs-lisp
(setq-default org-src-fontify-natively t)
#+END_SRC
***** HTTP
#+name: packages
#+begin_src emacs-lisp
(use-package ob-http
:ensure t
:after ob)
#+end_src
***** Language evaluation
Org-babel evaluation will be turned on for the following
languages. Setting ~Confirm Evaluation~ to ~No~ disables the
[[http://orgmode.org/manual/Code-evaluation-security.html][security prompt]] for that language.
#+name: org-babel-languages
| Language | Alias | Confirm Evaluation? | Description |
|--------------+-------+---------------------+---------------------------------|
| emacs-lisp | | Yes | Emacs Lisp |
| graphviz-dot | dot | No | Directed and undirected graphs |
| gnuplot | | No | Graphs |
| ditaa | | No | Ascii diagrams |
| plantuml | | No | Flow charts |
| mscgen | | No | Message sequence charts |
| haskell | | Yes | A pure, functional language |
| python | | Yes | A dynamic, all-purpose language |
| ruby | | Yes | A dynamic, all-purpose language |
| shell | | Yes | Shell scripts |
| http | | No | HTTP requests |
| sql | | No | SQL Queries |
| ledger | | No | Double-Entry Accounting |
#+name: packages
#+BEGIN_SRC emacs-lisp :noweb yes
(defvar my/org-babel-evaluated-languages ())
(defvar my/org-src-lang-modes ())
(defvar my/org-babel-no-confirm-languages ())
(defun my/org-confirm-babel-evaluate (lang body)
(not (member (intern lang) my/org-babel-no-confirm-languages)))
(let ((language-table (cddr '<<org-babel-languages()>>)))
(mapcar (lambda (lang-pair)
(let* ((alias (if (not (string= (cadr lang-pair) "")) (cadr lang-pair)))
(lang (intern (car lang-pair)))
(lang-or-alias (if alias (intern alias) lang))
(confirm (not (string= (cl-caddr lang-pair) "No"))))
(if alias
(add-to-list 'my/org-src-lang-modes (cons alias lang)))
(if (not confirm)
(add-to-list 'my/org-babel-no-confirm-languages lang-or-alias))
(add-to-list 'my/org-babel-evaluated-languages lang-or-alias)
lang-or-alias))
language-table))
(mapcar (lambda (alias)
(add-to-list 'org-src-lang-modes alias))
my/org-src-lang-modes)
(org-babel-do-load-languages
'org-babel-load-languages
(mapcar (lambda (lang)
(cons lang t))
my/org-babel-evaluated-languages))
(setq org-confirm-babel-evaluate 'my/org-confirm-babel-evaluate)
#+END_SRC
***** Reload images on source execution
#+name: packages
#+begin_src emacs-lisp
(defun my/redisplay-org-images ()
(when org-inline-image-overlays
(org-redisplay-inline-images)))
(add-hook 'org-babel-after-execute-hook
'my/redisplay-org-images)
#+end_src
**** Wrap text in blocks
A useful snippet for marking a region and wrapping it in an org block.
Taken from [[http://pragmaticemacs.com/emacs/wrap-text-in-an-org-mode-block/][Pragmatic Emacs]]
#+name: packages
#+BEGIN_SRC emacs-lisp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; function to wrap blocks of text in org templates ;;
;; e.g. latex or src etc ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun org-begin-template ()
"Make a template at point."
(interactive)
(if (org-at-table-p)
(call-interactively 'org-table-rotate-recalc-marks)
(let* ((choices '(("s" . "SRC")
("e" . "EXAMPLE")
("q" . "QUOTE")
("v" . "VERSE")
("c" . "CENTER")
("l" . "LaTeX")
("h" . "HTML")
("a" . "ASCII")))
(key
(key-description
(vector
(read-key
(concat (propertize "Template type: " 'face 'minibuffer-prompt)
(mapconcat (lambda (choice)
(concat (propertize (car choice) 'face 'font-lock-type-face)
": "
(cdr choice)))
choices
", ")))))))
(let ((result (assoc key choices)))
(when result
(let ((choice (cdr result)))
(cond
((region-active-p)
(let ((start (region-beginning))
(end (region-end)))
(goto-char end)
(insert "#+END_" choice "\n")
(goto-char start)
(insert "#+BEGIN_" choice "\n")))
(t
(insert "#+BEGIN_" choice "\n")
(save-excursion (insert "#+END_" choice))))))))))
;;bind to key
(define-key org-mode-map (kbd "C-<") 'org-begin-template)
#+END_SRC
**** Complete keywords with Company
Taken from https://emacs.stackexchange.com/a/30691.
#+name: packages
#+BEGIN_SRC emacs-lisp
(defun org-keyword-backend (command &optional arg &rest ignored)
(interactive (list 'interactive))
(cl-case command
(interactive (company-begin-backend 'org-keyword-backend))
(prefix (and (eq major-mode 'org-mode)
(cons (company-grab-line "^#\\+\\(\\w*\\)" 1)
t)))
(candidates (mapcar #'upcase
(cl-remove-if-not
(lambda (c) (string-prefix-p arg c))
(pcomplete-completions))))
(ignore-case t)
(duplicates t)))
(eval-after-load 'company
'(add-to-list 'company-backends 'org-keyword-backend))
(add-hook 'org-mode-hook 'company-mode)
#+END_SRC
**** Exporting
***** LaTeX
#+name: packages
#+BEGIN_SRC emacs-lisp :noweb yes
(use-package ox-latex
:defer t
:config
<<configure-ox-latex>>)
#+END_SRC
****** Document classes
Add org latex class definitions for some popular LaTeX classes,
including:
- [[HTTPS://ctan.org/pkg/koma-script?lang=en][KOMA-Script]]
- [[https://ctan.org/pkg/memoir?lang=en][Memoir]]
- [[https://ctan.org/pkg/hitec?lang=en][Hitec]]
- [[https://ctan.org/pkg/tufte-latex?lang=en][Tufte]]
- [[https://ctan.org/pkg/labbook?lang=en][Labbook]] (based on KOMA-Script)
#+name: configure-ox-latex
#+BEGIN_SRC emacs-lisp
(seq-map (apply-partially #'add-to-list 'org-latex-classes)
'(("koma-letter"
"\\documentclass{scrlttr2}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("koma-article"
"\\documentclass{scrartcl}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("koma-book"
"\\documentclass{scrbook}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("koma-book-chapters"
"\\documentclass{scrbook}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("koma-report"
"\\documentclass{scrreprt}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("memoir"
"\\documentclass{memoir}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("hitec"
"\\documentclass{hitec}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("paper"
"\\documentclass{paper}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("letter"
"\\documentclass{letter}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("tufte-handout"
"\\documentclass{tufte-handout}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("tufte-book"
"\\documentclass{tufte-book}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("tufte-book-chapters"
"\\documentclass{tufte-book}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
("labbook"
"\\documentclass{labbook}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\labday{%s}")
("\\subsubsection{%s}" . "\\experiment{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
#+END_SRC
****** Source Highlighting
Configure org-mode LaTeX export to use minted for syntax highlighting.
Some languages / markups I use aren't supported by minted, so I map
them here so they don't fail.
#+name: ox-latex-minted-mappings
#+CAPTION: Minted language mappings
| Language | Mapping |
|----------+--------------|
| dot | text |
| org | text |
| ditaa | text |
| plantuml | text |
| csv | text |
| conf | linux-config |
#+name: configure-ox-latex
#+BEGIN_SRC emacs-lisp :noweb yes
(setq org-latex-listings 'minted)
(setq org-latex-minted-options
'(("fontsize" "\\scriptsize")))
(seq-map (lambda (mapping)
(add-to-list 'org-latex-minted-langs
(cons (intern (car mapping)) (cdr mapping))))
(seq-drop '<<ox-latex-minted-mappings()>> 2))
(add-to-list 'org-latex-packages-alist
'("" "minted" nil))
#+END_SRC
****** TeX Engine
Prepare the LaTeX export process, and default the compiler to xelatex,
as it has better unicode support than pdflatex.
#+BEGIN_NOTES
The =%latex= expansion variable is used so that org documents can
override the latex compiler using the file-level =LATEX_COMPILER=
directive.
#+END_NOTES
#+name: configure-ox-latex
#+BEGIN_SRC emacs-lisp
(setq org-latex-pdf-process
(-repeat 3 "%latex -shell-escape -interaction nonstopmode -output-directory %o %f"))
;; Default to XeLaTeX
(setq org-latex-compiler "xelatex")
#+END_SRC
*** LaTeX
**** AUCTeX
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package tex-site
:ensure auctex
:mode ("\\.tex$" . TeX-latex-mode))
#+END_SRC
**** LaTeX-Extra
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package latex-extra
:ensure t
:diminish latex-extra-mode
:commands latex-extra-mode
:init (add-hook 'LaTeX-mode-hook #'latex-extra-mode))
#+END_SRC
*** Markdown
#+name: packages
#+begin_src emacs-lisp
(use-package markdown-mode
:ensure t
:mode "\\.md$")
#+end_src
** Tools
*** Flyspell
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package flyspell
:ensure t
:commands flyspell-mode
:diminish flyspell-mode
:init (mapcar (lambda (mode-hook)
(add-to-list mode-hook #'flyspell-mode))
'(text-mode-hook
org-mode-hook)))
#+END_SRC
*** Auto-Fill
Automatically wrap paragraphs while writing in text modes.
#+name: packages
#+BEGIN_SRC emacs-lisp
(mapcar (lambda (mode-hook)
(add-hook mode-hook #'auto-fill-mode))
'(text-mode-hook
org-mode-hook))
#+END_SRC
*** Unfill
Re-flowing paragraphs with =fill-paragraph= is nice, but there are
occasions when it's useful to do the inverse, and get rid of the line
breaks.
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package unfill
:ensure t
:commands (unfill-paragraph
unfill-region)
:bind ("M-Q" . unfill-paragraph))
#+END_SRC
*** Writegood
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package writegood-mode
:ensure t
:commands writegood-mode
:diminish writegood-mode
:init (mapcar (lambda (mode-hook)
(add-hook mode-hook #'writegood-mode))
'(text-mode-hook
org-mode-hook)))
#+END_SRC
* Finances
** Ledger
Command-line double-entry accounting system.
https://www.ledger-cli.org/
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package ledger-mode
:ensure t
:mode "\\.ledger$")
#+END_SRC
* Mail
** Gnus
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package gnus
:commands gnus
:init (progn (defun my/configure-gnus ()
<<gnus>>
)
(setq gnus-before-startup-hook 'my/configure-gnus)))
#+END_SRC
*** Avoid rich-text messages
#+name: gnus
#+BEGIN_SRC emacs-lisp
(setq mm-discouraged-alternatives '("text/html" "text/richtext"))
#+END_SRC
*** Summary view formatting
Taken from http://groups.google.com/group/gnu.emacs.gnus/browse_thread/thread/a673a74356e7141f
#+name: gnus
#+BEGIN_SRC emacs-lisp
(when window-system
(setq gnus-sum-thread-tree-indent " ")
(setq gnus-sum-thread-tree-root "") ;; "● ")
(setq gnus-sum-thread-tree-false-root "") ;; "◯ ")
(setq gnus-sum-thread-tree-single-indent "") ;; "◎ ")
(setq gnus-sum-thread-tree-vertical "│")
(setq gnus-sum-thread-tree-leaf-with-other "├─► ")
(setq gnus-sum-thread-tree-single-leaf "╰─► "))
(setq gnus-summary-line-format
(concat
"%0{%U%R%z%}"
"%3{│%}" "%1{%d%}" "%3{│%}" ;; date
" "
"%4{%-20,20f%}" ;; name
" "
"%3{│%}"
" "
"%1{%B%}"
"%s\n"))
(setq gnus-summary-display-arrow t)
#+END_SRC
*** Inline images
#+name: gnus
#+BEGIN_SRC emacs-lisp
(require 'mm-decode)
(add-to-list 'mm-attachment-override-types "image/.*")
(setq mm-inline-large-images t)
#+END_SRC
* Publishing
** Htmlize
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package htmlize
:ensure t
:commands (htmlize-region htmlize-buffer htmlize-file))
#+END_SRC
* Source Control
** Git-Gutter
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package git-gutter
:ensure t
:diminish git-gutter-mode
:bind (("C-x g n" . git-gutter:next-hunk)
("C-x g p" . git-gutter:previous-hunk))
:defer 1
:config
(progn
(global-git-gutter-mode t)
(defadvice ediff-make-temp-file (before make-temp-file-suspend-ll
activate compile preactivate)
"Disable git-gutter when running ediff"
(global-git-gutter-mode 0))
(add-hook 'ediff-cleanup-hook
'(lambda ()
(global-git-gutter-mode t)))))
#+END_SRC
** Magit
#+name: packages
#+BEGIN_SRC emacs-lisp
(use-package magit
:ensure t
:commands (magit-init
magit-status
magit-diff
magit-commit)
:bind (("C-c m s" . magit-status)
("C-c m d" . magit-diff)
("C-c m c" . magit-commit)
("C-c m l l" . magit-log-head)
("C-c m l b" . magit-log-buffer-file)
("C-c m l r" . magit-reflog-head))
:config
(progn
(defadvice magit-status (around magit-fullscreen activate)
(window-configuration-to-register :magit-fullscreen)
ad-do-it
(delete-other-windows))
(defadvice magit-quit-window (around magit-restore-screen activate)
ad-do-it
(jump-to-register :magit-fullscreen))))
(use-package magit-blame
:ensure magit
:commands magit-blame-mode
:bind ("C-c m b" . magit-blame))
#+END_SRC
* Other functionality
** Disable tab indenting by default
#+name: other
#+BEGIN_SRC emacs-lisp
(setq-default indent-tabs-mode nil)
#+END_SRC
** Rename file and buffer
Taken from [[http://emacsredux.com/blog/2013/05/04/rename-file-and-buffer/][Emacs Redux]]
#+name: other
#+BEGIN_SRC emacs-lisp
;; emacsredux.com
(defun rename-file-and-buffer ()
"Rename the current buffer and file it is visiting."
(interactive)
(let ((filename (buffer-file-name)))
(if (not (and filename (file-exists-p filename)))
(message "Buffer is not visiting a file!")
(let ((new-name (read-file-name "New name: " filename)))
(cond
((vc-backend filename) (vc-rename-file filename new-name))
(t
(rename-file filename new-name t)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil)))))))
#+END_SRC
** Eval and Replace
Taken from [[http://emacsredux.com/blog/2013/06/21/eval-and-replace/][Emacs Redux]]
#+name: other
#+BEGIN_SRC emacs-lisp
(defun eval-and-replace ()
"Replace the preceding sexp with its value."
(interactive)
(backward-kill-sexp)
(condition-case nil
(prin1 (eval (read (current-kill 0)))
(current-buffer))
(error (message "Invalid expression")
(insert (current-kill 0)))))
(global-set-key (kbd "C-)") 'eval-and-replace)
#+END_SRC
** Smarter navigation to the beginning of a line
Taken from [[http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/][Emacs Redux]]
#+name: other
#+BEGIN_SRC emacs-lisp
(defun smarter-move-beginning-of-line (arg)
"Move point back to indentation of beginning of line.
Move point to the first non-whitespace character on this line.
If point is already there, move to the beginning of the line.
Effectively toggle between the first non-whitespace character and
the beginning of the line.
If ARG is not nil or 1, move forward ARG - 1 lines first. If
point reaches the beginning or end of the buffer, stop there."
(interactive "^p")
(setq arg (or arg 1))
;; Move lines first
(when (/= arg 1)
(let ((line-move-visual nil))
(forward-line (1- arg))))
(let ((orig-point (point)))
(back-to-indentation)
(when (= orig-point (point))
(move-beginning-of-line 1))))
;; remap C-a to `smarter-move-beginning-of-line'
(global-set-key [remap move-beginning-of-line]
'smarter-move-beginning-of-line)
#+END_SRC
** Edit file with sudo
Taken from [[http://www.emacswiki.org/TrampMode#toc32][EmacsWiki]]
#+name: other
#+BEGIN_SRC emacs-lisp
(require 'dired)
(defun sudo-edit-current-file ()
(interactive)
(let ((my-file-name) ; fill this with the file to open
(position)) ; if the file is already open save position
(if (equal major-mode 'dired-mode) ; test if we are in dired-mode
(progn
(setq my-file-name (dired-get-file-for-visit))
(find-alternate-file (prepare-tramp-sudo-string my-file-name)))
(setq my-file-name (buffer-file-name); hopefully anything else is an already opened file
position (point))
(find-alternate-file (prepare-tramp-sudo-string my-file-name))
(goto-char position))))
(defun prepare-tramp-sudo-string (tempfile)
(if (file-remote-p tempfile)
(let ((vec (tramp-dissect-file-name tempfile)))
(tramp-make-tramp-file-name
"sudo"
(tramp-file-name-user nil)
(tramp-file-name-host vec)
(tramp-file-name-localname vec)
(format "ssh:%s@%s|"
(tramp-file-name-user vec)
(tramp-file-name-host vec))))
(concat "/sudo:root@localhost:" tempfile)))
(define-key dired-mode-map [s-return] 'sudo-edit-current-file)
#+END_SRC
** Backups
Borrowed from Sacha Chua
https://github.com/sachac/.emacs.d/
This is one of the things people usually want to change right away. By default, Emacs saves backup files in the current directory. These are the files ending in =~= that are cluttering up your directory lists. The following code stashes them all in =~/.emacs.d/backups=, where I can find them with =C-x C-f= (=find-file=) if I really need to.
#+name: other
#+begin_src emacs-lisp
(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
#+end_src
Disk space is cheap. Save lots.
#+name: other
#+begin_src emacs-lisp
(setq delete-old-versions -1)
(setq version-control t)
(setq vc-make-backup-files t)
(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))
#+end_src
** Disable lock files
Lock files have only ever gotten in my way.
#+name: other
#+BEGIN_SRC emacs-lisp
(setq create-lockfiles nil)
#+END_SRC
** History
From http://www.wisdomandwonder.com/wordpress/wp-content/uploads/2014/03/C3F.html
#+name: other
#+begin_src emacs-lisp
(setq savehist-file "~/.emacs.d/savehist")
(savehist-mode 1)
(setq history-length t)
(setq history-delete-duplicates t)
(setq savehist-save-minibuffer-history 1)
(setq savehist-additional-variables
'(kill-ring
search-ring
regexp-search-ring))
#+end_src
** Copy filename to clipboard
http://emacsredux.com/blog/2013/03/27/copy-filename-to-the-clipboard/
https://github.com/bbatsov/prelude
#+name: other
#+begin_src emacs-lisp
(defun prelude-copy-file-name-to-clipboard ()
"Copy the current buffer file name to the clipboard."
(interactive)
(let ((filename (if (equal major-mode 'dired-mode)
default-directory
(buffer-file-name))))
(when filename
(kill-new filename)
(message "Copied buffer file name '%s' to the clipboard." filename))))
#+end_src
** Prompt for 'y or n' instead of 'yes or no'
Because typing out "yes" and "no" is irritating.
#+name: other
#+BEGIN_SRC emacs-lisp
(defalias 'yes-or-no-p #'y-or-n-p)
#+END_SRC
** Support ANSI colors in compilation buffers
http://stackoverflow.com/a/13408008
#+name: other
#+BEGIN_SRC emacs-lisp
(require 'ansi-color)
(defun colorize-compilation-buffer ()
(toggle-read-only)
(ansi-color-apply-on-region compilation-filter-start (point))
(toggle-read-only))
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)
#+END_SRC
** Re-bind modifiers on OSX
On mac keyboards, the command key placement works better for me as
Meta rather than the default (Super), because it's right where my
muscle memory expects a PC keyboard's Alt key.
The control keys are typically pretty terrible, too, but I find it
easier to rebind Caps Lock to Control in the system preferences (which
is a nice thing to do in other environments, as well).
#+name: other
#+BEGIN_SRC emacs-lisp
(when (equal 'darwin system-type)
;; Command as meta, because alt/option's placement is terrible on
;; mac keyboards (this doesn't interfere with Spotlight's ⌘-Space
;; binding)
(setq ns-command-modifier 'meta))
#+END_SRC
* Custom settings
Store options set via =customize-*= in a separate file (Emacs stores
them in =init.el= by default).
#+name: custom-settings
#+BEGIN_SRC emacs-lisp
(setq custom-file "~/.emacs.d/custom.el")
(if (file-exists-p custom-file)
(load custom-file))
#+END_SRC
* Auto-loading elisp files
Any elisp files dropped into =~/.emacs.local.d/= will be
automatically loaded.
I usually use this is a testing ground for new configuration before
adding it here, and also for any personal / sensitive configuration.
#+name: auto-load
#+BEGIN_SRC emacs-lisp
(defun my/load-elisp-directory (path)
(let ((file-pattern "\\.elc?$"))
(when (file-directory-p path)
(mapcar (lambda (lisp-file)
(load-file lisp-file))
(directory-files (expand-file-name path) t file-pattern)))))
(my/load-elisp-directory "~/.emacs.local.d")
#+END_SRC
* Configuration file layout
Here I define the emacs.el file that gets generated by the code in
this org file.
#+BEGIN_SRC emacs-lisp :tangle yes :noweb no-export :exports code
;;;; Do not modify this file by hand. It was automatically generated
;;;; from `emacs.org` in the same directory. See that file for more
;;;; information.
;;;;
<<startup>>
<<look-and-feel>>
<<packages>>
<<programming>>
<<autocomplete>>
<<other>>
<<auto-load>>
<<custom-settings>>
#+END_SRC