#+TITLE: Gregory Burd's Emacs 24 Configuration #+AUTHOR: Gregory Burd #+EMAIL: greg@burd.me #+OPTIONS: toc:3 num:nil #+HTML_HEAD: * Configuration Emacs is a special beast. Taming it takes a lot of care. In an attempt to document/explain/share with the rest of the world, this is my attempt at configuration as a literate program. It also shows off the awesome power of org-mode, which makes all of this possible. ** User details :PROPERTIES: :CUSTOM_ID: user-info :END: Emacs will normally pick this up automatically, but this way I can be sure the right information is always present. #+begin_src emacs-lisp (setq user-full-name "Gregory Burd") (setq user-mail-address "greg@burd.me") #+end_src ** Environment :PROPERTIES: :CUSTOM_ID: environment :END: There are plenty of things installed outside of the default =PATH=. This allows me to establish additional =PATH= information. At the moment, the only things that added are =/usr/local/bin= for homebrew on OS X and =.cabal/bin= for [[http://www.haskell.org/cabal/][Haskell package binaries]]. Emacs lisp is really only a subset of common lisp, and I need to have some of the additional functionality to make the configuration and its dependencies work properly, which we get by requiring [[http://www.emacswiki.org/emacs/CommonLispForEmacs][Common Lisp for Emacs]]. #+begin_src emacs-lisp ;(setq debug-on-error t) ;(setq debug-on-signal t) (setenv "PATH" (concat "/usr/local/bin:/opt/local/bin:/usr/bin:/bin" (getenv "PATH"))) (require 'cl-lib) #+end_src *** Define default packages :PROPERTIES: :CUSTOM_ID: default-packages :END: This is the list of packages used in this configuration. #+begin_src emacs-lisp (setq burd-packages '( ; clojure-mode ; clojure-test-mode ; csharp-mode ; nrepl ac-slime ag ;; auto-complete ;; electric-pair-mode ;; cc-guess cc-mode cmake-mode coffee-mode company company-c-headers company-cmake deft dockerfile-mode editorconfig elixir-mix elixir-mode eredis erlang feature-mode flx flx-ido flx-isearch flycheck flycheck-google-cpplint flycheck-ocaml flycheck-pos-tip flycheck-rust gh gist git-commit go-mode graphviz-dot-mode haml-mode haskell-mode htmlize intellij-theme lua-mode magit markdown-mode marmalade multi-web-mode nix-mode nodejs-repl o-blog org paredit pastebin php-mode puppet-mode python-mode python-pep8 restclient rust-mode rvm scala-mode smex sml-mode solarized-theme toml-mode web-mode writegood-mode yaml-mode)) #+end_src ** Package Management :PROPERTIES: :CUSTOM_ID: package-management :END: Since Emacs 24, Emacs includes the Emacs Lisp Package Archive ([[http://www.emacswiki.org/emacs/ELPA][ELPA]]) by default. This provides a nice way to install additional packages. Since the default package archive doesn't include everything necessary, the [[http://marmalade-repo.org/][marmalade]], and [[http://melpa.milkbox.net/#][melpa]] repositories are also added. #+begin_src emacs-lisp (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")) ;; install any packages in burd-packages, if they are not installed already (let ((refreshed nil)) (when (not package-archive-contents) (package-refresh-contents) (setq refreshed t)) (dolist (pkg burd-packages) (when (and (not (package-installed-p pkg)) (assoc pkg package-archive-contents)) (unless refreshed (package-refresh-contents) (setq refreshed t)) (package-install pkg)))) (defun package-list-unaccounted-packages () "Like `package-list-packages', but shows only the packages that are installed and are not in `burd-packages'. Useful for cleaning out unwanted packages." (interactive) (package-show-package-list (remove-if-not (lambda (x) (and (not (memq x burd-packages)) (not (package-built-in-p x)) (package-installed-p x))) (mapcar 'car package-archive-contents)))) #+end_src ** Start-up options :PROPERTIES: :CUSTOM_ID: start-up-options :END: *** Splash Screen :PROPERTIES: :CUSTOM_ID: splash-screen :END: I want to skip straight to the scratch buffer. This turns off the splash screen and puts me straight into the scratch buffer. I don't really care to have anything in there either, so turn off the message while we're at it. Since I end up using =org-mode= most of the time, set the default mode accordingly. #+begin_src emacs-lisp (setq inhibit-splash-screen t initial-scratch-message nil initial-major-mode 'org-mode) #+end_src *** Scroll bar, Tool bar, Menu bar :PROPERTIES: :CUSTOM_ID: menu-bars :END: Emacs starts up with way too much enabled. Turn off the scroll bar, menu bar, and tool bar. There isn't really a reason to have them on. #+begin_src emacs-lisp (when window-system (scroll-bar-mode -1) (tool-bar-mode -1) (menu-bar-mode -1)) #+end_src *** Marking text :PROPERTIES: :CUSTOM_ID: regions :END: There are some behaviors in Emacs that aren't intuitive. Since I pair with others that don't know how Emacs handles highlighting, treat regions like other text editors. This means typing when the mark is active will write over the marked region. Also, make the common highlighting keystrokes work the way most people expect them to. This saves a lot of time explaining how to highlight areas of text. Emacs also has it's own clipboard and doesn't respond to the system clipboard by default, so tell Emacs that we're all friends and can get along. #+begin_src emacs-lisp (delete-selection-mode t) (transient-mark-mode t) (setq x-select-enable-clipboard t) #+end_src *** Display Settings :PROPERTIES: :CUSTOM_ID: buffers :END: I have some modifications to the default display. First, a minor tweak to the frame title. It's also nice to be able to see when a file actually ends. This will put empty line markers into the left hand side. #+begin_src emacs-lisp (when window-system (setq frame-title-format '(buffer-file-name "%f" ("%b"))) (set-face-attribute 'default nil :family "Fira Code Nerd Font Mono" :height 134 :weight 'normal :width 'normal) (when (functionp 'set-fontset-font) (set-fontset-font "fontset-default" 'unicode (font-spec :family "DejaVu Sans Mono" :width 'normal :size 12.4 :weight 'normal)))) (setq-default indicate-empty-lines t) (setq-default fill-column 80) ; (setq-default auto-fill-mode nil) (require 'newcomment) (setq comment-auto-fill-only-comments 1) (setq-default auto-fill-function 'do-auto-fill) (when (not indicate-empty-lines) (toggle-indicate-empty-lines)) #+end_src *** Font Ligature :PROPERTIES: :CUSTOM_ID: ligature :END: Modern fonts such as Fira Code and PragmataPro provide ligatures for common useful programming constructs (for example -> to ⟶ or lambda to λ). https://github.com/tonsky/FiraCode/wiki/Emacs-instructions https://emacs.stackexchange.com/questions/9586/otf-ligature-support-in-emacs https://www.reddit.com/r/emacs/comments/4sm6fa/how_to_enable_pragmatapro_ligatures/ #+begin_src emacs-lisp (cl-defun fira-code-mode--make-alist (list) "Generate prettify-symbols alist from LIST." (let ((idx -1)) (mapcar (lambda (s) (setq idx (1+ idx)) (let* ((code (+ #Xe100 idx)) (width (string-width s)) (prefix ()) (suffix '(?\s (Br . Br))) (n 1)) (while (< n width) (setq prefix (append prefix '(?\s (Br . Bl)))) (setq n (1+ n))) (cons s (append prefix suffix (list (decode-char 'ucs code)))))) list))) (defconst fira-code-mode--ligatures '("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\" "{-" "[]" "::" ":::" ":=" "!!" "!=" "!==" "-}" "--" "---" "-->" "->" "->>" "-<" "-<<" "-~" "#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_(" ".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*" "/**" "/=" "/==" "/>" "//" "///" "&&" "||" "||=" "|=" "|>" "^=" "$>" "++" "+++" "+>" "=:=" "==" "===" "==>" "=>" "=>>" "<=" "=<<" "=/=" ">-" ">=" ">=>" ">>" ">>-" ">>=" ">>>" "<*" "<*>" "<|" "<|>" "<$" "<$>" "