Emacs configuration

Customization of built in Emacs features

"yes or no" vs "y or n"

I can't understand why anybody would want to answer a full word "yes", instead of just "y", or "no", instead of just "n". It's certainly too long for me. Therefore, I make all prompts "y or n".

(defalias 'yes-or-no-p 'y-or-n-p)

Backup files

I don't want backup files littering my folders. I use VCS a lot anyway.

(setq make-backup-files nil)

Menu and tool bars

Coming from a vim background, I prefer to not have menu bars and tool bars clutter my limited screen real estate. I like all of the screen devoted to just text. Menu bars are very useful to discover new features, but I can always enable them when I need to, instead of keeping them permanently enabled.

(menu-bar-mode 0)
(tool-bar-mode 0)

Visual line mode

A lot of my work in emacs involves writing using org mode and latex. Word wrapping and the use of "visual lines" is absolutely important for this.

(global-visual-line-mode t)

Highlighting parentheses

Highlighting matching parentheses is really important when coding. I don't know why this is not enabled by default in emacs.

(show-paren-mode)

Smooth scrolling

Scrolling must be smooth, bringing up one new line at a time. When a whole new page is brought up, the effect is so jumpy. It is easy to lose track of where you were in the text and you have to scan the screen looking for the cursor.

(setq scroll-step 1)

Splitting windows

(setq split-height-threshold nil
      split-width-threshold 75)

Package manager

Set up the package manager. Define the list of repos and initialize installed packages.

(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(package-initialize)

use-package

use-package is an immensely useful macro system that helps you organize your various customizations in a sane per-package fashion.

(require 'use-package)

Moving between windows

The standard way of moving between windows using C-x o involves too many keystrokes. I prefer the more spatially intuitive S-{left,right,up,down} keybindings of the windmove package with wrapping around the edge of the frame enabled.

(use-package windmove
  :config
  (windmove-default-keybindings)
  (setq windmove-wrap-around t))

Evil and other evil plugins

I was using vim for around 3 to 4 years before switching to emacs for lisp and its superior programmability. However, I hardly want to retrain my muscle memory by learning all new keybindings. Besides, why not use the best of both worlds? So, I use evil (the Extensible VI Layer for emacs) on top of emacs to emulate vim.

;; evil
(use-package evil
  :config (evil-mode))

Vim users have come up with nifty plugins to make life more convenient and efficient on vim. I used to use many of these plugins when I was on vim. Thankfully, many of these plugins have been ported to emacs evil, and I can stay right at home here in emacs and enjoy their benefits.

evil-surround

evil-surround, a port of vim-surround, helps change surrounding text objects (such as matching parentheses) easily. How did people live without these things!

(use-package evil-surround
  :config (global-evil-surround-mode))

evil-commentary

evil-commentary, a port of vim-commentary, helps quickly and easily comment out and uncomment lines. Very useful when coding. Earlier, I used to use regexes to do the same, but this is such a commonly performed operation, that it is worth having a separate plugin for it.

(use-package evil-commentary
  :config (evil-commentary-mode))

evil-quickscope

A common character motion in vim/evil is to jump to a target word by using "f". For larger sentences, this gets tedious because you are forced to scan through the text trying to decide which character to jump to.

evil-quickscope, a port of vim-quickscope, highlights these characters, making it each easier to jump to words without guesswork or tedious scanning.

evil-quickscope-always-mode is distracting with too many colors changing rather rapidly. So, I prefer to use evil-quickscope-mode which highlights target characters only on pressing the "f" key.

(use-package evil-quickscope
  :config (global-evil-quickscope-mode))

Relative line numbering

Relative line numbering (similar to vim's "set rnu") is very important for the "j" and "k" motions of evil. In emacs, relative line numbering is implemented by linum-relative. While this is not an evil plugin, I include it along with evil plugins because it emulates a vim-like feature.

(use-package linum-relative
  :config
  (setq linum-relative-current-symbol "")
  (linum-relative-global-mode))

Gnuplot mode

Gnuplot mode provides syntax highlighting, indentation and a few other convenient functions for editing gnuplot scripts. Unfortunately, gnuplot-mode only recognizes file extensions ".gp" and ".gnuplot" as gnuplot scripts, while vim recognizes the ".gpi" extension. I don't want to have to rename all my gnuplot scripts. So, I just tell gnuplot-mode to recognize the ".gpi" extension as well.

(use-package gnuplot-mode
  :mode "\\.gpi")

Helm

Helm has among the best fuzzy matching I've seen outside of search engines such as Google. The way it asynchronously completes commands feels just magical. It is definitely one of those must have emacs packages.

I have rebound several standard emacs functions to equivalent (and superior!) helm functions. A wonderfully colorful introduction to helm is here. Slowly, as my use of emacs evolves, I'll include more of helm's features into my workflow. Right now, I've barely begun to scratch the surface.

For commands, I prefer using the vim/evil style ":" key binding, instead of the emacs style M-x. So, I have bound helm's version of M-x to ":". My workflow is still not completely independent of the evil command prompt, and I still use it occasionally. Hence I have moved it to ";" for when I need it.

Screen real estate is precious. So, I've enabled helm's autoresize feature to make it use as less space as possible on the screen. Besides, an automatically resizing window looks so dynamic and alive!

(use-package helm
  :bind
  ("C-x C-f" . helm-find-files)
  ("C-x b" . helm-mini)
  ("C-s" . helm-occur)
  ("C-h i" . helm-info-emacs)
  :init
  (bind-keys :map evil-normal-state-map
             (":" . helm-M-x)
             (";" . evil-ex))
  :config (helm-autoresize-mode))

Dired

With its convenient emacsy interface and good emacs integration, dired is the text based file manager that finally convinced me to quit the GUI file managers I was using earlier. I spend so much time in emacs (programming, mail, blogging, getting things done with org mode, etc.) that an emacs based file manager is just the natural thing to have!

In dired's file listings, I prefer seeing human readable file sizes (such as 1K, 234M, 2G, etc.) instead of the number of bytes which are usually too large to be meaningfully interpreted by a human being. Hence I've added the -h switch to dired's ls calls.

(use-package dired
  :defer t
  :config (setq dired-listing-switches "-alh"))

smartparens

smartparens is a minor mode for structured editing of parenthesis pairs. This (especially slurping and barfing) is very important for writing lisp S-expressions, and I can't imagine coding without it.

I also find smartparens useful for other non-lisp work such as for inserting balanced parentheses while editing LaTeX equations, and even while editing C source code.

I use evil-smartparens on top of smartparens to make evil play nice with smartparens. I've rebound various smartparens commands to convenient vim/evil like key bindings.

(use-package smartparens
  :defer t
  :init
  (dolist (hook '(emacs-lisp-mode-hook lisp-mode-hook scheme-mode-hook
                        c-mode-hook LaTeX-mode-hook))
    (add-hook hook 'smartparens-strict-mode))
  (add-hook 'smartparens-enabled-hook 'evil-smartparens-mode)
  :config (require 'smartparens-config))

(use-package evil-smartparens
  :defer t
  :init
  (defun s-expression-evil-smartparens ()
    (interactive)
    (bind-keys :map evil-normal-state-local-map
               ("l" . sp-forward-sexp)
               ("h" . sp-backward-sexp)
               ("L" . sp-up-sexp)
               ("H" . sp-backward-up-sexp)
               ("<" . sp-backward-slurp-sexp)
               (">" . sp-forward-slurp-sexp)
               ("{" . sp-forward-barf-sexp)
               ("}" . sp-backward-barf-sexp)))
  (dolist (hook '(emacs-lisp-mode-hook lisp-mode-hook scheme-mode-hook))
    (add-hook hook 's-expression-evil-smartparens)))

doc-view

Continuous scrolling feels more natural than having to switch keys to get to the next page.

(use-package doc-view
  :defer t
  :config (setq doc-view-continuous t))