#+TITLE: Making Emacs Work For Me #+AUTHOR: Joost Diepenmaat #+EMAIL: joost@zeekat.nl * Configuring Emacs: A Yak Shaving Diary This is my ∞th attempt at creating a readable and maintainable Emacs configuration. I'm hopeful that using Org-Babel and a literate programming style will help tame the bit-rot and spaghettification. * How to use my configuration ** Obtaining the source You can find the latest public version of the configuration in [[https://github.com/joodie/emacs-literal-config/][the Github repository]]. The meat of it (and the source of this document) is the ~emacs.org~ file. ** Installation This configuration is intended to auto-install from scratch. ** Installation procedure - Install GNU Emacs 24 or higher - Clone [[https://github.com/joodie/emacs-literal-config][the repository]] as ~$HOME/.emacs.d~ (or symlink it to that directory). - Start Emacs * Graphics and looks ** Color theme Leuven theme is awesome! Except for the font sizes. #+name: look-and-feel #+BEGIN_SRC emacs-lisp (defun single-font-size () "Reset all faces to the height of the default face." (dolist (f (face-list)) (when (not (equal 'default f)) (set-face-attribute f nil :height 1.0)))) (load-theme 'tango-dark t) (add-hook 'after-init-hook 'single-font-size) #+END_SRC ** Font # I like [[http://www.levien.com/type/myfonts/inconsolata.html][Inconsolata]], but it doesn't support a wide range of Unicode # characters, so I fall back on [[http://dejavu-fonts.org/wiki/Main_Page][DejaVu Sans]] for those. #+name: look-and-feel #+BEGIN_SRC emacs-lisp (set-face-attribute 'default nil :family "Inconsolata" :height 150 :weight 'normal :width 'normal) (when (functionp 'set-fontset-font) (set-fontset-font "fontset-default" 'unicode (font-spec :family "DejaVu Sans Mono" :width 'normal :size 15.5 :weight 'normal))) #+END_SRC ** Reduce clutter Remove the toolbar. It's ugly and I never use it. Also remove the scroll bars; below, I set up the fringe to show my position in a buffer. #+name: look-and-feel #+BEGIN_SRC emacs-lisp (when (window-system) (tool-bar-mode -1) (scroll-bar-mode -1)) #+END_SRC When running emacs in a terminal, remove the menu bar. #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (when (not (window-system)) (menu-bar-mode -1)) #+END_SRC ** Fringe decorations [[http://www.emacswiki.org/emacs/TheFringe][The fringe]] is the vertical region at the right and left of the buffer. Emacs lets you customize it of course. Here I set up git diffs and buffer position in the fringe. #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (when (window-system) (require 'git-gutter-fringe)) (global-git-gutter-mode +1) (setq-default indicate-buffer-boundaries 'left) (setq-default indicate-empty-lines +1) #+END_SRC ** Mode line I'm using smart mode line to clean up the modeline display a little. #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (sml/setup) (sml/apply-theme 'dark) (setq sml/shorten-directory t) (setq sml/shorten-modes t) (nyan-mode +1) (setq nyan-wavy-trail nil) (setq nyan-animate-nyancat t) #+END_SRC I like to see the current time. #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (setq display-time-24hr-format t) (display-time-mode +1) #+END_SRC There's a lot of modes that I don't need to see. #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (require 'eldoc) (add-to-list 'after-init-hook (lambda () (dolist (m '(projectile company git-gutter eldoc paredit)) (diminish (my/->mode m) "")))) #+END_SRC ** Scrolling behavior Emacs's default scrolling behavior, like a lot of the default Emacs experience, is pretty idiosyncratic. The following snippet makes for a smoother scrolling behavior when using keyboard navigation. #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (setq redisplay-dont-pause t scroll-margin 1 scroll-step 1 scroll-conservatively 10000 scroll-preserve-screen-position 1) #+END_SRC This snippet makes mouse wheel and trackpad scrolling bearable. Scroll in 1-line increments the buffer under the mouse. #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (setq mouse-wheel-follow-mouse 't) (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) #+END_SRC ** Buffer names Setup uniquify so that non-unique buffer names get the parent path included to make them unique. #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (require 'uniquify) (setq uniquify-buffer-name-style 'forward) #+END_SRC ** Window systems and terminals. Emacs runs very fine in a terminal as is, but there are a few tweaks that make terminal usage even nicer. *** Make mouse clicks work in xterm (and iTerm). #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (when (not (window-system)) (xterm-mouse-mode +1)) #+END_SRC ** Prefer single frames #+NAME: look-and-feel #+BEGIN_SRC emacs-lisp (setq ediff-window-setup-function 'ediff-setup-windows-plain) #+END_SRC * Start up Start with an empty scratch buffer in org mode; no start up screen. #+NAME: startup #+BEGIN_SRC emacs-lisp (setq inhibit-startup-screen +1) (setq initial-major-mode 'org-mode) (setq initial-scratch-message nil) #+END_SRC #+NAME: startup #+BEGIN_SRC emacs-lisp (toggle-frame-maximized) #+END_SRC * Formatting and white-space #+name: formatting #+BEGIN_SRC emacs-lisp (setq-default indent-tabs-mode nil) (defun my/clean-buffer-formatting () "Indent and clean up the buffer" (interactive) (indent-region (point-min) (point-max)) (whitespace-cleanup)) (global-set-key "\C-cn" 'my/clean-buffer-formatting) ;; by default, ;; highlight trailing whitespace (defun my/general-formatting-hooks () (setq show-trailing-whitespace 't)) (dolist (mode-hook (my/normal-mode-hooks)) (add-hook mode-hook 'my/general-formatting-hooks)) (defun fixup-json () "Re-indent json buffers with broken literal strings. Needs jsonpp installed (available using homebrew)" (interactive) (shell-command-on-region (point-min) (point-max) "sed -e ':a' -e 'N' -e '$!ba' -e 's/\\n/ /g'|jsonpp" nil t)) #+END_SRC ** Text (non-code) formatting For writing text, I prefer Emacs to do line wrapping for me. Also, superfluous white-space should be shown. #+name: formatting #+BEGIN_SRC emacs-lisp (defun my/text-formatting-hooks () (my/turn-on 'auto-fill)) ; turn on automatic hard line wraps (add-hook 'text-mode-hook 'my/text-formatting-hooks) #+END_SRC * Programming ** Spelling I use flyspell-prog-mode to check strings and comments in source code. #+name: programming-setup #+BEGIN_SRC emacs-lisp (defun my/general-prog-hooks () (flyspell-prog-mode)) ;; cannot use my/turn-on to turn it on because ;; this function does not take an argument (add-hook 'prog-mode-hook 'my/general-prog-hooks) #+END_SRC #+name: programming-setup #+BEGIN_SRC emacs-lisp ;; Cycle between snake case, camel case, etc. (require 'string-inflection) (global-set-key (kbd "C-c i") 'string-inflection-all-cycle) #+END_SRC ** Pair programming Normally, I think line numbers in code editors just take up space, but they can be useful when pair programming; calling out a line number is probably more efficient than pointing at the screen. I wrapped this in a global minor mode so turning that stuff on and off is easy. #+name: programming-setup #+BEGIN_SRC emacs-lisp (define-minor-mode my/pair-programming-mode "Toggle visualizations for pair programming. Interactively with no argument, this command toggles the mode. A positive prefix argument enables the mode, any other prefix argument disables it. From Lisp, argument omitted or nil enables the mode, `toggle' toggles the state. This turns on hightlighting the current line, line numbers and command-log-mode." ;; The initial value. nil ;; The indicator for the mode line. " Pairing" ;; The minor mode bindings. '() :group 'my/pairing (my/set-modes (if my/pair-programming-mode 1 -1) '(linum hl-line command-log))) (define-global-minor-mode my/global-pair-programming-mode my/pair-programming-mode (lambda () (my/pair-programming-mode 1))) (global-set-key "\C-c\M-p" 'my/global-pair-programming-mode) #+END_SRC ** Lisps For lisp code, I want ParEdit plus general highlighting etc. I'm testing parinfer-mode at the moment instead though. #+NAME: programming-setup #+BEGIN_SRC emacs-lisp (setq my/lisps '(emacs-lisp lisp clojure)) ;; Install local bindings for paredit that work under ssh/terminal (require 'paredit) (require 'parinfer-mode) (define-key paredit-mode-map (kbd "C-c s ") 'paredit-forward-slurp-sexp) (define-key paredit-mode-map (kbd "C-c s ") 'paredit-forward-barf-sexp) (require 'literal-string) (defun my/general-lisp-hooks () (my/turn-on 'paredit 'rainbow-delimiters 'show-paren 'literal-string)) (dolist (mode (mapcar 'my/->mode-hook my/lisps)) (add-hook mode 'my/general-lisp-hooks)) (setq show-paren-style 'expression) #+END_SRC ** Emacs Lisp #+NAME: programming-setup #+BEGIN_SRC emacs-lisp (defun my/emacs-lisp-hooks () (my/turn-on 'eldoc-mode)) (add-hook 'emacs-lisp-mode-hook 'my/emacs-lisp-hooks) #+END_SRC ** Clojure I'm using [[https://github.com/clojure-emacs/cider/commits/master][CIDER]] (formerly ~nrepl.el~) for clojure source/repl interaction. #+NAME: programming-setup #+BEGIN_SRC emacs-lisp (defun my/cider-mode-hooks () "Clojure specific setup code that should only be run when we have a CIDER REPL connection" (my/turn-on 'eldoc)) (add-hook 'cider-mode-hook 'my/cider-mode-hooks) (setq cider-repl-history-file (expand-file-name "~/.emacs.d/.cider-repl-history")) #+END_SRC Clojure-specific enhancements to lisp config. #+NAME: programming-setup #+BEGIN_SRC emacs-lisp (defun my/clojure-mode-hooks () (my/turn-on 'subword) (my/turn-on 'yas-minor) (my/turn-on 'flycheck) (my/turn-on 'clj-refactor) (cljr-add-keybindings-with-prefix "C-c r") (sayid-setup-package)) (setq clojure-align-forms-automatically t) (add-hook 'clojure-mode-hook 'my/clojure-mode-hooks) #+END_SRC I treat the REPL mode specially, since certain hooks that work in ~clojure-mode~ won't make sense or break functionality in ~cider-repl-mode~. #+NAME: programming-setup #+BEGIN_SRC emacs-lisp (defun my/cider-repl-mode-hooks () (my/turn-on 'paredit 'rainbow-delimiters 'show-paren 'subword)) (add-hook 'cider-repl-mode-hook 'my/cider-repl-mode-hooks) #+END_SRC I'm trying out joker for flycheck clojure linting #+NAME: programming-setup #+BEGIN_SRC emacs-lisp (require 'flycheck-joker) (with-eval-after-load 'flycheck (flycheck-pos-tip-mode)) #+END_SRC ** Ruby Tell Emacs rake files are Ruby files. #+name: programming-setup #+BEGIN_SRC emacs-lisp (dolist (exp '("Rakefile\\'" "\\.rake\\'")) (add-to-list 'auto-mode-alist (cons exp 'ruby-mode))) #+END_SRC Since I'm using Ruby mostly for Rails projects, erb support is nice. #+NAME: programming-setup #+BEGIN_SRC emacs-lisp (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode)) (setq web-mode-engines-alist '(("erb" . "\\.erb\\'"))) (defun my/web-mode-hook () (setq web-mode-markup-indent-offset 2) (setq web-mode-code-indent-offset 2)) (add-hook 'web-mode-hook 'my/web-mode-hook) #+END_SRC ** Perl I still occasionally need to work on Perl code, so I have a few basic settings to make that reasonably painless. #+name: programming-setup #+BEGIN_SRC emacs-lisp (fset 'perl-mode 'cperl-mode) ;; force cperl mode (defun my/cperl-mode-hooks () (my/turn-on 'flycheck)) (add-hook 'cperl-mode-hook 'my/cperl-mode-hooks) #+END_SRC ** Javascript I use RJSX-mode for javascript source. #+name: programming-setup #+BEGIN_SRC emacs-lisp (add-to-list 'auto-mode-alist '("\\.js[x]?\\'" . rjsx-mode)) #+END_SRC ** JSON For JSON-formatted files, I use the default js-mode, which accepts top-level bare objects (which is incorrect behaviour for javascript, but the default in JSON). #+name: programming-setup #+BEGIN_SRC emacs-lisp (add-to-list 'auto-mode-alist '("\\.json\\'\\|\\.json\\.template\\'\\|\\.jshintrc\\'" . js-mode)) ; (setq js-indent-level 2) #+END_SRC ** CSS #+name: programming-setup #+BEGIN_SRC emacs-lisp (add-hook 'css-mode-hook 'rainbow-mode) #+END_SRC ** ASCIIDOC #+name: programming-setup #+BEGIN_SRC emacs-lisp (add-to-list 'auto-mode-alist '("\\.adoc\\'" . adoc-mode)) #+END_SRC ** Compilation mode improvements *** ANSI Colors See http://stackoverflow.com/questions/3072648/cucumbers-ansi-colors-messing-up-emacs-compilation-buffer #+name: programming-setup #+BEGIN_SRC emacs-lisp (require 'ansi-color) (defun colorize-compilation-buffer () (toggle-read-only) (ansi-color-apply-on-region (point-min) (point-max)) (toggle-read-only)) (add-hook 'compilation-filter-hook 'colorize-compilation-buffer) (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on) (add-to-list 'comint-output-filter-functions 'ansi-color-process-output) ;(add-hook 'eshell-preoutput-filter-functions 'ansi-color-filter-apply) (add-hook 'eshell-preoutput-filter-functions 'ansi-color-apply) #+END_SRC *** Follow output #+name: programming-setup #+BEGIN_SRC emacs-lisp (setq compilation-scroll-output t) #+END_SRC * Database client Don't wrap lines (query rows) when working with a database. #+NAME: databases #+BEGIN_SRC emacs-lisp (add-hook 'sql-interactive-mode-hook (lambda () (toggle-truncate-lines t))) #+END_SRC Fix SQLi prompt for postgres when there are underscores in the database name #+NAME: databases #+BEGIN_SRC emacs-lisp (sql-set-product-feature 'postgres :prompt-regexp "^[a-zA-Z_]*=[#>] ") #+END_SRC * Dired #+name: dired Make dired-move and friends default to "other dired window" if there is one. #+BEGIN_SRC emacs-lisp (setq dired-dwim-target t) #+END_SRC * TODO Auto Complete Getting auto completion to work right tends to be a messy process of trial and error, though in recent years the situation has improved, with =auto-complete= mode being more or less the defacto standard. - Fuzzy matching isn't working the way I expected, though. Need to work on that. #+NAME: auto-complete #+BEGIN_SRC emacs-lisp ;; (require 'fuzzy) ;; (require 'auto-complete) ;; (setq ac-auto-show-menu t ;; ac-quick-help-delay 0.5 ;; ac-use-fuzzy t) ;; (global-auto-complete-mode +1) #+END_SRC Company mode seems to be better supported by CIDER, so let's try that for now. #+NAME: auto-complete #+BEGIN_SRC emacs-lisp (require 'company) (add-hook 'after-init-hook 'global-company-mode) (add-hook 'cider-repl-mode-hook #'company-mode) (add-hook 'cider-mode-hook #'company-mode) (global-set-key (kbd "TAB") #'company-indent-or-complete-common) #+END_SRC * Global key bindings As far as reasonable, I try to keep my custom key bindings within the "official" restraints. Specifically, I want my global key bindings to start with =C-c [lower case letter]=. #+name: global-keys #+BEGIN_SRC emacs-lisp (global-set-key "\C-cg" 'magit-status) (global-set-key "\C-cq" 'delete-indentation) (global-set-key (kbd "C-=") 'er/expand-region) (global-set-key "\C-s" 'isearch-forward-regexp) #+END_SRC I also unmap the right Alt (Meta) key so that I can use standard OSX key binding for € and °, and similar. Also, disable CTRL-z since it sucks #+name: global-keys #+BEGIN_SRC emacs-lisp (when (boundp 'ns-right-alternate-modifier) (setq ns-right-alternate-modifier nil)) (global-unset-key [(control z)]) (global-unset-key [(control x)(control z)]) #+END_SRC `which-key` mode will show available followup-keys when typing long key bindings: #+name: global-keys #+BEGIN_SRC emacs-lisp (my/turn-on 'which-key) #+END_SRC * Magit When tracking a branch from a remote, use the same name. #+name: programming-setup #+BEGIN_SRC emacs-lisp (setq magit-default-tracking-name-function #'magit-default-tracking-name-branch-only) (setq magit-last-seen-setup-instructions "1.4.0") #+END_SRC * Global navigation I like ~ido~ and ~smex~ for narrowing down files, commands, buffers etc. #+name: global-navigation #+BEGIN_SRC emacs-lisp (defun my/edit-emacs-configuration () (interactive) (find-file "~/.emacs.d/emacs.org")) (global-set-key "\C-ce" 'my/edit-emacs-configuration) (setq ido-enable-flex-matching t) (ido-mode +1) (ido-ubiquitous-mode +1) (require 'ido-yes-or-no) (ido-yes-or-no-mode +1) (global-set-key "\M-x" 'smex) (global-set-key "\C-cw" 'pass) #+END_SRC ** Projects Projectile is useful. Especially, ~projectile-replace~ and ~projectile-find-file~. Projectile commands are bound with the default ~C-c p~ prefix. So I can type ~C-c p C-h~ to list all of them. #+name: global-navigation #+BEGIN_SRC emacs-lisp (projectile-global-mode +1) (require 'projectile-direnv) (add-hook 'projectile-mode-hook 'projectile-direnv-export-variables) #+END_SRC * Backup configuration Store backup files in the system temp directory so I don't leave *~ files everywhere. #+NAME backup-config #+BEGIN_SRC emacs-lisp (setq backup-directory-alist `((".*" . ,temporary-file-directory))) #+END_SRC * Org Mode ** Global keys Short key bindings for capturing notes/links and switching to agenda. #+name: org-config #+BEGIN_SRC emacs-lisp (global-set-key "\C-cl" 'org-store-link) (global-set-key "\C-cc" 'org-capture) (global-set-key "\C-ca" 'org-agenda) (global-set-key "\C-cb" 'org-iswitchb) #+END_SRC Org-Agenda needs to be loaded before calling =org-agenda= works. #+name: org-config #+BEGIN_SRC emacs-lisp (require 'org-agenda) #+END_SRC I prefer a forthnight's overview on the agenda. #+name: org-config #+BEGIN_SRC emacs-lisp (setq org-agenda-span 14) #+END_SRC Store new notes in ~/org/notes.org #+name: org-config #+BEGIN_SRC emacs-lisp (setq org-default-notes-file (concat org-directory "/gtd.org")) #+END_SRC ** Getting things done Actionable item keywords - NEXT :: something that can be done at any moment if I'm in the right context. If it has a SCHEDULED date, it probably should not be done before that date and the configuration will make it invisible in the calender views if the date is in the future. These items can also have a DEADLINE for when they should be DONE at that date. - WAITING :: something that's awaiting feedback from someone else. If it has a SCHEDULED date, it needs followup if there hasn't been any feedback at that time. - APPT :: Appointment; something that needs to be done at a particular day or time. Must also have a date/timestamp (not a SCHEDULED date or DEADLINE). - SOMEDAY :: something that I may want to pick up later. Should be evaluated during reviews. - CANCELLED :: decided not to do this. May include a note on why it's been cancelled. - DONE :: finished item. #+name: org-config #+BEGIN_SRC emacs-lisp (setq org-todo-keywords '((sequence "NEXT(n)" "WAITING(w@)" "SOMEDAY(s)" "APPT(a)" "DEFERRED(e)" "|" "CANCELLED(c@)" "DONE(d!)"))) ;; These settings ensure that items SCHEDULED in the future are not shown ;; until that date (setq org-agenda-todo-ignore-scheduled 'future) (setq org-agenda-tags-todo-honor-ignore-options t) #+END_SRC I want to file and refile notes to any header level 1 - 3 in any file in my =org-agenda-files= list. #+name: org-config #+BEGIN_SRC emacs-lisp (setq org-refile-targets '((nil :maxlevel . 3) (org-agenda-files :maxlevel . 3))) (setq org-capture-templates '(("t" "Todo" entry (file+headline "~/org/gtd.org" "Inbox") "* NEXT %?\nEntered on %U\n %i\n %a") ("j" "Journal" entry (file+datetree "~/org/journal.org") "* %?\nEntered on %U\n %i\n %a"))) (defun my/get-things-done () (interactive) (find-file "~/org/gtd.org")) (global-set-key "\C-cd" 'my/get-things-done) (setq org-agenda-custom-commands '(("g" "Plan today" ((agenda "" ((org-agenda-span 14))) (tags-todo "Bellen") (tags-todo "Computer") (tags-todo "Online") (tags-todo "Mailen") (tags-todo "Schrijven") (tags-todo "Kantoor") (tags-todo "Boodschappen") (tags-todo "Thuis") (tags-todo "Marieke") (tags-todo "Remvee") (tags-todo "GeorgeEnRiet") (tags-todo "Lezen"))))) (setq org-modules '(org-w3m org-bbdb org-bibtex org-docview org-gnus org-info org-irc org-mhe org-rmail org-habit)) #+END_SRC ** Org-Babel *** Fontifying source blocks Enable syntax highlighting in src blocks. #+name: org-config #+BEGIN_SRC emacs-lisp (setq-default org-src-fontify-natively t) #+END_SRC Use the =minted= package for syntax highlighting source blocks in LaTeX / PDF exports. [[http://joat-programmer.blogspot.nl/2013/07/org-mode-version-8-and-pdf-export-with.html][Configuration copied from a blog post by Florian Bergmann.]] #+name: org-config #+BEGIN_SRC emacs-lisp ;; Include the latex-exporter (require 'ox-latex) ;; Add minted to the defaults packages to include when exporting. (add-to-list 'org-latex-packages-alist '("" "minted")) ;; Tell the latex export to use the minted package for source ;; code coloration. (setq org-latex-listings 'minted) ;; Let the exporter use the -shell-escape option to let latex ;; execute external programs. ;; This obviously and can be dangerous to activate! ;; I use pdflatex instead of xelatex because that seems to work ;; much better with utf-8 files (setq org-latex-pdf-process '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f")) #+END_SRC Untangle files. #+name: org-config #+BEGIN_SRC emacs-lisp (global-set-key "\C-cu" 'my/org-babel-untangle) (defun my/org-babel-untangle (path) (interactive "fFile to include: ") (message "Untangling '%s'..." path) (save-current-buffer (let ((lang (save-current-buffer (set-buffer (find-file-noselect path)) (my/mode->language major-mode)))) (insert (format "\n** %s\n\n#+BEGIN_SRC %s :tangle %s\n" (capitalize (replace-regexp-in-string "\\[_-\\]" " " (file-name-base path))) lang (file-relative-name path))) (forward-char (cadr (insert-file-contents path))) (insert "\n#+" "END_SRC\n")))) (defun my/mode->language (mode) "Return the language for the given mode" (intern (replace-regexp-in-string "\\-mode$" "" (my/->string mode)))) (defun my/org-babel-untangle-tree (path) (interactive "Droot directory to untangle: ") (mapc 'my/org-babel-untangle (cl-remove-if 'file-directory-p (f-files path (lambda (p) t) t)))) #+END_SRC ** Language evaluation support Org-Babel needs to be told that evaluation of certain languages is allowed. I collect all languages here, then enable all of them at the end of the section. #+name: org-config #+BEGIN_SRC emacs-lisp ;; List of languages that may be evaluated in Org documents (setq org-babel-load-languages '((emacs-lisp . t) ; (shell . t) (clojure .t) (ledger . t) (plantuml . t) (dot . t) (ditaa . t))) (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages) ;; use CIDER repl to evaluate clojure snippets (setq org-babel-clojure-backend 'cider) #+END_SRC ** Diagramming I like [[http://www.graphviz.org/][Graphviz]] for generating graphs. It takes a few lines of code to link graphviz's =dot= mode to =org-babel= so I can include dot source in org mode and export with nice looking diagrams. #+BEGIN_SRC emacs-lisp (add-to-list 'org-src-lang-modes (quote ("dot" . graphviz-dot))) #+END_SRC ** Exporting to slides #+name: org-config-languages #+BEGIN_SRC emacs-lisp (require 'ox-latex) (require 'ox-beamer) #+END_SRC ** Exporting to LibreOffice / ODT #+name: org-config-languages #+BEGIN_SRC emacs-lisp (require 'ox-odt) #+END_SRC * Bookkeeping I'm trying out ~ledger-cli~ and ~ledger-mode~ for personal bookkeeping. #+name: bookkeeping-setup #+BEGIN_SRC emacs-lisp (add-to-list 'auto-mode-alist '("\\.ledger\\'" . ledger-mode)) #+END_SRC Also enable ledger in org-babel literal programming style. See http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-ledger.html * 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. ;;;; ;;;; If you cannot find the `emacs.org` file, see the source ;;;; repository at https://github.com/joodie/emacs-literal-config (defvar outline-minor-mode-prefix "\M-#") <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> #+END_SRC * Tools This section defines some functionality used elsewhere in this configuration. ** Hooks and modes #+name: tools #+BEGIN_SRC emacs-lisp (defun my/->string (str) (cond ((stringp str) str) ((symbolp str) (symbol-name str)))) (defun my/->mode-hook (name) "Turn mode name into hook symbol" (intern (replace-regexp-in-string "\\(-mode\\)?\\(-hook\\)?$" "-mode-hook" (my/->string name)))) (defun my/->mode (name) "Turn mode name into mode symbol" (intern (replace-regexp-in-string "\\(-mode\\)?$" "-mode" (my/->string name)))) (defun my/set-modes (arg mode-list) (dolist (m mode-list) (if (fboundp (my/->mode m)) (funcall (my/->mode m) arg) (message "No mode %s found" m)))) (defun my/turn-on (&rest mode-list) "Turn on the given (minor) modes." (my/set-modes +1 mode-list)) (defvar my/normal-base-modes (mapcar 'my/->mode '(text prog)) "The list of modes that are considered base modes for programming and text editing. In an ideal world, this should just be text-mode and prog-mode, however, some modes that should derive from prog-mode derive from fundamental-mode instead. They are added here.") (defun my/normal-mode-hooks () "Returns the mode-hooks for `my/normal-base-modes`" (mapcar 'my/->mode-hook my/normal-base-modes)) #+END_SRC * Environment OSX doesn't set the environment from the shell init files for graphical applications, but I set PATH and a bunch of other stuff there. The =exec-path-from-shell= package will take care of that. Thanks to Ting-Yu Lin for pointing it out. #+NAME: environment #+BEGIN_SRC emacs-lisp (when (memq window-system '(mac ns)) (exec-path-from-shell-initialize) (setenv "LANG" "en_US.UTF-8")) #+END_SRC External packages may be dropped in the .emacs.d/ext directory. #+NAME: environment #+BEGIN_SRC emacs-lisp (add-to-list 'load-path "~/.emacs.d/ext") (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu/mu4e") #+END_SRC Connect info for GPG Agent #+NAME: environment #+BEGIN_SRC emacs-lisp ;; read gpg-agent environment (defun my/read-env-line (line) "read a env line and post to environment" (let ((key-value-pair (split-string line "=" t))) (setenv (car key-value-pair) (car (last key-value-pair))))) (defvar my/gpg-agent-info-file) (setq my/gpg-agent-info-file (concat (getenv "HOME") "/.gpg-agent-info")) (when (file-exists-p my/gpg-agent-info-file) (with-temp-buffer (insert-file-contents my/gpg-agent-info-file) (mapc 'my/read-env-line (split-string (buffer-string) "\n" t)))) #+END_SRC * Options set using the customize interface By default, Emacs saves the options you set via the `customize-*` functions in the user init file, which is "~/.emacs.d/init.el" in this setup. I prefer to have it put that data in a seperate file. #+name: customize-config #+BEGIN_SRC emacs-lisp (setq custom-file "~/.emacs.d/custom.el") (load custom-file) #+END_SRC