Personal .emacs.d directory.
Emacs Lisp
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
local
site-lisp
.gitignore
README.org
init.el

README.org

Jon-Michael Deldin’s Emacs Configuration

I started using Emacs in the fall of 2010 after a few years of Vim. I use GNU Emacs 25.1+ on Ubuntu for Org-Mode, Ruby, LaTeX, sh, and a host of miscellaneous other languages.

Installation

You can clone directly as $HOME/.emacs.d:

git clone git://github.com/jmdeldin/.emacs.d.git ~/.emacs.d/

Notes

Improvements

add org-mode/orgstruct to magit

evaluate company-mode

Keys

KeyDescription
C-q TABInsert literal tab
M-yTraverse kill-ring (after C-y)
C-u C-SPCJump to last mark
M-n(In cua-mode) Increment digit
C-M \Indent according to major mode
C-c C-sStart IRB
C-c C-rSend region to IRB (C-c C-s first)
C-x v =Diff against HEAD
C-u C-x v =Diff against other branch
C-x v uDiscard changes
C-x v ~Checkout another rev
C-x v lView commit log
C-Shift BSKill whole line
C-c ’Edit code block (org-babel)
C-x r mBookmark the current loc in a file
C-x r bJump to bookmark
C-x r lList bookmarks
C-x C-nNarrow region
C-x C-wWiden region
C-x r wSave window configuration
C-x r jRestore configuration
M-&Execute shell command asynchronously
C-x r tRemoves the content in a rectangle (mark first)
M-0 .. M-9Prefix argument
M– M-cCapitalize last word (M-dash for back)
M-eForward sentence
M-aBackward sentence
C-M-fMove forward by a balanced expr (e.g., “,’, [])
C-M-bMove backward by a balanced expr
M-mback-to-indentation (^ in Vim)
M-rmove the point w/o scrolling
M-g M-ggoto-line
M-o M-sCenter text
C-x r NNumber lines

Searching

KeyDescription
M-pprevious search term
M-nnext search term
M-ctoggle case-sensitivity
C-s C-wsearch with the word at point (* inv Vim)

Ido-mode

These keys work inside the Ido minibuffer (C-x C-f).

KeyDescription
C-dOpen a dired buffer in the current directory
C-aToggles showing ignored files
C-cToggles case-sensitivity
C-s & C-rMove to the next/prev match
C-SPCRestrict to an expr (C-x C-b .org C-SPC for just org)

Functions and modes

FunctionDescription
follow-modeBrowse splits like they’re one window
ielm-modeElisp REPL
hexl-modeHex viewer
bury-bufferSend buffer to end of list
highlight-changes-modeShow newly changed text in red
info-aproposfull-text search of info

org-mode

CommandDecription
C-c C-nnext heading
C-c C-pprevious heading
C-c C-fnext heading (same level)
C-c C-bprevious heading (same level)
C-c C-uback to a higher heading
C-c /Sparse tree
M-S-RETInsert new item with checkbox
M-S-UP/DOWNMove items including subitems up/down
C-c -Cycle list level through different bullets

Dired

CommandDescription
% uuppercase filename
% llowercase filename
% Rregex rename

Initialization

Load custom helper functions

(load-file (concat user-emacs-directory "site-lisp/defuns.el"))

Set custom-file

On clean installs, some packages will try to append custom vars to init.el, breaking installation. The custom-file must be set before trying to install packages.

(setq custom-file (concat user-emacs-directory "local/emacs-custom.el"))
(load custom-file 'noerror)

Set up repositories

(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
                         ("melpa-stable" . "https://stable.melpa.org/packages/")
                         ("melpa-unstable" . "https://melpa.org/packages/")))

Define required packages

We can declare the origin of our packages with the package-pinned-packages variable:

(setq package-pinned-packages
      '(
        (ac-geiser . "melpa-stable")
        (ace-window . "melpa-stable")
        (ag   . "melpa-stable")
        (auto-complete . "melpa-stable")
        (cider . "melpa-stable")
        (clojure-mode . "melpa-stable")
        (coffee-mode . "melpa-stable")
        (dim . "melpa-unstable")
        (elfeed . "melpa-unstable")
        (evil . "melpa-unstable")
        (evil-matchit . "melpa-stable")
        (evil-numbers . "melpa-stable")
        (evil-paredit . "melpa-unstable")
        (geiser . "melpa-stable")
        (go-mode . "melpa-stable")
        (haml-mode . "melpa-stable")
        (highlight-indentation . "melpa-stable")
        (htmlize . "melpa-unstable") ; for org exports
        (ledger-mode . "melpa-stable")
        (magit . "melpa-stable")
        (markdown-mode . "melpa-stable")
        (mmm-mode . "melpa-stable")
        (nginx-mode . "melpa-stable")
        (org . "gnu")
        (projectile . "melpa-stable")
        (rainbow-mode . "gnu")
        (rspec-mode . "melpa-stable")
        (slim-mode . "melpa-stable")
        (smex . "melpa-stable")
        (tiny . "melpa-unstable") ; for invoices
        (tuareg . "melpa-stable")
        (yaml-mode . "melpa-stable")
        ))

Install Packages

(setq jm/packages (mapcar 'car package-pinned-packages))

(jm/install-all-packages jm/packages)

Server

Only load the server if it isn’t running:

(load "server")
(unless (server-running-p)
  (server-start))

Garbage

This section is dedicated to all of the turd files Emacs leaves all over your machine.

Lockfiles

Disable lockfiles – there’s only one user on this machine. This prevents guard from re-running specs everytime the file is edited (but not saved).

(setq create-lockfiles nil)

Backups

Place backups in ~/.emacs.d/local/backups:

(setq backup-by-copying t)
(setq backup-directory-alist
      (list (cons "." (jm/local-path "backups"))))
(setq delete-old-versions t)
(setq kept-new-versions 6)
(setq kept-old-versions 2)
(setq version-control t)

Auto-saves

Keep auto-save files together. Test with M-x do-auto-save.

(let ((new-dir (jm/local-path "auto-saves/")))
  (setq auto-save-list-file-prefix new-dir)
  (setq auto-save-file-name-transforms
      `((".*" ,new-dir t))))

Bookmarks

Use ~/.emacs.d/local/.emacs.bmk for bookmarks:

(setq bookmark-file (jm/local-path "bookmarks"))

Communication

ERC

Prevent auto-joining #erc

(setq erc-autojoin-channels-alist '())

Spell-check ERC:

(erc-spelling-mode 1)

Ignore noise:

(setq erc-network-hide-list '("JOIN" "PART" "QUIT" "NICK" "MODE"))
(setq erc-track-exclude-server-buffer t)

Highlight nick:

(setq erc-current-nick-highlight-type 'nick)

mu4e

Initialization

Run this in your local/local.el file to actually initialize mu4e. I keep this in a function for the machines I don’t use mu4e on.

(defun jm/setup-mu4e ()
  (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e/")
  (require 'mu4e)
  (require 'mu4e-contrib))

Network

I use nullmailer locally for SMTP, which acts just like sendmail:

(setq message-send-mail-function 'message-send-mail-with-sendmail)

getmail is a pretty simple client to configure:

(setq mu4e-get-mail-command "getmail")

Reading

Enable inline-images:

(setq mu4e-view-show-images t)

Use imagemagick to convert a file when necessary:

(when (fboundp 'imagemagick-register-types)
  (imagemagick-register-types))

Convert HTML emails:

(setq mu4e-html2text-command 'mu4e-shr2text)

Writing

Close the compose buffer after sending:

(setq message-kill-buffer-on-exit t)

One last chance to undo:

(add-hook 'message-send-hook
  (lambda ()
    (unless (yes-or-no-p "Are you sure you want to send this?")
      (signal 'quit nil))))

Keybindings

(global-set-key (kbd "<f8>") 'mu4e)

News

Elfeed is a really nice RSS reader for Emacs that’s easy to use and fast.

Elfeed Configuration

Keep the database inside ~/.emacs.d instead of in $HOME:

(setq elfeed-db-directory (concat user-emacs-directory "local/elfeed"))

Keybinding:

(defun jm/elfeed ()
  "Download feed updates before using elfeed."
  (interactive)
  (elfeed-update)
  (elfeed))

(global-set-key (kbd "<f9>") 'jm/elfeed)

Feeds

(setq elfeed-feeds
      '(
        ("https://feeds.feedburner.com/lifehacker/full" drivel)
        ("http://nullprogram.com/feed/" emacs)
        ("http://planet.emacsen.org/atom.xml" emacs)
        ("http://sachachua.com/blog/feed/" emacs)
        ("https://www.masteringemacs.org/feed" emacs)
        ("https://www.reddit.com/r/emacs.xml" emacs)
        ("http://matthewkirk.com/feed/" friends)
        ("https://www.reddit.com/r/linux.rss" linux)
        ("http://www.jmdeldin.com/atom.xml" personal)
        ("https://jvns.ca/atom.xml" programming)
        ("https://www.reddit.com/r/everett.xml" news)))

Text Editing

Default to 72 column width for plain text

(add-hook 'text-mode-hook
          '(lambda ()
             (set-fill-column 72)))

Match parens and quotes

(electric-pair-mode t)

Enable on-the-fly reindentation

(electric-indent-mode t)

Insert a newline around special characters

(electric-layout-mode t)

Use single spaces between sentences for fill-paragraph (M-q)

(setq sentence-end-double-space nil)

Use Unicode everywhere

(prefer-coding-system 'utf-8)

Changing a region’s case is useful

(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)

Remember last edit position

(require 'saveplace)
(setq-default save-place t)
(setq save-place-file (jm/local-path "places"))

Auto-Complete Mode

(require 'auto-complete-config)
(ac-config-default)
(setq ac-ignore-case nil)
(add-to-list 'ac-modes 'ruby-mode)
(setq ac-comphist-file (jm/local-path "ac-comphist.dat"))

Spelling

Use aspell instead of ispell, use list for faster region checking, and use a faster suggestion mode.

(setq ispell-program-name "aspell")
(setq ispell-list-command "list")
(setq ispell-extra-args '("--sug-mode=ultra"))

Turn it on for comments

(mapcar (lambda (mode-hook) (add-hook mode-hook 'highlight-indentation-current-column-mode))
        '(c-mode-common-hook emacs-lisp-mode-hook ruby-mode-hook
                             coffee-mode-hook))
(ac-flyspell-workaround)

Turn it on for some modes:

(mapcar (lambda (mode)
          (add-hook mode (lambda () (flyspell-mode t))))
        '(org-mode-hook markdown-mode text-mode))
(add-hook 'git-commit-mode-hook 'turn-on-flyspell)

Whitespace

Wrap lines at column 78

(setq-default fill-column 78)

Highlight right-margin when whitespace-mode is on

(setq whitespace-line-column fill-column)

Highlight empty lines

(setq-default indicate-empty-lines t)

Hard-wrap lines all the time

(add-hook 'text-mode-hook 'turn-on-auto-fill)

Use spaces, not tabs (C-q C-i to insert a hard-tab)

(setq-default indent-tabs-mode nil)

2-space tabs

(setq-default tab-width 2)

Insert tabs when appropriate

(setq indent-line-function 'insert-tab)

Insert a newline at the EOF

(setq-default require-final-newline t)

Delete trailing whitespace on save

(add-hook 'before-save-hook 'delete-trailing-whitespace)

Highlight Stuff

(mapcar (lambda (mode-hook) (add-hook mode-hook 'highlight-indentation-current-column-mode))
        '(ruby-mode-hook coffee-mode-hook slim-mode-hook))

UI

Hide the {menu,tool,scroll}bars

(if window-system
    (progn
      (scroll-bar-mode -1)
      (tool-bar-mode -1)))
(menu-bar-mode -1)

Hide the startup messages

(setq inhibit-startup-message t)
(setq inhibit-startup-echo-area-message t)

“y or n” instead of “yes or no”

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

Show line & column number in the mode line

(column-number-mode t)

Show file size

(size-indication-mode t)

Highlight parens

(show-paren-mode t)
(setq show-paren-delay 0.0)

Highlight current line

(global-hl-line-mode 1)

Use ibuffer instead of list-buffers

(defalias 'list-buffers 'ibuffer)

No bells

(setq ring-bell-function 'ignore)

Window Management

Restore window configuration with C-c LEFT

(winner-mode)

Enable windmove – default binding is shift

(windmove-default-keybindings)
(setq windmove-wrap-around t)

Make windmove work in org-mode:

(add-hook 'org-shiftup-final-hook 'windmove-up)
(add-hook 'org-shiftleft-final-hook 'windmove-left)
(add-hook 'org-shiftdown-final-hook 'windmove-down)
(add-hook 'org-shiftright-final-hook 'windmove-right)

Minibuffer

IDO

Interactively-do-things is the greatest Emacs extension.

(setq ido-enable-flex-matching t)
(setq ido-everywhere t)
(setq ido-show-dot-for-dired t)
(setq ido-save-directory-list-file (jm/local-path "ido.last"))
(setq ido-use-virtual-buffers t)
(ido-mode 1)

Uniquify

Use part of the directory to distinguish between identically-named files:

(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)

Minibuffer History

Save minibuffer history:

(savehist-mode 1)
(setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring))
(setq savehist-file (jm/local-path "savehist"))

Recent Files

Enable recent files:

(require 'recentf)
(setq recentf-save-file (jm/local-path "recentf"))
(setq recentf-max-saved-items 1000)
(recentf-mode 1)

Mouse

Enable mouse support in a terminal (from StackOverflow):

(unless window-system
  (require 'mouse)
  (xterm-mouse-mode t)
  (global-set-key [mouse-4] '(lambda ()
                               (interactive)
                               (scroll-down 1)))
  (global-set-key [mouse-5] '(lambda ()
                               (interactive)
                               (scroll-up 1)))
  (defun track-mouse (e))
  (setq mouse-sel-mode t))

Keybindings

Evil

Arguably the best Vim ever, but sometimes, I still want Emacs keys.

(evil-mode t)
(define-key evil-insert-state-map (kbd "C-a") 'beginning-of-line)
(define-key evil-insert-state-map (kbd "C-e") 'end-of-line)
(define-key evil-insert-state-map (kbd "C-d") 'delete-forward-char)
(define-key evil-insert-state-map (kbd "C-k") 'kill-line)
(define-key evil-normal-state-map (kbd "C-p") 'evil-previous-line)
(define-key evil-normal-state-map (kbd "C-n") 'evil-next-line)
(define-key evil-insert-state-map (kbd "C-p") 'evil-previous-line)
(define-key evil-insert-state-map (kbd "C-n") 'evil-next-line)
(define-key evil-insert-state-map (kbd "C-z") 'suspend-emacs)
(define-key evil-normal-state-map (kbd "C-z") 'suspend-emacs)

Disable vi in some buffers:

(mapc (lambda (mode)
        (evil-set-initial-state mode 'emacs))
      '(elfeed-show-mode elfeed-search-mode Info-mode-hook Ledger-Report-Mode))

Editing

M-/ – use a more powerful expansion

(global-set-key (kbd "M-/") 'hippie-expand)

C-c C-r – Revert buffer

(global-set-key (kbd "C-c C-r") 'revert-buffer)

Swap C-j and RET

(global-set-key (kbd "RET") 'reindent-then-newline-and-indent)
(global-set-key (kbd "C-j") 'newline)

C-c C-d – Remove trailing whitespace

(global-set-key (kbd "C-c C-d") 'delete-trailing-whitespace)

C-w – delete the previous word (like most shells)

(global-set-key (kbd "C-w") 'backward-kill-word)

C-x C-k – kill region (since we just unbound it with C-w)

(global-set-key (kbd "C-x C-k") 'kill-region)

C-x C-j – join line

(global-set-key (kbd "C-x C-j") 'join-line)

C-c w – toggle whitespace mode

(global-set-key (kbd "C-c w") 'global-whitespace-mode)

better commenting (replaces the original comment-dwim)

(global-set-key (kbd "M-;") 'comment-or-uncomment-region)

C-x m – recompile

(global-set-key (kbd "C-x m") 'recompile)

C-x gmagit-status

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

C-x xjm/shell

(global-set-key (kbd "C-x x") 'jm/shell)

M-#jm/reload-init

(global-set-key (kbd "M-#") 'jm/reload-init)

C-x aag-regexp-project-at-point

(global-set-key (kbd "C-x a") 'ag-regexp-project-at-point)

C-x p – find files in project

(projectile-global-mode t)
(setq projectile-known-projects-file (jm/local-path "projectile-bookmarks.eld"))
(setq projectile-cache-file (jm/local-path "projectile-cache"))
(global-set-key (kbd "C-x p") 'projectile-find-file)

M-x – ido-like completion for functions

(smex-initialize)
(global-set-key (kbd "M-x") 'smex)
(setq smex-save-file (jm/local-path "smex-items"))

Windows

M-s/M-S – switch windows

(global-set-key (kbd "M-s") 'ace-window)
(global-set-key (kbd "M-S") 'ace-window)

Mac

Make the Cmd and Opt keys work for M-x

(when system-type "darwin"
  (setq-default mac-command-modifier 'super)
  (setq-default mac-option-modifier 'meta))

Clutter

Hide a bunch of minor modes:

(dim-minor-names '(
           (auto-complete-mode "")
           (auto-fill-function "") ; the "Fill" text
           (eldoc-mode "")
           (flyspell-mode "")
           (highlight-indentation-current-column-mode "")
           (org-indent-mode "")
           (projectile-mode "")
           (rspec-mode "")
           (undo-tree-mode "")
           ))

VC mode does not need to show more than the branch. The following code from Malabrba does just that:

(setcdr (assq 'vc-mode mode-line-format)
        '((:eval (replace-regexp-in-string "^ Git" " " vc-mode))))

Themes

For dumb terminals:

(if (and (not window-system) (string= (getenv "TERM") "dumb"))
    (progn
      (set-face-background 'hl-line "#666")
      (set-face-foreground 'hl-line "#fff")))

For GUIs:

(if window-system
    (let ((jm/font "Source Code Pro-13"))
      (set-face-attribute 'default nil :font jm/font)
      (set-frame-font jm/font)))

Languages

C

The only way to program.

(setq c-default-style "k&r")

Use four spaces for tabs.

(setq-default c-basic-offset 4)

Many-windows mode makes Emacs into a more traditional IDE for GDB. See C-h f gdb for details. NOTE: This doesn’t work on OS 10.8 (non-stop mode isn’t supported).

(setq gdb-many-windows t)

Clojure

(add-hook 'cider-mode-hook 'cider-turn-on-eldoc-mode)
(setq cider-repl-result-prefix ";; => ")
(add-hook 'cider-repl-mode-hook 'subword-mode)
(setq cider-auto-select-error-buffer nil)

(add-hook 'cider-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c ,") 'cider-test-run-tests)))

CSS

Turn on rainbow-mode for colored hex values

(add-hook 'css-mode-hook 'rainbow-mode)

Prevent SCSS from compiling at save time:

(setq scss-compile-at-save nil)

Two spaces:

(setq css-indent-offset 2)

Graphviz

(associate-file-type '(".gv" ".dot") 'graphviz-dot-mode)

JavaScript

2 space indent:

(setq js-indent-level 2)

Support React stuff:

(associate-file-type '(".jsx") 'js-mode)

LaTeX

Produce PDFs instead of DVIs

(setq TeX-PDF-mode t)

Lisp

(define-key lisp-mode-shared-map (kbd "C-c e") 'eval-buffer)

(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)

Markdown

(associate-file-type '(".md" ".markdown") 'markdown-mode)

ERB

Support editing mixed mode files, like ERB templates.

(require 'mmm-auto)
(setq mmm-global-mode 'auto)
(setq mmm-submode-decoration-level 2)
(setq mmm-parse-when-idle t)

(mmm-add-mode-ext-class 'html-erb-mode "\\.html\\.erb\\'" 'erb)
(mmm-add-mode-ext-class 'html-erb-mode nil 'html-js)
(mmm-add-mode-ext-class 'html-erb-mode nil 'html-css)

(associate-file-type '(".html.erb" ".erb") 'html-erb-mode)

Org-Mode

Include the org-habit module for the agenda:

(setq org-modules (quote (org-habit)))

Paths

This configuration assumes org files live in the ~/org directory. You can customize it by setting these variables in ../local/local.el:

(setq org-directory "~/org")
(setq org-default-notes-file "~/org/capture.org")
(setq org-journal-file "~/org/journal.org.gpg")
(setq org-work-journal-file "~/org/work.org")
(setq org-log-file "~/org/log.org")
(setq org-notes-file "~/org/notes.org")
(setq org-archive-location "archive/%s_archive::")
(setq org-agenda-files (filter (lambda (fn)
                                 (not (string-match (rx "#") fn)))
                               (file-expand-wildcards org-directory)))

Capture Templates

Hit C-c c to trigger these:

(defun jm/find-org-headline (&optional heading)
  "Prompts for and finds a heading.

Adapted from URL `http://emacs.stackexchange.com/a/5931'."
  (let* ((target (save-excursion
                   (org-refile-get-location heading nil t t)))
         (file (nth 1 target))
         (pos (nth 3 target)))
    (with-current-buffer (find-file-noselect org-notes-file)
      (goto-char pos)
      (org-end-of-subtree)
      (org-return))))

(setq org-capture-templates
      '(("t" "TODO" entry (file+headline org-default-notes-file "Tasks")
         "* TODO %^{Task} %^g \n%U \n%?")
        ("w" "Work Journal" entry (file+datetree org-work-journal-file)
         "* %^{Title}\n%U \n%?\n")
        ("j" "Journal" entry (file+datetree org-journal-file)
         "* %^{Title}\n%U \n%?\n")
        ("n" "Notes" entry (file+function org-notes-file jm/find-org-headline)
         "* %^{Title}\n%U \n%?"
         :empty-lines 1)
        ("d" "Appointment" entry (file+headline org-default-notes-file "Tasks")
          "* TODO %^{Description} %^g\n%?\nSCHEDULED: %t\n%i\n%a")
        ("l" "Log" entry (file+datetree+prompt org-log-file)
         "* %^{Task} %^g\n%?" :clock-in t :clock-resume t)
        ))

Skeleton

(define-skeleton orgmode-skeleton
  "Inserts orgmode defaults into the current buffer."
  "Title: "
  "#+TITLE:       " str | (file-name-nondirectory buffer-file-name) \n
  "#+DESCRIPTION: " (skeleton-read "Description: ") \n
  "#+STARTUP:     align hidestars indent lognotedone" \n
  \n _)

Keybindings

(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c c") 'org-capture)
(global-set-key (kbd "C-c b") 'org-iswitchb)
;; for terminals -- TAB does not work
(global-set-key (kbd "C-x t") 'org-cycle)
(global-set-key (kbd "C-c C-x h") 'org-html-export-to-html)

Babel

Include these languages for babel

(org-babel-do-load-languages
 'org-babel-load-languages (mapcar (lambda (l) (cons l t))
        '(C calc emacs-lisp gnuplot latex ledger perl python ruby screen sh)))

Highlight src blocks

(setq org-src-fontify-natively t)
(defun jm/org-confirm-babel-evaluate (lang body)
  "Don't ask to confirm evaluating a ledger block."
  (not (string= lang "ledger")))
(setq org-confirm-babel-evaluate 'jm/org-confirm-babel-evaluate)

Diary/Agenda

Hide some holidays:

(setq holiday-bahai-holidays nil)
(setq holiday-hebrew-holidays nil)
(setq holiday-islamic-holidays nil)

Show the agenda from the current day:

(setq org-agenda-start-on-weekday nil)

Show all habits

(setq org-habit-show-habits-only-for-today nil)

Set the location for showing the sunrise/sunset in the agenda:

(setq calendar-latitude 47.9790)
(setq calendar-longitude -122.2021)
(setq calendar-location-name "Everett, WA")

Exporting

Remove “Valid XHTML” link

(setq org-export-html-validation-link nil)

Minted latex export

(setq org-export-latex-minted-options
      '(("fontsize" "\\scriptsize")))

Perl

Use the more modern cperl-mode

(defalias 'perl-mode 'cperl-mode)

Use cperl-mode for .t tests

(associate-file-type '(".t") 'cperl-mode)

Use four-space indents

(setq cperl-indent-level 4)

Indent only four-spaces in broken-up calls like

someCall(
    $var,
    $var2
)
(setq cperl-indent-parens-as-block t)
(setq cperl-close-paren-offset -4)

Fix indentation for lines not starting statements (e.g., hash members)

(setq cperl-continued-statement-offset 0)

R

(associate-file-type '(".R" ".r") 'r-mode)
(autoload 'r-mode "ess-site" nil t)

Don’t be so slow at evaluating buffers:

(setq ess-eval-visibly-p nil)

Ruby

Running

Shortcut for running a script and returning focus to it:

(defun ruby-run-buffer ()
  "Run the current Ruby script and switch focus back to the script."
  (interactive)
  (ruby-compilation-this-buffer)
  (other-window -1))

Filetypes

(associate-file-type '(".rake" "Gemfile" "Rakefile" ".ru" "Capfile" "Guardfile") 'ruby-mode)

Turn on rdoc-mode:

(autoload 'rdoc-mode "rdoc-mode" "Major mode for rdoc files" t)
(associate-file-type '(".rdoc" ".rd") 'rdoc-mode)

Hooks

(add-hook 'ruby-mode-hook
          (lambda ()
            (rspec-mode 1)
            ; for binding.pry to work -- hit C-x C-q at breakpoint
            (add-hook 'after-init-hook 'inf-ruby-switch-setup)
            (autoload 'ri "ri")
            (local-set-key (kbd "C-c , x") 'rspec-verify-single)
            (local-set-key (kbd "C-h r") 'yari)
            (local-set-key (kbd "C-c C-c") 'ruby-run-buffer)))
(add-hook 'slim-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c , r") 'rspec-rerun)))

RSpec

(setq rspec-use-rake-when-possible nil)
(setq rspec-use-spring-when-possible t)

Scheme

Variables

(setq scheme-program-name "scheme")

Helper functions

(defun scheme-run-buffer ()
  "Runs the current buffer through scheme and switches focus back to the script."
  (interactive)
  (scheme-send-region (point-min) (point-max)))

Hooks

(add-hook 'scheme-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c C-c") 'scheme-run-buffer)
            (local-set-key (kbd "C-j") 'scheme-send-last-sexp)))

Tools

Browsers

There are far too many ways to configure which browser to use in emacs. xdg-open should be the default but alas, we need this:

(setq shr-external-browser 'browse-url-xdg-open)
(setq browse-url-browser-function 'browse-url-generic
      browse-url-generic-program "chromium-browser")

Clock

Customize M-x display-time-world:

(setq display-time-world-list
      '(("America/Los_Angeles" "Seattle")
        ("America/Denver" "Cascade")
        ("America/Chicago" "Ann Arbor")
        ("America/New_York" "New York")))

Dired

Make it so hitting C on a filename in a dired window defaults to the other dired window:

(setq dired-dwim-target t)

Ledger

Add a few custom reports:

(require 'ledger-mode)

(add-to-list
 'ledger-reports
 '("taxes" "ledger -f %(ledger-file) bal --cleared Liabilities:Taxes Savings:Taxes"))

(add-to-list
 'ledger-reports
 '("donations" "ledger -f %(ledger-file) bal Expenses:Donations Liabilities:Donations"))

(add-to-list
 'ledger-reports
 '("biz-income" "ledger -f %(ledger-file) equity --cleared Biz:Income"))

(add-to-list
 'ledger-reports
 '("biz-outstanding" "ledger -f %(ledger-file) reg Biz:AccountsReceivable"))

(add-to-list
 'ledger-reports
 '("year-spending" "ledger -f %(ledger-file) --monthly --empty --collapse reg Expenses"))

(add-to-list
 'ledger-reports
 '("uncleared" "ledger -f %(ledger-file) reg --uncleared"))

(add-to-list
 'ledger-reports
 '("cc-spending" "ledger -f %(ledger-file) bal Liabilities:Credit -l 'amount < 0'"))

(add-to-list
 'ledger-reports
 '("credit-cap1"
   "ledger -f %(ledger-file) reg Liabilities:Credit:CapitalOne --display 'd>=[last month]' --cleared"))

(add-to-list
 'ledger-reports
 '("checking-cap1"
   "ledger -f %(ledger-file) reg Assets:Checking:CapitalOne --display 'd>=[last month]' --cleared"))

(add-to-list
 'ledger-reports
 '("net" "ledger -f %(ledger-file) bal Assets Liabilities --cleared"))

Man

Open man pages in a different window

(setq Man-notify-method 'friendly)

I tend to keep man pages pretty narrow

(setenv "MANWIDTH" "72")

Shell

Set $PAGER to cat to avoid WARNING: terminal is not fully functional messages.

(setenv "PAGER" "cat")

Ensure eshell garbage stays in ~/.emacs.d/local:

(setq eshell-directory-name (concat user-emacs-directory "local/eshell"))

Silver Searcher

(require 'ag)
(setq ag-highlight-search t)

Local configuration

Load local config to override any of the above settings

(load (jm/local-path "local") 'noerror)