#+TITLE: Emacs Configuration for Alan Pearce
#+OPTIONS: ^:nil
#+PROPERTY: results silent
#+PROPERTY: eval no-export
#+PROPERTY: header-args :comments link
* Introduction
This is a living document, detailing my Emacs configuration using org-mode
* Basics
** Startup
Open Emacs with just a plain window.  No graphics or messages, please!
#+BEGIN_SRC emacs-lisp
(put 'inhibit-startup-echo-area-message 'saved-value
     (setq inhibit-startup-echo-area-message (user-login-name)))
(setq inhibit-startup-screen t)
(setq gc-cons-threshold 100000000)
(defvar file-name-handler-alist-backup file-name-handler-alist)
(setq file-name-handler-alist nil)
(remove-hook 'find-file-hooks #'vc-refresh-state)
#+END_SRC

** Compatibility

#+BEGIN_SRC emacs-lisp
(if (version< emacs-version "25.0")
    (defmacro with-eval-after-load (file &rest body)
      `(eval-after-load ,file (lambda () ,@body))))
#+END_SRC

** Scratch buffers
I usually use scratch buffers for any sort of text.  If I need a
programming mode in one, then I’ll just call it manually.  I also like
the buffer to be empty.
#+BEGIN_SRC emacs-lisp
(setq initial-scratch-message ""
      initial-major-mode 'text-mode)
#+END_SRC

** Personal Information
#+BEGIN_SRC emacs-lisp
(setq user-mail-address "alan@alanpearce.co.uk"
      user-full-name "Alan Pearce")
#+end_src

* Packaging

** Use-package

#+BEGIN_SRC emacs-lisp
(eval-and-compile
  (setq tls-checktrust t
        gnutls-verify-error t
        package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
                           ("melpa-stable" . "https://stable.melpa.org/packages/")
                           ("melpa" . "https://melpa.org/packages/"))
        package-user-dir (concat "~/.emacs.d/packages/" emacs-version "/elpa")
        package-pinned-packages '(("use-package" . melpa-stable)
                                  ("diminish" . melpa-stable)
                                  ("bind-key" . melpa-stable))
        package-archive-priorities '(("melpa-stable" . 10)
                                     ("gnu" . 10)
                                     ("marmalade" . 5)
                                     ("melpa" . 0))
        package-menu-async t
        package-menu-hide-low-priority t)
  (package-initialize)
  (unless (package-installed-p 'use-package)
    (package-refresh-contents)
    (package-install 'use-package)))
(eval-when-compile (require 'use-package))
(unless (featurep 'use-package)
  (require 'diminish)
  (require 'bind-key)
  (use-package use-package
    :commands (use-package-autoload-keymap)
    :defer 5))
(setq use-package-verbose t
      use-package-always-ensure t
      package-enable-at-startup nil)
#+END_SRC

* Customize
I don’t really like using customize for normal configuration.
Instead, I use it for things that get saved automatically.  That’s why
I use a different file, which is ignored by the VCS.  It also means
that it’s not important whether the file exists or not, which is why I
pass =:noerror= to =load=

#+BEGIN_SRC emacs-lisp
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file :noerror :nomessage)
#+END_SRC

* Styles

I prefer an always-visible cursor.  Feels less distracting.
#+BEGIN_SRC emacs-lisp
(when (fboundp #'blink-cursor-mode)
  (blink-cursor-mode -1))
#+END_SRC

Disable all the bars, unless on OSX, in which case, keep the menu bar.

#+BEGIN_SRC emacs-lisp
(when (and menu-bar-mode (not (eq window-system 'ns)))
  (menu-bar-mode -1))
(with-eval-after-load 'scroll-bar
  (set-scroll-bar-mode nil))
(with-eval-after-load 'tooltip
  (tooltip-mode -1))
(with-eval-after-load 'tool-bar
  (tool-bar-mode -1))
#+END_SRC

Ring the bell sometimes, but not so often
#+BEGIN_SRC emacs-lisp
(setq ring-bell-function
      (lambda ()
        (unless (memq this-command
                      '(isearch-abort abort-recursive-edit exit-minibuffer keyboard-quit undo-tree-undo))
          (ding))))
#+END_SRC

** Colours

Let’s try a more minimal theme.

#+BEGIN_SRC emacs-lisp
(use-package minimal-theme
  :disabled t
  :config (progn
            (load-theme 'minimal-light t)))
#+END_SRC

Let’s try a basic theme.

#+BEGIN_SRC emacs-lisp
(use-package basic-theme
  :if (display-graphic-p)
  :config (progn
            (load-theme 'basic t)

            (set-face-background 'mode-line "#a1b56c")
            (set-face-background 'border "#a1b56c")
            (set-face-foreground 'border "#a1b56c")
            (set-face-background 'vertical-border "#a1b56c")
            (set-face-foreground 'vertical-border "#a1b56c")
            (set-face-background 'window-divider "#a1b56c")
            (set-face-foreground 'window-divider "#a1b56c")

            (defvar mode-line-default-format mode-line-format)
            (defvar mode-line-default-hidden nil
              "Whether to hide the mode line by default")

            (defun show-mode-line ()
              (interactive)
              (setq mode-line-format mode-line-default-format)
              (when (called-interactively-p 'interactive)
                (setq-default mode-line-format mode-line-default-format)
                (setq mode-line-default-hidden nil)))
            (defun hide-mode-line ()
              (interactive)
              (setq mode-line-format nil)
              (when (called-interactively-p 'interactive)
                (setq-default mode-line-format nil)
                (setq mode-line-default-hidden t)))

            (setq-default cursor-type '(bar . 1))
            (setq-default cursor-in-non-selected-windows nil)

            (defun hide-clutter ()
              (interactive)
              (fringe-mode '(0 . 4))
              (hide-mode-line))

            (defun show-clutter ()
              (interactive)
              (fringe-mode '(8 . 4))
              (show-mode-line))
            (hide-clutter)

            (when mode-line-default-hidden
              (call-interactively #'hide-mode-line))

            (defun hide-mode-line-if-default-hidden ()
              (if mode-line-default-hidden
                  (hide-mode-line)
                (show-mode-line)))

            (add-to-list 'default-frame-alist '(border-width . 0))
            (add-to-list 'default-frame-alist '(internal-border-width . 1))
            (when (eq window-system 'x)
              (setq window-divider-default-bottom-width 1
                    window-divider-default-right-width 1
                    window-divider-default-places t)
              (setq mode-line-default-hidden t)
              (window-divider-mode +1))

            (add-hook 'after-change-major-mode-hook #'hide-mode-line-if-default-hidden)

            (add-hook 'minibuffer-setup-hook #'show-mode-line)
            (add-hook 'minibuffer-exit-hook #'hide-mode-line)))
#+END_SRC

Highlighting quasi-quoted expressions in lisps is quite useful, but I
don't need it all the time.  I'll keep it around for a while so that I
can enable it if needed.
#+BEGIN_SRC emacs-lisp
(use-package highlight-stages
  :diminish highlight-stages-mode)
#+END_SRC

** Fonts

When possible, set up fonts.  I don’t have any settings here for X11,
because I manage those in my [[file:~/projects/dotfiles/tag-xresources/xresources/main][XResources file]].
#+BEGIN_SRC emacs-lisp
(when (or (display-graphic-p)
          (daemonp))

  (defun use-variable-fonts ()
    (interactive)
    (variable-pitch-mode)
    (setq cursor-type 'bar))

  (defun ap/set-fonts (mono-face mono-font-size variable-face variable-font-size antialias)
    (if (boundp 'ns-antialias-text)
      (setq ns-antialias-text antialias))
    (when mono-face
      (let ((default-font (font-spec :family mono-face :size  mono-font-size)))
        (add-to-list 'default-frame-alist `(font . ,(format "%s %s" mono-face mono-font-size)))
        (set-face-font 'fixed-pitch default-font)
        (set-frame-font default-font t t)))
    (when variable-face
      (set-face-font 'variable-pitch (font-spec :name variable-face :size variable-font-size))))

  (defun ap/set-fonts-according-to-system ()
    (interactive)
    (cond
     ((eq window-system 'w32)
      (ap/set-fonts "Liberation Mono" 11 "Segoe UI" 11 t))
     ((eq window-system 'ns)
      (let ((displays (string-to-number (shell-command-to-string "system_profiler SPDisplaysDataType | grep \"Online: Yes\" | wc -l"))))
        (if (eq displays 1)
            (ap/set-fonts "Roboto Mono" 13 "Lucida Grande" 13 t)
          (ap/set-fonts "Monaco" 10 "Lucida Grande" 12 nil))))
     ((eq window-system 'x)
      (set-fontset-font "fontset-default" 'unicode (font-spec :name "Terminus" :size 8))
      (ap/set-fonts "Fixed" 8 "Lucida" 8 nil))))

  (ap/set-fonts-according-to-system))
#+END_SRC

Reduce font decoration.  I’m trying to see whether this helps me focus
on the right things.
#+BEGIN_SRC emacs-lisp
(setq font-lock-maximum-decoration '((dired-mode . 1)
                                     (t . 1)))
#+END_SRC

** Page Breaks

By default, Emacs displays page breaks as ^L.  Lines look much nicer.
On Windows, Emacs incorrectly detects that U+2500 (Box Drawings Light
Horizontal) can only be displayed with a different font, which is not
correct, at least for Liberation Mono.

#+BEGIN_SRC emacs-lisp
(use-package page-break-lines
  :defer 5
  :diminish page-break-lines-mode
  :config (progn
            (global-page-break-lines-mode)
            (unless (eq (char-displayable-p ?─) (char-displayable-p ?a))
              (set-fontset-font "fontset-default"
                                (cons page-break-lines-char page-break-lines-char)
                                (face-attribute 'default :family)))))
#+END_SRC
** Modeline

#+BEGIN_SRC emacs-lisp
(column-number-mode t)
(size-indication-mode t)

(setq frame-title-format '("%f" (dired-directory dired-directory)))
#+END_SRC

** Highlight Changes

Highlight what just changed when I undo, yank, and so on.

#+BEGIN_SRC emacs-lisp
(use-package volatile-highlights
  :diminish volatile-highlights-mode
  :config (progn
            (volatile-highlights-mode t)))
#+END_SRC

** Beacon

I was against the idea of having flashy animations inside Emacs, but
this one is useful.  It highlights the cursor when scrolling or
switching windows.

#+BEGIN_SRC emacs-lisp
(use-package beacon
  :diminish beacon-mode
  :config (progn
            (beacon-mode +1)
            (setq beacon-blink-delay 0.25
                  beacon-blink-duration 0.25
                  beacon-size 20
                  beacon-color "#a1b56c")))
#+END_SRC

** Renaming major modes

Diminishing major modes does not happen in the same manner as minor
modes.

#+BEGIN_SRC emacs-lisp
(unless (version<= emacs-version "24.4")
  (use-package cyphejor
    :defer 2
    :config (progn
              (setq cyphejor-rules `(("emacs"       "ε")
                                     ("diff"        "Δ")
                                     ("js2"         "js")
                                     ("magit-status" ,(char-to-string (seq-find #'char-displayable-p '(11942 5848 177))))
                                     ("inferior"    "i" :prefix)
                                     ("interaction" "i" :prefix)
                                     ("interactive" "i" :prefix)
                                     ("menu"        "▤" :postfix)
                                     ("ledger"      "Ledger")
                                     ("mode"        "")
                                     ("shell"       "sh" :postfix)))
              (cyphejor-mode 1))))
#+END_SRC


* Environment Variables

MacOS doesn’t have a reasonable way to set environment variables and
read them automatically any more.  So, let’s use the
[[https://github.com/purcell/exec-path-from-shell][exec-path-from-shell]] package to set up ~exec-path~ and similar
variables from whatever my shell configuration is.

#+BEGIN_SRC emacs-lisp
(use-package exec-path-from-shell
  :if (eq system-type 'darwin)
  :config (exec-path-from-shell-initialize))
#+END_SRC

* Keybindings

I think =set-keyboard-coding-system= stops OS X from doing something
annoying to add accents.  The modifier setup is to match my
re-arrangement of modifiers on OSX: Cmd on the outside, then
Option/alt, then Control.

#+BEGIN_SRC emacs-lisp
(when (eq system-type 'darwin)
  (set-keyboard-coding-system nil)
  (custom-set-variables
   '(mac-option-modifier 'meta)
   '(mac-right-option-modifier 'none)
   '(mac-control-modifier 'control)
   '(mac-right-control-modifier 'left)
   '(mac-command-modifier 'super)
   '(mac-right-command-modifier 'left)
   '(mac-function-modifier 'hyper))
  (unbind-key "s-x"))
#+END_SRC

#+BEGIN_SRC emacs-lisp
(unbind-key "<f4>")
(bind-key* "<f5>" #'compile)
(bind-key* "<f6>" #'kmacro-start-macro-or-insert-counter)
(bind-key* "<f7>" #'kmacro-end-or-call-macro)

(bind-key* "<apps>" #'execute-extended-command)

(unbind-key "C-z")
(bind-key* "C-<tab>" #'other-window)

(bind-key* "C-x C-r" #'revert-buffer)
(bind-key* "C-x C-j" #'delete-indentation)
(unbind-key "C-x C-c")

(bind-key* "C-c i" #'insert-char)
(bind-key* "M-/" #'hippie-expand)

(unbind-key "s-h")
(unbind-key "s-n")
(unbind-key "s-p")
(unbind-key "s-w")
(bind-key* "s-k" #'kill-or-delete-this-buffer-dwim)

(bind-key "C-M-a" #'backward-paragraph text-mode-map)
(bind-key "C-M-e" #'forward-paragraph text-mode-map)

(bind-key* "s-x" (define-prefix-command 'super-x-map))
(bind-key* "s-," #'switch-to-dotfiles)
(bind-key* "C-M-x" #'execute-extended-command)
(set-register ?z `(file . ,(expand-file-name ".config/zsh/zshrc" "~")))
#+END_SRC

** Crux

I can replace most of the simple helper/wrapper functions in my
configuration with crux.el

#+BEGIN_SRC emacs-lisp
(use-package crux
  :bind (("M-o" . crux-smart-open-line-above)
         ("C-o" . crux-smart-open-line)

         ("C-x 4 t" . crux-transpose-windows)
         ("C-c e" . crux-eval-and-replace)
         ("C-c D" . crux-delete-file-and-buffer)
         ("C-c R" . crux-rename-file-and-buffer))
  :init (progn
          (defalias 'delete-current-buffer-file #'crux-delete-file-and-buffer)
          (defalias 'rename-current-buffer-file #'crux-rename-file-and-buffer)))
#+END_SRC

* Projects

#+BEGIN_SRC emacs-lisp
(defvar projects-root-directory "~/projects")
#+END_SRC

#+BEGIN_SRC emacs-lisp
(defun switch-to-dotfiles ()
  (interactive)
  (projectile-switch-project-by-name (expand-file-name "~/projects/git.alanpearce.uk/alan/dotfiles/")))
#+END_SRC

** The Silver Searcher

#+BEGIN_SRC emacs-lisp
(use-package ag
  :defer 30
  :config (setq ag-project-root-function #'projectile-project-root))

(use-package wgrep-ag
  :after ag)
#+END_SRC

** Ripgrep

Step over Silver Search, here comes a new challenger.

#+BEGIN_SRC emacs-lisp
(use-package ripgrep
  :if (executable-find "rg"))

(use-package projectile-ripgrep
  :after (ripgrep projectile)
  :if (executable-find "rg")
  :bind (("C-c p s r" . projectile-ripgrep)))
#+END_SRC

** Projectile

Projectile is awesome for working in projects, especially VCS-backed
ones.  I added a couple of functions to allow me to open new projects
based upon some folder conventions I use.

#+BEGIN_SRC emacs-lisp
(use-package projectile
  :bind (("s-p" . projectile-switch-project)
         ("C-c C-f" . projectile-find-file)
         ("s-x s-f" . projectile-find-file)
         ("C-x g" . projectile-vc)
         ("s-G"   . projectile-vc))
  :demand t
  :diminish projectile-mode
  :config (progn
            (projectile-global-mode)
            (add-to-list 'projectile-globally-ignored-directories ".stversions")

            (defun directory-directories (dir)
              (seq-filter #'file-directory-p
                          (directory-files dir t (rx string-start
                                                     (char alnum)))))

            (defun project-directories (start-dir)
              (seq-map (lambda (x) (file-relative-name x start-dir))
                       (seq-mapcat #'directory-directories
                                   (seq-mapcat #'directory-directories
                                               (directory-directories start-dir)))))

            (defun ap/open-subfolder-project (from-dir &optional arg)
              (let ((project-dir (projectile-completing-read "Open project: "
                                                             (project-directories from-dir))))
                (projectile-switch-project-by-name (expand-file-name project-dir from-dir) arg)))

            (defun yarn-install (&optional arg)
              (interactive "P")
              (projectile-with-default-dir (projectile-project-root)
                (cmd-to-echo "yarn" "install")))

            (defun yarn-add-dev (package)
              (interactive "spackage: ")
              (projectile-with-default-dir (projectile-project-root)
                (cmd-to-echo "yarn" (concat "add --dev " package))))

            (defun yarn-add (package)
              (interactive "spackage: ")
              (projectile-with-default-dir (projectile-project-root)
                (cmd-to-echo "yarn" (concat "add " package))))

            (defun yarn-run (cmd)
              (interactive "scommand: ")
              (projectile-with-default-dir (projectile-project-root)
                (cmd-to-echo "yarn" (concat "run " cmd))))

            (defun ap/open-project (&optional arg)
              (interactive "P")
              (ap/open-subfolder-project projects-root-directory arg))

            (setq projectile-switch-project-action #'projectile-commander
                  projectile-completion-system 'ivy)))
#+END_SRC

** vc

This is nice for some things that magit doesn’t do, and for those rare
occasions that I’m working with something other than git.

#+BEGIN_SRC emacs-lisp
(use-package vc
  :defer t
  :bind (("C-x v C" . vc-resolve-conflicts))
  :config (progn
            (setq vc-follow-symlinks t)
            (setq vc-ignore-dir-regexp (format "\\(%s\\)\\|\\(%s\\)"
                                               vc-ignore-dir-regexp
                                               tramp-file-name-regexp))))
#+END_SRC

** git-gutter-fringe

It’s nice to be able to see at a glance which lines of a file have
changed.  This package colours the fringe.  I have it set to the right
fringe so it doesn’t interfere with flycheck.

#+BEGIN_SRC emacs-lisp
(use-package git-gutter-fringe
  :defer 2
  :diminish git-gutter-mode
  :config (progn
            (global-git-gutter-mode 1)
            (set-face-foreground 'git-gutter:modified "grey")
            (setq git-gutter-fr:side 'right-fringe)))
#+END_SRC

** magit

Magit is my favourite way to use git.  I use selective staging all the
time.  Make sure to set it up with a nice =completing-read-function=

#+BEGIN_SRC emacs-lisp
(use-package magit
  :defer 5
  :commands (magit-status)
  :config (progn (setq magit-completing-read-function #'ivy-completing-read
                       magit-popup-use-prefix-argument 'default
                       magit-display-buffer-function #'magit-display-buffer-fullcolumn-most-v1
                       global-magit-file-mode nil)
                 (add-to-list 'magit-no-confirm 'safe-with-wip))
  :init (add-hook 'magit-mode-hook #'magit-load-config-extensions))
#+END_SRC

** git-timemachine

This package allow me to go through a file’s history with just a few
keys.  It makes it very easy to figure what what exactly was in a file
in the past.  I often find it useful when I remember writing something
a particular way, but it changed later.

#+BEGIN_SRC emacs-lisp
(use-package git-timemachine
  :commands git-timemachine)
#+END_SRC

* Files

** Auto-saving

Auto-save everything to a temporary directory, instead of cluttering
the filesystem.  I don’t want emacs-specific lockfiles, either.

#+BEGIN_SRC emacs-lisp
(setq auto-save-file-name-transforms `((".*" ,temporary-file-directory t))
      create-lockfiles nil)
#+END_SRC
** Backups

I like to keep my backups out of regular folders.  I tell emacs to use
a subfolder of its configuration directory for that.  Also, use the
trash for deleting on OS X.
#+BEGIN_SRC emacs-lisp
(let ((backup-dir (expand-file-name "~/.emacs.d/backups/")))
  (unless (file-directory-p backup-dir)
    (make-directory backup-dir))
  (setq backup-directory-alist `((".*" . ,backup-dir))
        backup-by-copying-when-linked t
        backup-by-copying-when-mismatch t))
(if (eq system-type 'darwin)
    (setq delete-by-moving-to-trash t)
  (if (and (executable-find "trash") (not (fboundp #'system-move-file-to-trash)))
      (defun system-move-file-to-trash (file)
        (call-process (executable-find "trash")
                      nil 0 nil
                      file))))
#+END_SRC

** autorevert

#+BEGIN_SRC emacs-lisp
(use-package autorevert
  :diminish auto-revert-mode
  :init (progn
          (global-auto-revert-mode 1)
          (setq auto-revert-verbose nil
                auto-revert-use-notify (not (eq system-type 'darwin)))))
#+END_SRC

** Encoding

UTF-8 is usually appropriate.  Note that =prefer-coding-system= expects
only a coding system, not a coding system and line ending combination.

#+BEGIN_SRC emacs-lisp
(prefer-coding-system 'utf-8)
(setq-default buffer-file-coding-system 'utf-8-auto-unix)
#+END_SRC

** Buffer-file management

Ask if I want to create a directory when it doesn’t exist.  This is
especially nice when starting new projects.

#+BEGIN_SRC emacs-lisp
(defun my-create-non-existent-directory ()
  (let ((parent-directory (file-name-directory buffer-file-name)))
    (when (and (not (file-exists-p parent-directory))
               (y-or-n-p (format "Directory `%s' does not exist!  Create it?" parent-directory)))
      (make-directory parent-directory t))))
(add-to-list 'find-file-not-found-functions #'my-create-non-existent-directory)
#+END_SRC

I often want to rename or delete the file that I’m currently visiting
with a buffer.

#+BEGIN_SRC emacs-lisp
(defun kill-or-delete-this-buffer-dwim (&optional arg)
  "Kills current buffer.  With prefix arg, delete it."
  (interactive "P")
  (if (equal arg '(4))
      (delete-current-buffer-file)
    (if server-buffer-clients
        (server-edit)
      (let ((buf (buffer-name)))
        (when (equal buf "*HTTP Response*")
          (other-window 1))
        (kill-buffer buf)))))
#+END_SRC

** Whitespace Butler

I don’t like it when editors change an entire file’s layout when I
open it.  Whitespace butler fixes whitespace only for lines that I’m editing.

#+BEGIN_SRC emacs-lisp
(use-package ws-butler
  :if window-system
  :diminish ws-butler-mode
  :config (ws-butler-global-mode 1))
(if (daemonp)
    (add-hook 'before-make-frame-hook (lambda ()
                                        (use-package ws-butler
                                          :config (ws-butler-global-mode 1)))))
#+END_SRC

** shrink-whitespace

DWIM whitespace removal.  So I don’t need =M-SPC=, =M-\= and =C-x o=
for similar things any more.

#+BEGIN_SRC emacs-lisp
(use-package shrink-whitespace
  :bind ("M-SPC" . shrink-whitespace))
#+END_SRC

** Tramp

Tramp is awesome.  It makes SSH feel Unix-y.  The proxy setup is so
that I can sudo on remote machines

#+BEGIN_SRC emacs-lisp
(use-package tramp
  :defer 7
  :config (progn
            (unless (getenv "SSH_AUTH_SOCK")
              (setenv "SSH_AUTH_SOCK" (format "/run/user/%s/ssh-agent" (user-uid))))
            (setq tramp-default-method "ssh"
                  tramp-default-user-alist '(("\\`su\\(do\\)?\\'" nil "root"))
                  tramp-backup-directory-alist backup-directory-alist
                  tramp-completion-reread-directory-timeout 60
                  tramp-ssh-controlmaster-options nil
                  backup-enable-predicate (lambda (name)
                                            (and (normal-backup-enable-predicate name)
                                                 (not (let ((method (file-remote-p name 'method)))
                                                        (when (stringp method)
                                                          (member method '("su" "sudo")))))))
                  tramp-shell-prompt-pattern "\\(?:^\\|
\\)[^]#$%>\n]*#?[]#$%>❯›] *\\(\\[\\??[0-9;]*[a-zA-Z] *\\)*")
            (add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" (concat "/" tramp-default-method ":%h:")))
            (add-to-list 'tramp-default-proxies-alist `(,(regexp-quote (system-name)) nil nil))
            (add-to-list 'tramp-default-proxies-alist '("localhost" nil nil))))

(use-package tramp-sh
  :ensure nil
  :defer t
  :config (progn
            (add-to-list 'tramp-remote-path "/usr/local/sbin")
            (add-to-list 'tramp-remote-path "~/bin")))
#+END_SRC

** ediff

I like a horizonal diff setup, with everything in one frame.

#+BEGIN_SRC emacs-lisp
(use-package ediff
  :defer t
  :config (progn
            (setq ediff-split-window-function 'split-window-horizontally
                  ediff-window-setup-function 'ediff-setup-windows-plain)))
#+END_SRC

* Indentation

Ah, a complicated topic.  One day we’ll all be using elastic
tabstops.  I’ve recently switched to using two spaces, since elastic
tabstops is probably never going to happen.

#+BEGIN_SRC emacs-lisp
(setq-default tab-width 2
              indent-tabs-mode nil)
#+END_SRC


** smart-tabs-mode

Not related to [[smart-tab][=smart-tab=]], this mode indents with tabs and aligns
with spaces.  Perfect!

#+BEGIN_SRC emacs-lisp
(use-package smart-tabs-mode
  :defer 1
  :config (progn
            (smart-tabs-insinuate 'c 'cperl 'python)
            (add-hook 'php-mode-hook (lambda ()
                                       (smart-tabs-mode indent-tabs-mode)))))
#+END_SRC

** editorconfig

#+BEGIN_SRC emacs-lisp
(use-package editorconfig
  :config (editorconfig-mode 1))
#+END_SRC

** dtrt-indent-mode

Sometimes people use different indentation settings.  [[https://github.com/jscheid/dtrt-indent][dtrt-indent]]
guesses the correct settings for me.

#+BEGIN_SRC emacs-lisp
(use-package dtrt-indent
  :config (progn
            (defun ap/dtrt-adapt-if-needed ()
              (unless editorconfig-mode
                (dtrt-indent-adapt)))
            (if (fboundp #'editorconfig-mode)
                (add-hook 'after-change-major-mode-hook #'ap/dtrt-adapt-if-needed)
              (add-hook 'after-change-major-mode-hook #'dtrt-indent-adapt))
            (defadvice dtrt-indent-try-set-offset (after toggle-smart-tabs activate)
              (smart-tabs-mode (or indent-tabs-mode -1)))))
#+END_SRC

* Security

** password-store

This is a frontend to the GPG-powered =pass= program.
#+BEGIN_SRC emacs-lisp
(use-package password-store
  :defer 15
  :config (progn
            (setq password-store-password-length 16)))
#+END_SRC
* Buffers

** Ibuffer
Ibuffer is quite nice for listing all buffers.

#+BEGIN_SRC emacs-lisp
(use-package ibuffer
  :bind (("C-x C-b" . ibuffer))
  :config (progn
            (setq ibuffer-saved-filter-groups
                  (quote (("default"
                           ("org" (mode . org-mode))
                           ("emacs" (mode . emacs-lisp-mode))
                           ("zsh" (filename . "/zsh"))
                           ("server" (filename . "/su:root@server"))))))

            ;; Human-readable base-2 size column
            (define-ibuffer-column size-h
              (:name "Size" :inline t)
              (cond
               ((> (buffer-size) 1024)
                (format "%7.2fK" (/ (buffer-size) 1024.0)))
               ((> (buffer-size) 1048576)
                (format "%7.2fM" (/ (buffer-size) 1048576.0)))
               (t
                (format "%8d" (buffer-size)))))

            (setq ibuffer-formats
                  '((mark modified read-only " "
                          (name 18 18 :left :elide)
                          " "
                          (size-h 9 -1 :right)
                          " "
                          (mode 16 16 :left :elide)
                          " "
                          filename-and-process)))))
#+END_SRC

** Relative Buffer names

#+BEGIN_SRC emacs-lisp
(use-package relative-buffers
  :defer 15
  :config (progn
            (global-relative-buffers-mode)))
#+END_SRC
** Narrowing

Enable it without prompting

#+BEGIN_SRC emacs-lisp
(put 'narrow-to-defun  'disabled nil)
(put 'narrow-to-page   'disabled nil)
(put 'narrow-to-region 'disabled nil)
#+END_SRC

** ace-window

I don’t often have many windows open at once, but when I do,
=ace-window= is really nice to jump around them in the same way that
=ace-jump= or =avy= work.
#+BEGIN_SRC emacs-lisp
(use-package ace-window
  :bind (("s-s" . ace-window))
  :config (progn
            (setq aw-dispatch-always t
                  aw-dispatch-alist '((?k aw-delete-window " Ace - Delete Window")
                                      (?K aw-delete-window)
                                      (?m aw-swap-window " Ace - Swap Window")
                                      (?f aw-flip-window)
                                      (?v aw-split-window-vert " Ace - Split Vert Window")
                                      (?b aw-split-window-horz " Ace - Split Horz Window")
                                      (?m delete-other-windows " Ace - Maximize Window")
                                      (?l delete-other-windows)
                                      (?, winner-undo)
                                      (?. winner-redo))
                  aw-keys '(?a ?r ?s ?t ?n ?e ?i ?o))))
#+END_SRC

* Windows

Scrolling is tricky.  I use this setup to help me keep track of the
point whilst I’m moving about.

#+BEGIN_SRC emacs-lisp
(setq scroll-conservatively 100
      scroll-margin 1
      scroll-preserve-screen-position t
      mouse-wheel-scroll-amount '(1 ((shift) . 1) ((control)))
      split-height-threshold 80
      split-width-threshold 160
      frame-resize-pixelwise nil)
(if (boundp 'ns-pop-up-frames)
    (setq ns-pop-up-frames nil))
#+END_SRC

** winner

Undo, for window-based commands.

#+BEGIN_SRC emacs-lisp
(use-package winner
  :config (setq winner-boring-buffers '("*Completions*" "*Help*" "*Apropos*" "*Buffer List*" "*info*" "*Compile-Log*"))
  :init (progn
          (winner-mode 1)))
#+END_SRC

** windmove

Directional window movement

#+BEGIN_SRC emacs-lisp
(use-package windmove
  :bind (("S-<left>"  . windmove-left)
         ("S-<right>" . windmove-right)
         ("S-<up>"    . windmove-up)
         ("S-<down>"  . windmove-down)))
#+END_SRC
* Completion

Make built-in completion a bit more intelligent, by adding substring
and initial-based completion and ignoring case.

#+BEGIN_SRC emacs-lisp
(setq completion-styles '(basic initials partial-completion substring)
      completion-ignore-case t
      tab-always-indent 'complete)
#+END_SRC

** Company

The main choices for automatic completion in Emacs are company and
auto-complete-mode.  I’ve not tried auto-complete-mode as company
seems to work perfectly well for me.

#+BEGIN_SRC emacs-lisp
(use-package company
  :commands (company-mode)
  :diminish "Cmpl"
  :bind (("C-<tab>" . company-complete)
         ("TAB" . company-indent-or-complete-common))
  :init (progn
          (add-hook 'prog-mode-hook #'company-mode)
          (setq company-backends '(company-bbdb company-web-html company-tern company-nxml company-css company-eclim company-semantic company-elisp
                                                company-clang company-xcode company-cmake company-capf
                                                company-files (company-gtags
                                                               company-etags company-keywords) company-oddmuse)
                company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
                                    company-preview-frontend
                                    company-echo-metadata-frontend)
                company-idle-delay .3
                company-begin-commands '(self-insert-command)
                company-auto-complete #'company-explicit-action-p
                company-auto-complete-chars '(?\ ?\( ?\) ?.)
                company-tooltip-align-annotations t)))
#+END_SRC

#+BEGIN_SRC emacs-lisp
(use-package company-web
  :after company)
#+END_SRC

#+BEGIN_SRC emacs-lisp
(use-package company-nixos-options
  :if (eq system-type 'gnu/linux)
  :config (progn
            (add-to-list 'company-backends 'company-nixos-options)))
#+END_SRC

* Dates & Times

** Calendar

Weeks start on Monday for me and I prefer ISO-style dates.
#+BEGIN_SRC emacs-lisp
(use-package calendar
  :defer 1
  :config (progn
            (setq calendar-week-start-day 1)
            (calendar-set-date-style 'iso)))
#+END_SRC

Sometimes I want to insert a date or time into a buffer.
#+BEGIN_SRC emacs-lisp
(defun insert-date (prefix)
  "Insert the current date.  With prefix-argument, use British format.  With
     two prefix arguments, write out the day and month name."
  (interactive "P")
  (let ((format (cond
                 ((not prefix) "%Y-%m-%d")
                 ((equal prefix '(4)) "%d/%m/%Y")
                 ((equal prefix '(16)) "%A, %d %B %Y"))))
    (insert (format-time-string format))))

(defun insert-datetime (prefix)
  "Insert the current date and time."
  (interactive "P")
  (let ((format (cond
                 ((not prefix) "%Y-%m-%d %H:%M:%S")
                 ((equal prefix '(4)) "%Y-%m-%dT%H:%M:%SZ"))))
    (insert (format-time-string format))))
#+END_SRC

#+BEGIN_SRC emacs-lisp
(defun yesterday-time ()
  "Provide the date/time 24 hours before the time now in the format of current-time."
  (timer-relative-time (current-time) -86400))
#+END_SRC

* Directories

Dired works quite nicely, but not always in the way I want.  I don’t
like having so many prompts for recursive operations.  Also, when I
have two dired windows open, assume that I’m going to be
copying/moving files between them.

#+BEGIN_SRC emacs-lisp
(use-package dired
  :defer 3
  :ensure nil
  :config (progn
            (bind-key "<return>" #'dired-find-file dired-mode-map)
            (bind-key "^" (lambda () (interactive) (find-alternate-file "..")) dired-mode-map)
            (setq dired-dwim-target t
                  dired-recursive-copies 'top
                  dired-recursive-deletes 'top
                  dired-listing-switches "-alh")
            (when (and (eq system-type 'darwin) (executable-find "gls"))
              (setq insert-directory-program (executable-find "gls")))
            (put 'dired-find-alternate-file 'disabled nil)))
#+END_SRC

Don’t show uninteresting files in dired listings.

#+BEGIN_SRC emacs-lisp
(defun turn-on-dired-omit-mode ()
  (interactive)
  (dired-omit-mode 1))

(use-package dired-x
  :commands (dired-omit-mode
             dired-expunge)
  :ensure nil
  :config (progn
            (setq dired-omit-files "#\\|\\.$"
                  dired-omit-verbose nil
                  dired-find-subdir t
                  dired-bind-jump nil))
  :init (progn
          (add-hook 'dired-mode-hook #'turn-on-dired-omit-mode)))
#+END_SRC

#+BEGIN_SRC emacs-lisp
(use-package dired+
  :defer 5
  :config (progn
            (diredp-toggle-find-file-reuse-dir 1)
            (unbind-key "C-h C-m" dired-mode-map)))
#+END_SRC

Expand subfolders like a tree inside the parent

#+BEGIN_SRC emacs-lisp
(with-eval-after-load 'dired
  (use-package dired-subtree
    :functions (dired-subtree--get-ov
                dired-subtree-maybe-up)
    :init (progn
            (setq dired-subtree-use-backgrounds nil)
            (defun dired-subtree-maybe-up ()
              "Jump up one subtree or directory"
              (interactive)
              (let ((ov (dired-subtree--get-ov)))
                (if ov
                    (progn (goto-char (overlay-start ov))
                           (dired-previous-line 1))
                  (dired-up-directory))))
            (bind-key "^" #'dired-subtree-maybe-up dired-mode-map)
            (bind-key "i" #'dired-subtree-toggle dired-mode-map))))
#+END_SRC

** Dired-narrow
One can already use dired with wildcards to browse a filtered
directory listing, but it opens a new buffer.  Dired-narrow is a
slightly nicer interface: with a currently-open dired buffer, use =/=
to start filtering, =RET= to complete the filter and =g= to refresh
the buffer, removing the filter.

#+BEGIN_SRC emacs-lisp
(with-eval-after-load 'dired
  (use-package dired-narrow
    :bind (:map dired-mode-map
                ("/" . dired-narrow))))
#+END_SRC

* Documentation

** ehelp

ehelp is a less well-known package that’s part of Emacs and slightly
improves the normal help commands, mostly by making quitting them easier.

#+BEGIN_SRC emacs-lisp
(use-package ehelp
  :bind-keymap ("C-h" . ehelp-map))
#+END_SRC
** counsel-dash

Emacs’ documentation is great to read from inside Emacs.  Counsel-dash
helps to make documentation for other languages easier to access

#+BEGIN_SRC emacs-lisp
(defmacro ap/create-counsel-dash-hook (mode docsets)
  (let* ((mode-s (symbol-name mode))
         (fun (intern (concat "counsel-dash-hook-" mode-s)))
         (hook (intern (concat mode-s "-mode-hook"))))
    `(progn
       (defun ,fun ()
         (when (require 'counsel-dash nil :noerror)
           (seq-map #'counsel-dash-install-docset
             (seq-difference ',docsets
                                  (helm-dash-installed-docsets)))
           (setq-local counsel-dash-docsets ',docsets)))
       (add-hook (quote ,hook) (function ,fun)))))

(use-package counsel-dash
  :defer 20
  :defines counsel-dash-docsets
  :config (progn
            (setq counsel-dash-browser-func #'eww)
            (ap/create-counsel-dash-hook nginx ("Nginx"))
            (ap/create-counsel-dash-hook ansible ("Ansible"))
            (ap/create-counsel-dash-hook php ("PHP" "Symfony"))
            (ap/create-counsel-dash-hook twig ("Twig"))
            (ap/create-counsel-dash-hook js2 ("JavaScript" "NodeJS" "jQuery" "Express" "SailsJS" "Lo-Dash"))
            (ap/create-counsel-dash-hook markdown ("Markdown"))
            (ap/create-counsel-dash-hook saltstack ("SaltStack"))
            (ap/create-counsel-dash-hook clojure ("Clojure"))
            (ap/create-counsel-dash-hook sql ("PostgreSQL" "MySQL"))))
#+END_SRC

** discover-my-major

A nicer way to browse keybindings for major modes.

#+BEGIN_SRC emacs-lisp
(use-package discover-my-major
  :bind ("<f1>" . discover-my-major))
#+END_SRC

** which-key

Popup keybindings following a prefix automatically.

#+BEGIN_SRC emacs-lisp
(use-package which-key
  :diminish which-key-mode
  :config (progn
            (which-key-mode 1)
            (which-key-setup-side-window-right-bottom)))
#+END_SRC

** eldoc

Documentation in the echo-area (where the minibuffer is displayed) is
rather useful.

#+BEGIN_SRC emacs-lisp
(use-package eldoc
  :commands (eldoc-mode)
  :diminish eldoc-mode
  :config (progn
            (setq eldoc-idle-delay 0.1)
            (eldoc-add-command 'paredit-backward-delete 'paredit-close-round)))
#+END_SRC
* Mail

** Gnus

At work, I use gnus for email.  Some of the setup is specific to my
workplace, so I keep it in a host-specific, GPG-encrypted file.

#+BEGIN_SRC emacs-lisp
(use-package gnus
  :config (progn
            (setq gnus-gcc-mark-as-read t
                  mml-secure-openpgp-encrypt-to-self t
                  send-mail-function #'smtpmail-send-it
                  message-send-mail-function #'smtpmail-send-it)))

(with-eval-after-load 'gnus-mime
  (define-key gnus-mime-button-map " " #'gnus-mime-view-part-externally))

(with-eval-after-load "mailcap"
  (when (eq system-type 'darwin)
    (mailcap-add-mailcap-entry "application" "pdf" '((viewer . "/usr/bin/qlmanage -p %s") (type . "application/pdf")))))

(with-eval-after-load "mm-decode"
  (add-to-list 'mm-discouraged-alternatives "text/html")
  (add-to-list 'mm-discouraged-alternatives "text/richtext"))
#+END_SRC

** BBDB

As I'm using Emacs for email, it makes sense to have contact
information here as well.

#+BEGIN_SRC emacs-lisp
(use-package bbdb
  :config (progn
            (bbdb-initialize 'gnus 'mail 'message 'pgp)
            (bbdb-mua-auto-update-init 'gnus 'message)
            (setq bbdb-send-mail-style 'gnus
                  bbdb-complete-mail-allow-cycling t
                  bbdb-mua-auto-update t
                  bbdb-mua-update-interactive-p '(query . create)
                  bbdb-message-all-addresses t
                  bbdb-offer-save t
                  bbdb-offer-to-create 1)))
#+END_SRC

* Misc

#+BEGIN_SRC emacs-lisp
(defvar *init-file*
  (let ((init-file (or user-init-file
                       (expand-file-name "init.el" user-emacs-directory))))
    (expand-file-name "init.el"
                      (file-name-directory (file-truename init-file))))
  "Where the emacs init file really is, passing through symlinks.")
(set-register ?e `(file . ,*init-file*))

(defun ap/remove-extra-cr ()
  "Remove extraneous CR codes from a file"
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (search-forward "
  " nil t)
      (replace-match ""))))

(use-package rect
  :ensure nil
  :init (defun copy-rectangle (start end)
          "Copy the region-rectangle."
          (interactive "r")
          (setq killed-rectangle (extract-rectangle start end))))

(defun shell-execute (to-current-buffer)
  (interactive "P")
  (let ((file-buffer (if (buffer-file-name)
                         (file-name-nondirectory (buffer-file-name))
                       ""))
        (command (read-shell-command "Shell command: " nil nil nil)))
    (shell-command (replace-regexp-in-string "%" file-buffer command) to-current-buffer)))

(defun process-exit-code (program &rest args)
  "Run PROGRAM with ARGS and return the exit code"
  (apply 'call-process program nil nil nil args))

(defun narrow-to-region-indirect (start end)
  "Restrict editing in this buffer to the current region, indirectly."
  (interactive "r")
  (deactivate-mark)
  (let ((buf (clone-indirect-buffer nil nil)))
    (with-current-buffer buf
      (narrow-to-region start end))
    (switch-to-buffer buf)))

(bind-key* "M-!" #'shell-execute)
(bind-key* "C-x r M-w" #'copy-rectangle)
#+END_SRC

** Auxillary Configuration

#+BEGIN_SRC emacs-lisp
(require 'pinentry)

(defvar have-private-key
  (file-exists-p (expand-file-name "secring.gpg" "~/.gnupg/")))

(defvar gpg-agent-ssh-sock
  (or (getenv "GPG_AGENT_INFO")
      (concat "/run/user/" (number-to-string (user-uid)) "/gnupg/S.gpg-agent.ssh")))

(defun read-gpg-file (file)
  (let ((file-to-decrypt (expand-file-name file user-emacs-directory))
	(ctx (epg-make-context epa-protocol)))
    (if (file-exists-p file-to-decrypt)
	(epg-decrypt-file ctx file-to-decrypt nil)
      (message "Decrypting %s...failed" file-to-decrypt)
      (error "File %s does not exist" file-to-decrypt))))

(defun load-gpg (file)
  (if have-private-key
      (load file)
    (message "WARNING: Couldn't load %s (No gpg key found)" file)))

; load this in a post-frame hook because gpg-agent asks for a password on first
; startup and caches it. Don't want emacs daemon to hang because of gpg-agent.
(defun load-private-data ()
  (interactive)
  (if (not (file-exists-p (expand-file-name (concat system-name ".el.gpg") user-emacs-directory)))
      (message "No encrypted configuration matches system name `%s'" system-name)
    (if (not have-private-key)
        (message "ERROR: Private GPG key not found")
      (unless (or (getenv "GPG_AGENT_INFO")
                  (getenv "SSH_AUTH_SOCK"))
        (start-process "gpg-agent" nil "gpg-agent" "--daemon")
        (setenv "SSH_AUTH_SOCK" gpg-agent-ssh-sock))
      (setq password-cache-expiry nil)
      (unless (file-exists-p (concat pinentry--socket-dir "pinentry"))
        (pinentry-start)
        (add-hook 'kill-emacs-hook 'pinentry-stop))
      (add-to-list 'load-suffixes ".el.gpg")
      (load-gpg (expand-file-name system-name user-emacs-directory)))))

(defun first-frame-hook (frame)
  (remove-hook 'after-make-frame-functions #'first-frame-hook)
  (run-at-time nil nil 'load-private-data))

(if (eq 1 (length (frame-list)))
    (add-hook 'after-init-hook #'load-private-data)
  (add-hook 'after-make-frame-functions #'first-frame-hook))
#+END_SRC

* Minibuffer

Sometimes I want to use the minibuffer, but I’m already inside it.
Fortunately, this is possible.  Of course, I need to know how many
minibuffers there are on the stack.

#+BEGIN_SRC emacs-lisp
(setq enable-recursive-minibuffers t)
(minibuffer-depth-indicate-mode t)
#+END_SRC

This avoids some issue with the minibuffer and the point being behind
the prompt.  I don’t remember what exactly.
#+BEGIN_SRC emacs-lisp
(setq minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt))
#+END_SRC

Occasionally, I exit emacs.  I should probably reduce the frequency of this.
#+BEGIN_SRC emacs-lisp
(if (daemonp)
    (defalias 'exit-emacs #'delete-frame)
  (defalias 'exit-emacs #'save-buffers-kill-emacs))
#+END_SRC

** swiper/ivy

Ivy is the new kid on the completion block.  It seems to be a strong
replacement for helm so far.

#+BEGIN_SRC emacs-lisp
(use-package swiper
  :bind (("C-s" . swiper)
         ("C-r" . swiper)
         ("C-x i" . ivy-imenu-goto)
         ("C-=" . swiper))
  :diminish ivy-mode
  :demand t
  :config (progn
            (ivy-mode 1)
            (setq ivy-re-builders-alist '((internal-complete-buffer . ivy--regex-fuzzy)
                                          (t . ivy--regex-plus)))
            (defun ivy-imenu-get-candidates-from (alist  &optional prefix)
              (cl-loop for elm in alist
                       nconc (if (imenu--subalist-p elm)
                                 (ivy-imenu-get-candidates-from
                                  (cl-loop for (e . v) in (cdr elm) collect
                                           (cons e (if (integerp v) (copy-marker v) v)))
                                  (concat prefix (if prefix ".") (car elm)))
                               (and (cdr elm) ; bug in imenu, should not be needed.
                                    (setcdr elm (copy-marker (cdr elm))) ; Same as [1].
                                    (list (cons (concat prefix (if prefix ".") (car elm))
                                                (copy-marker (cdr elm))))))))

            (defun ivy-imenu-goto ()
              "Go to buffer position"
              (interactive)
              (let ((imenu-auto-rescan t) items)
                (unless (featurep 'imenu)
                  (require 'imenu nil t))
                (setq items (imenu--make-index-alist t))
                (ivy-read "imenu items:"
                          (ivy-imenu-get-candidates-from (delete (assoc "*Rescan*" items) items))
                          :action (lambda (k) (goto-char k)))))
            (ivy-set-actions 'ivy-switch-buffer '(("k" (lambda (x)
                                                         (kill-buffer x)
                                                         (ivy--reset-state ivy-last))
                                                   "kill")))
            (add-to-list 'ivy-initial-inputs-alist '(counsel-M-x . ""))))
#+END_SRC

** counsel

#+BEGIN_SRC emacs-lisp
(use-package counsel
  :config (progn
            (bind-key "M-x" #'counsel-M-x)
            (bind-key "<apps>" #'counsel-M-x)
            (bind-key "<menu>" #'counsel-M-x)
            (bind-key "C-c M-x" #'execute-extended-command)
            (bind-key "C-x C-f" #'counsel-find-file)
            (bind-key "M-y" #'counsel-yank-pop)
            (bind-key "M-y" #'ivy-next-line ivy-minibuffer-map)
            (defadvice counsel-find-file (after find-file-sudo activate)
              "Find file as root if necessary."
              (when (and buffer-file-name
                         (not (file-writable-p buffer-file-name)))
                (message "File not writable %s" buffer-file-name)
                (find-alternate-file (concat "/sudo::" buffer-file-name))))))
#+END_SRC


** smex

Smex is my favourite way to use =M-x=.  Counsel’s =counsel-M-x=
function uses it internally, so I’m keeping it around, even though I
don’t use it directly.

#+BEGIN_SRC emacs-lisp
(use-package smex
  :commands (smex
             smex-update
             smex-initialize)
  :config (progn
            (setq smex-key-advice-ignore-menu-bar t
                  smex-auto-update nil)
            (defun smex-update-after-load (_unused)
              (if (boundp 'smex-cache)
                  (smex-update)))
            (add-hook 'after-load-functions 'smex-update-after-load))
  :init (progn
          (setq smex-history-length 100
                smex-save-file (concat user-emacs-directory
                                       "smex-items"))))
#+END_SRC

** cmd-to-echo

I’ve been looking for some way to run programming projects (mostly
node.js) inside emacs.  =cmd-to-echo= seems great for this, as new
output pops up in the echo area.

#+BEGIN_SRC emacs-lisp
(use-package cmd-to-echo
  :commands (cmd-to-echo)
  :config (setq cmd-to-echo-add-output-to-process-buffers t))
#+END_SRC
* Modes

Setup some modes for systemd files
#+BEGIN_SRC emacs-lisp
(add-to-list 'auto-mode-alist '("\\.service\\'" . conf-mode))
(add-to-list 'auto-mode-alist '("\\.target\\'" . conf-mode))
(add-to-list 'auto-mode-alist '("\\.socket\\'" . conf-mode))
#+END_SRC

=direnv=’s files are basically shell scripts, it’s a nice way to
set environment variables for projects.
#+BEGIN_SRC emacs-lisp
(add-to-list 'auto-mode-alist '("\\.envrc\\'" . sh-mode))
#+END_SRC

Some modes that I don’t really customise much, mostly for
configuration files.
#+BEGIN_SRC emacs-lisp
(use-package xrdb-mode
  :ensure nil
  :mode (("\\.Xdefaults\\'" . xrdb-mode)
         ("\\.Xresources\\'" . xrdb-mode)))

(use-package haskell-mode
  :mode (("\\.hs\\'" . haskell-mode)))

(use-package dockerfile-mode
  :mode (("Dockerfile\\'" . dockerfile-mode)))

(use-package nix-mode
  :mode (("\\.nix\\'" . nix-mode)))

(define-derived-mode xmonad-mode haskell-mode "XM")
(add-to-list 'auto-mode-alist '("xmobarrc\\'" . xmonad-mode))
(add-to-list 'auto-mode-alist '("xmonad.hs\\'" . xmonad-mode))

(use-package nginx-mode
  :defer t
  :mode (("/nginx/servers/" . nginx-mode)
         ("/nginx/.*\\.d/" . nginx-mode)))

(use-package lua-mode
  :defer t)

(use-package ruby-mode
  :mode (("\\.rb\\'" . ruby-mode)
         ("\\.cap\\'" . ruby-mode)))

(use-package go-mode
  :mode (("\\.go\\'" . go-mode)))

(use-package jinja2-mode
  :mode (("\\.j2\\'" . jinja2-mode)
         ("\\.jinja\\'" . jinja2-mode)))

(use-package scss-mode
  :defer t
  :config (progn
            (setq scss-compile-at-save nil)))

(use-package yaml-mode
  :mode (("/group_vars/.*" . yaml-mode)
         ("/host_vars/.*" . yaml-mode)))

(define-derived-mode ansible-mode yaml-mode "Ansible")
(add-to-list 'auto-mode-alist '("\\(?:ansible.+\\|roles/.+/\\(?:tasks\\|handlers\\)\\)/.+\\.yml\\'" . ansible-mode))

(define-derived-mode saltstack-mode yaml-mode "Salt")
(add-to-list 'auto-mode-alist '("\\.sls\\'" . saltstack-mode))
#+END_SRC

** ledger

I use [[http://ledger-cli.org/][=ledger=]] to manage my finances.  It has an Emacs mode, which
works really nicely.

#+BEGIN_SRC emacs-lisp
(use-package ledger-mode
  :mode ("\\.ledger\\'" . ledger-mode)
  :init (progn
          (defun open-budget ()
            (interactive)
            (projectile-switch-project-by-name "~/Sync/Default")
            (find-file (expand-file-name "ledger/my.ledger" (projectile-project-root)))
            (ledger-report "Budget (Cumulative)" nil)))
  :config (progn
            (setq ledger-use-iso-dates t
                  ledger-post-use-completion-engine :built-in
                  ledger-reconcile-default-commodity "€"
                  ledger-clear-whole-transactions t
                  ledger-narrow-on-reconcile t
                  ledger-default-date-format "%Y-%m-%d"
                  ledger-reports '(("Monthly Expenses" "ledger -f %(ledger-file) reg -M Expenses --real -l \"payee != 'Opening Balances'\"")
                                   ("Expenses:This Month" "ledger -f %(ledger-file) bal \\^Expenses -p \"this month\"")
                                   ("On-budget Balances" "ledger -f %(ledger-file) bal --current -R :Budget: Assets:Receivable Liabilities:Personal")
                                   ("All Account Balances" "ledger -f %(ledger-file) bal --current -R \\^Assets \\^Liabilities")
                                   ("Budget Values (Current Month)" "ledger -f %(ledger-file) bal -p \"this month\" --limit \"payee=~/budget/\" \\^Funds")
                                   ("Budget (Cumulative)" "ledger -f %(ledger-file) bal -E \\^Funds \\^Assets:Budget$")
                                   ("Budget Allocation" "ledger -f %(ledger-file) bal -p \"this month\" --limit \"payee=~/budget/\" \\^Funds --format \"\\
                    %-17((depth_spacer)+(partial_account))\\
                    %10(percent(market(display_total), market(parent.total)))\\
                    %16(market(display_total))\n%/\"")
                                   ("bal" "ledger -f %(ledger-file) bal")
                                   ("reg" "ledger -f %(ledger-file) reg")
                                   ("equity" "ledger -f %(ledger-file) equity")
                                   ("payee" "ledger -f %(ledger-file) reg @%(payee)")
                                   ("account" "ledger -f %(ledger-file) reg %(account)")))))
#+END_SRC

** Markdown

#+BEGIN_SRC emacs-lisp
(use-package markdown-mode
  :defer t
  :config (progn
            (add-hook 'markdown-mode-hook #'turn-on-auto-fill)))
#+END_SRC

** Org

Org is wünderbar.

#+BEGIN_SRC emacs-lisp
(use-package org
  :bind (("C-c C-a" . org-agenda-list)
         ("C-c a" . org-agenda)
         ("C-c l" . org-store-link))
  :defer 8
  :init (setq org-replace-disputed-keys t
              org-ellipsis "…")
  :config (progn
            (setq org-directory "~/Sync/org"
                  org-agenda-files `(,(concat org-directory "/agenda"))

                  org-default-notes-file (concat org-directory "/notes")

                  ;; ‘Remember’: new items at top
                  org-reverse-note-order t

                  org-modules '(org-protocol)

                  ;; Add time done to ‘done’ tasks
                  org-log-done 'time

                  org-list-allow-alphabetical t

                  org-adapt-indentation nil

                  org-pretty-entities t

                  org-table-duration-custom-format 'seconds

                  org-src-fontify-natively nil

                  org-export-have-math t

                  org-blank-before-new-entry '((heading . t)
                                               (plain-list-item . auto))
                  org-fontify-done-headline t

                  org-todo-keywords '((sequence "BACKLOG(b)" "TODO(t)" "WAIT(w@/!)" "STARTED(s!)" "|" "DONE(d!)")
                                      (sequence "|" "CANCELLED(c@)"))
                  org-log-into-drawer "LOGBOOK")
            (set-register ?o `(file . ,(expand-file-name "organiser.org" org-directory)))
            (add-hook 'org-mode-hook #'turn-on-auto-fill)
            (org-load-modules-maybe t)))
#+END_SRC

**** org-babel

Org’s babel feature is really nice.  I use it for this file, and I can
use it to communicate between programming languages.  Sometime I hope
to have my =ledger= setup in an org file with some graph processing
with R or something.

#+BEGIN_SRC emacs-lisp
(use-package ob-core
  :defer t
  :ensure nil
  :config (progn
            (org-babel-do-load-languages 'org-babel-load-languages
                                         '((ledger . t)
                                           (sh . t)))
            (setq org-src-tab-acts-natively t
                  org-edit-src-content-indentation 0
                  org-src-preserve-indentation t)))
#+END_SRC

**** org-journal

I can use this to keep a journal.  I should use it.

#+BEGIN_SRC emacs-lisp
(use-package org-journal
  :bind ("s-j" . org-journal-new-entry)
  :defer 20
  :config (progn
            (setq org-journal-date-format "%A, %d %B %Y")
            (defun org-journal-display-entry-yesterday ()
              "Show org-journal entry for yesterday"
              (interactive)
              (org-journal-read-or-display-entry (yesterday-time)))))
#+END_SRC

**** org-mobile

#+BEGIN_SRC emacs-lisp
(defun ap/org-mobile-pull (descriptor action file)
  (org-mobile-pull))
(use-package org-mobile
  :defer 30
  :ensure nil
  :disabled t
  :config (progn
            (setq org-mobile-directory "~/Mobile/Org"
                  org-mobile-inbox-for-pull "~/Mobile/Org/from-mobile.org")
            (defvar org-mobile-push-timer nil
              "Timer that `org-mobile-push-timer' used to reschedule itself, or nil.")

            (defun org-mobile-push-with-delay (secs)
              (when org-mobile-push-timer
                (cancel-timer org-mobile-push-timer))
              (setq org-mobile-push-timer
                    (run-with-idle-timer
                     (* 1 secs) nil 'org-mobile-push)))

            (add-hook 'after-save-hook
                      (lambda ()
                        (when (eq major-mode 'org-mode)
                          (dolist (file (org-mobile-files-alist))
                            (if (string= (file-truename (expand-file-name (car file)))
                                         (file-truename (buffer-file-name)))
                                (org-mobile-push-with-delay 30))))))

            (run-at-time "00:05" 86400 '(lambda () (org-mobile-push-with-delay 1))) ;; refreshes agenda file each day
            (org-mobile-pull) ;; run org-mobile-pull at startup

            (defvar org-mobile-watcher nil)
            (when file-notify--library
              (let ((org-file (expand-file-name
                               (concat
                                (file-name-as-directory org-mobile-directory)
                                org-mobile-capture-file))))
                (setq org-mobile-watcher
                      (file-notify-add-watch org-file '(change) #'ap/org-mobile-pull))))))
#+END_SRC

**** org-caldav

I’ve setup CalDAV on my server, it would be nice to use it directly
from org-mode.  Previously I had to wait for org-mobile to sync and
write to the Android calendar, and then for DAVDroid to sync with the server.

#+BEGIN_SRC emacs-lisp
(use-package org-caldav
  :defer 30
  :config (progn
            (setq org-caldav-url "https://calendar.alanpearce.uk/alan"
                  org-caldav-calendar-id "caldav"
                  org-caldav-inbox (concat org-directory "/agenda/caldav.org")
                  org-caldav-files `(,(concat org-directory "/agenda/organiser.org"))
                  org-icalendar-timezone "Europe/Berlin"
                  org-icalendar-use-scheduled '(event-if-todo event-if-not-todo todo-start)
                  org-icalendar-use-deadline '(event-if-todo event-if-not-todo todo-due)
                  org-icalendar-alarm-time 60)))
#+END_SRC

**** org-page

I would like to convert my website from using hugo to something else
that I can work with nicely from inside Emacs.  I wonder if org-page
will do the trick.

#+BEGIN_SRC emacs-lisp
(use-package org-page
  :config (progn
            (setq op/site-domain "https://alanpearce.uk/"
                  op/repository-directory "~/projects/alanpearce/"
                  op/personal-github-link "https://github.com/alanpearce")))
#+END_SRC

* Music
Emacs actually supports playing music via mpd.

#+BEGIN_SRC emacs-lisp
(use-package mpc
  :defer t
  :config (progn
            (setq mpc-browser-tags '(Genre Albumartist|Composer|Performer Album|Playlist))))
#+END_SRC
* Programming
** flycheck

On-the-fly error checking in programming modes?  Yes please.

#+BEGIN_SRC emacs-lisp
(use-package flycheck
  :diminish " ✓"
  :defer 5
  :config (progn
            (global-flycheck-mode)
            (setq flycheck-check-syntax-automatically '(save new-line mode-enabled))
            (if (executable-find "eslint_d")
                (setq flycheck-javascript-eslint-executable (executable-find "eslint_d")))))
#+END_SRC

** golang

Go has a few packages to inter-operate with other emacs packages.

#+BEGIN_SRC emacs-lisp
(use-package company-go
  :commands company-go
  :config (progn
            (setq company-go-show-annotation t))
  :init (progn
          (defun ap/company-go-setup ()
            (set (make-local-variable 'company-backends)
                 '(company-go)))
          (add-hook 'go-mode-hook #'ap/company-go-setup)))

(use-package go-eldoc
  :commands go-eldoc-setup
  :init (progn
          (add-hook 'go-mode-hook #'go-eldoc-setup)))

(use-package go-projectile
  :defer t
  :config (progn
            (setq go-projectile-switch-gopath 'maybe)))


#+END_SRC

** ggtags

A nice completion backend for programming modes.

#+BEGIN_SRC emacs-lisp
(use-package ggtags
  :if (executable-find "gtags")
  :commands turn-on-ggtags-mode
  :functions (ggtags-navigation-mode-abort)
  :config (progn
            (bind-key "q" #'ggtags-navigation-mode-abort ggtags-navigation-mode-map))
  :init (progn
          (defun turn-on-ggtags-mode ()
            (interactive)
            (ggtags-mode 1))
          (add-hook 'c-mode-common-hook #'turn-on-ggtags-mode)))
#+END_SRC

** dumb-jump

A "clever" way of implementing go-to-definition across languages: use
a project-wide text search and apply heuristics to the results to
guess a definition.

#+BEGIN_SRC emacs-lisp
(use-package dumb-jump
  :bind (("M-g o" . dumb-jump-go-other-window)
         ("M-g j" . dumb-jump-go)
         ("M-g x" . dumb-jump-go-prefer-external)
         ("M-g z" . dumb-jump-go-prefer-external-other-window))
  :config (setq dumb-jump-selector 'ivy))
#+END_SRC

** Lisps

*** All

Lisp modes don’t seem to have a common ancestor.  So I made a custom
hook which I trigger in every lispy-mode.

#+BEGIN_SRC emacs-lisp
(defcustom lisp-mode-common-hook nil
  "Hook run when entering any Lisp mode."
  :type 'hook
  :group 'lisp)

(defun ap/lisp-setup ()
  (run-hooks 'lisp-mode-common-hook))
#+END_SRC

**** Redshank

Lisp syntax allows for really easy refactoring.  Redshank gives some
operations that aren’t part of paredit, like extracting variables into
let bindings.
#+BEGIN_SRC emacs-lisp
(use-package redshank
  :diminish " Λ"
  :after (paredit)
  :config (progn
            (add-hook 'lisp-mode-common-hook #'turn-on-redshank-mode)))
#+END_SRC

*** Emacs Lisp

Customise the modeline-display of =emacs-lisp-mode=.  Then make sure
it runs the common lisp hooks.

#+BEGIN_SRC emacs-lisp
(add-hook 'emacs-lisp-mode-hook #'ap/lisp-setup)
(add-hook 'emacs-lisp-mode-hook #'eldoc-mode)
#+END_SRC

Go-to function for elisp.  Except it works through the entire Emacs ecosystem.

#+BEGIN_SRC emacs-lisp
(use-package elisp-slime-nav
  :commands elisp-slime-nav-mode
  :diminish elisp-slime-nav-mode
  :init (progn
          (add-hook 'emacs-lisp-mode-hook #'elisp-slime-nav-mode)))
#+END_SRC

Interactive elisp

#+BEGIN_SRC emacs-lisp
(use-package ielm
  :defer t
  :ensure nil
  :config (progn
            (add-hook 'ielm-mode-hook (lambda ()
                                        (run-hooks 'lisp-mode-common-hook)))))
#+END_SRC

*** Scheme & Lisp

I don’t work with these as often as I would like

#+BEGIN_SRC emacs-lisp
(add-hook 'scheme-mode-hook #'ap/lisp-setup)
(add-hook 'lisp-mode-hook #'ap/lisp-setup)
(defun set-common-lisp-indentation ()
  (set (make-local-variable 'lisp-indent-function)
       #'common-lisp-indent-function))
(add-hook 'lisp-mode-hook #'set-common-lisp-indentation)
#+END_SRC

**** geiser

A REPL thing for Scheme.  Hopefully I’ll get to use it more in the
future.

#+BEGIN_SRC emacs-lisp
(use-package geiser
  :commands (geiser-mode
             geiser
             run-geiser
             run-racket))
#+END_SRC

**** slime

A REPL thing (and more) for Lisp.

#+BEGIN_SRC emacs-lisp
(use-package slime
  :commands (slime)
  :config (progn
            (let ((ql-slime-helper (expand-file-name "~/quicklisp/slime-helper.el")))
              (if (file-exists-p ql-slime-helper)
                  (load ql-slime-helper))
              (slime-setup))
            (setq inferior-lisp-program (or (executable-find "sbcl")
                                            (executable-find "ccl64")))))
#+END_SRC

*** Clojure

#+BEGIN_SRC emacs-lisp
(use-package clojure-mode
  :defer t
  :init (progn
          (add-hook 'cider-repl-mode-hook (lambda () (highlight-changes-mode -1)))
          (add-hook 'clojure-mode-hook #'ap/lisp-setup)))

(use-package clj-refactor
  :defer t
  :functions (clj-refactor-mode cljr-add-keybindings-with-prefix)
  :config (progn
            (cljr-add-keybindings-with-prefix "C-c C-m"))
  :init (progn
          (defun turn-on-clj-refactor-mode ()
            (clj-refactor-mode 1))
          (add-hook 'clojure-mode-hook #'turn-on-clj-refactor-mode)))
#+END_SRC

**** cider

A REPL thing for Clojure

#+BEGIN_SRC emacs-lisp
(use-package cider
  :defer t
  :config (progn
            (setq nrepl-hide-special-buffers t)
            (unbind-key "C-c C-f" cider-mode-map)
            (add-hook 'cider-mode-hook #'eldoc-mode)))
#+END_SRC

** Auto-compile

Auto-compile emacs lisp when saving.
#+BEGIN_SRC emacs-lisp
(use-package auto-compile
  :defer t
  :init (add-hook 'emacs-lisp-mode-hook #'auto-compile-on-save-mode))
#+END_SRC

** cc-mode

Although I don’t use C or C++, setting up the mode is helpful because
quite a few other modes are derived from it.

#+BEGIN_SRC emacs-lisp
(use-package cc-mode
  :defer 5
  :init (progn
          (add-hook 'c-mode-common-hook #'electric-indent-mode))
  :config (progn
            (setq c-default-style '((java-mode . "java")
                                    (awk-mode . "awk")
                                    (other . "k&r"))
                  c-basic-offset 4)
            (c-set-offset 'case-label '+)))
#+END_SRC

** quickrun

It’s nice to be able to quickly evaluate some code.  Although I don’t
really seem to use it.
#+BEGIN_SRC emacs-lisp
(use-package quickrun
  :bind (("C-c C-e" . quickrun)))
#+END_SRC

** Scala

Let’s try using Scala.

#+BEGIN_SRC emacs-lisp
(use-package scala-mode
  :pin melpa-stable)
#+END_SRC

And add ensime, an IDE-style environment.

#+BEGIN_SRC emacs-lisp
(use-package ensime
  :pin melpa-stable)
#+END_SRC

** Web development

*** js2-mode

This mode is really great for editing Javascript.  It turns code into
an AST internally, so it can work with it almost like a lisp.  I don’t
think there’s anything as good as paredit/redshank for refactoring in
it though

#+BEGIN_SRC emacs-lisp
(use-package js2-mode
  :mode (("\\.js\\'" . js2-mode)
         ("\\.jsx\\'" . js2-jsx-mode))
  :interpreter ("node" . js2-mode)
  :functions js2-next-error
  :config (progn
            (define-key js2-mode-map [menu-bar Javascript] nil)
            (defun js2--imenu-around (do-it name)
              "Don't create a menu from js2-mode"
              (if (and (not (string-equal name "IM-Javascript-IDE"))
                       (fboundp #'do-it))
                  (do-it name)))
            (advice-add 'imenu-add-to-menubar :around #'js2--imenu-around)
            (defun ap/js2-prev-error ()
              (interactive)
              (js2-next-error -1))
            (bind-key "M-g M-n" #'js2-next-error js2-mode-map)
            (bind-key "M-g M-p" #'ap/js2-prev-error js2-mode-map)
            (setq js2-basic-offset 2
                  js2-include-node-externs t)))
#+END_SRC

**** jade (not pug)

Javascript with an inferior node.js process and a debugger?  Awesome.

To debug with node, use version 6.9.1 or later of node and run it with
~--inspect~ and, to break on the first line, ~--debug-brk~.

For Chrom*, it needs to be launched with ~--remote-debugging-port=9222~

#+BEGIN_SRC emacs-lisp
(use-package jade
  :config (progn
            (add-hook 'js2-mode-hook #'jade-interaction-mode)))
#+END_SRC

*** coffee-mode

#+BEGIN_SRC emacs-lisp
(use-package coffee-mode
  :mode ("\\.coffee\\'" . coffee-mode)
  :config (progn
            (setq coffee-indent-like-python-mode t)))
#+END_SRC

*** tern

Tern understands javascript.  It adds really clever documented
completions, besides other IDE-like things.

#+BEGIN_SRC emacs-lisp
(use-package tern
  :commands ap/enable-tern
  :if (executable-find "tern")
  :defer 5
  :config (progn
            (setq tern-command (list (executable-find "tern")))
            (defun ap/enable-tern ()
              (tern-mode 1))
            (add-hook 'js2-mode-hook #'ap/enable-tern)
            (add-hook 'web-mode-hook #'ap/enable-tern)))

(with-eval-after-load 'tern
  (use-package company-tern))
#+END_SRC

*** json-mode

#+BEGIN_SRC emacs-lisp
(use-package json-mode
  :mode (("\\.json\\'" . json-mode)
         ("\\.sailsrc\\'" . json-mode)
         ("composer\\.lock\\'" . json-mode)
         ("\\.tern-project\\'" . json-mode)))
#+END_SRC

*** restclient

Restclient is really nice.  It’s like a scratchpad for HTTP api
calls.  Feels a bit like using =org-babel=.  I wonder if there’s an
integration between the two yet.

#+BEGIN_SRC emacs-lisp
(use-package restclient
  :mode ("\\.api\\'" . restclient-mode)
  :config (progn
            (defun imenu-restclient-sections ()
              (setq imenu-prev-index-position-function nil)
              (add-to-list 'imenu-generic-expression '("Services" "^## ?\\(.+\\)$" 1) t)
              (add-to-list 'imenu-generic-expression '("Calls" "^# ?\\(.+\\)$" 1) t))
            (add-hook 'restclient-mode-hook #'imenu-restclient-sections)))

(use-package company-restclient
  :after (company restclient)
  :init (add-to-list 'company-backends #'company-restclient t))
#+END_SRC

*** sgml-mode

This is for HTML, since old versions of HTML were derived from SGML.
#+BEGIN_SRC emacs-lisp
(use-package sgml-mode
  :defer t
  :config (setq sgml-basic-offset 2))
#+END_SRC

*** emmet-mode

Emmet is really nice to write HTML quickly.  Especially with
frameworks that require multiple nested elements to do anything useful.
#+BEGIN_SRC emacs-lisp
(use-package emmet-mode
  :commands (emmet-mode)
  :diminish (emmet-mode . " >")
  :init (progn
          (setq emmet-indentation 2)
          (add-hook 'web-mode-hook #'emmet-mode)))
#+END_SRC

*** web-mode

This mode handles just about every templating language out ther, which
is really nice, because it handles the HTML part the same way in all
of them as well.

#+BEGIN_SRC emacs-lisp
(use-package web-mode
  :mode (("/views/.*\\.php\\'" . web-mode)
         ("\\.html\\'" . web-mode)
         ("/templates/.*\\.php\\'" . web-mode)
         ("\\.ejs\\'" . web-mode))
  :config (progn
            (setq web-mode-code-indent-offset 2
                  web-mode-css-indent-offset 2
                  web-mode-markup-indent-offset 2
                  web-mode-style-padding 0
                  web-mode-script-padding 0
                  web-mode-comment-style 2
                  web-mode-enable-auto-pairing nil
                  web-mode-enable-auto-quoting nil)
            (sp-local-pair '(web-mode) "<%" "%>")))
#+END_SRC

I derived a mode for twig, in order to use its =mode-hook=.

#+BEGIN_SRC emacs-lisp
(define-derived-mode twig-mode web-mode "Twig")
(add-to-list 'auto-mode-alist '("\\.html\\.twig\\'" . twig-mode))
#+END_SRC

* Spelling

#+BEGIN_SRC emacs-lisp
(use-package ispell
  :bind (("<f8>" . ispell-word))
  :config (progn
            (cond
             ((executable-find "aspell") (setq ispell-program-name "aspell"
                                               ispell-dictionary "british"
                                               ispell-really-aspell t
                                               ispell-really-hunspell nil))
             ((executable-find "hunspell") (setq ispell-program-name "hunspell"
                                                 ispell-really-aspell nil
                                                 ispell-really-hunspell t)))))
#+END_SRC

#+BEGIN_SRC emacs-lisp
(use-package flyspell
  :config (progn
            (add-hook 'text-mode-hook (lambda () (flyspell-mode +1)))
            (add-hook 'prog-mode-hook #'flyspell-prog-mode)))
#+END_SRC

* Scripting

Make a shell-script buffer executable after saving it, if it has a shebang.

#+BEGIN_SRC emacs-lisp
(add-hook 'after-save-hook
          #'executable-make-buffer-file-executable-if-script-p)

(use-package sh-script
  :mode (("\\.zsh\\'" . shell-script-mode)
         ("zshenv\\'" . shell-script-mode)
         ("zshrc\\'"  . shell-script-mode))
  :config (setq sh-shell-file "/usr/bin/env zsh"
                sh-indentation 2
                sh-basic-offset 2))
#+END_SRC

#+BEGIN_SRC emacs-lisp
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
#+END_SRC

** eshell

I should try to get into the habit of using this more.  It’s really
nice, when I remember to use it.

#+BEGIN_SRC emacs-lisp
(use-package eshell
  :bind ("C-c s" .  eshell)
  :config (progn
            (setq eshell-directory-name "~/.emacs.d/eshell"
                  eshell-prompt-function (lambda ()
                                           (concat
                                            (eshell/pwd)
                                            "\n$ ")))
            (add-hook 'eshell-load-hook (lambda ()
                                          (bind-key "C-c C-l" #'counsel-esh-history eshell-mode-map)))))

(use-package em-smart
  :ensure nil
  :commands eshell-smart-initialize
  :init (progn
          (add-hook 'eshell-load-hook #'eshell-smart-initialize))
  :config (progn
            (setq eshell-where-to-jump 'begin
                  eshell-review-quick-commands nil
                  eshell-smart-space-goes-to-end t)))

(autoload #'eshell/cd "em-dirs")
(defun eshell-goto-current-dir (&optional arg)
  (interactive "P")
  (let ((dir default-directory))
    (eshell arg)
    (eshell/cd dir)))
(bind-key "C-c S" #'eshell-goto-current-dir)


#+END_SRC

*** Shells

#+BEGIN_SRC emacs-lisp
(use-package shell
  :defer t
  :ensure nil
  :config (define-key shell-mode-map
            (kbd "C-d") 'comint-delchar-or-eof-or-kill-buffer))

(use-package comint
  :defer t
  :ensure nil
  :config (bind-key "C-c C-l" #'counsel-shell-history comint-mode-map))

(defun comint-delchar-or-eof-or-kill-buffer (arg)
  (interactive "p")
  (if (null (get-buffer-process (current-buffer)))
      (kill-buffer)
    (comint-delchar-or-maybe-eof arg)))
#+END_SRC

* Text editing

Emacs has an editor within.

#+BEGIN_SRC emacs-lisp
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)
(setq sentence-end-double-space t
      line-move-visual nil)
#+END_SRC

** align

=Align= is a useful command to line things up, once given some rules.
The most important one for me is JSON property alignment.

#+BEGIN_SRC emacs-lisp
(use-package align
  :defer 10
  :ensure nil
  :config (progn
            (add-to-list 'align-rules-list
                         '(colon-key-value
                           (regexp . ":\\(\\s-*\\)")
                           (modes  . '(js2-mode))))))
#+END_SRC

** Clipboard

I like to use the clipboard more than the primary selection in X11.

#+BEGIN_SRC emacs-lisp
(setq x-select-enable-clipboard t
      save-interprogram-paste-before-kill t)
(if (functionp 'x-cut-buffer-or-selection-value)
    (setq interprogram-paste-function 'x-cut-buffer-or-selection-value))
(when (boundp 'x-select-request-type)
  (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))
#+END_SRC

*** Copy formatted code

#+BEGIN_SRC emacs-lisp
(bind-key* "C-c w" (define-prefix-command 'copy-as-map))
(use-package copy-as-format
  :bind (("C-c C-w" . copy-as-format)
         :map copy-as-map
         ("b" . copy-as-format-bitbucket)
         ("g" . copy-as-format-github)
         ("h" . copy-as-format-hipchat)
         ("w" . copy-as-format-html)
         ("j" . copy-as-format-jira)
         ("m" . copy-as-format-markdown)
         ("s" . copy-as-format-slack)))
#+END_SRC

**

** Selection

I’m quite used to deleting text by selecting it and typing.  Emacs has
a mode for that.

#+BEGIN_SRC emacs-lisp
(delete-selection-mode t)
#+END_SRC

Sub-word movement is really nice for camel- and Pascal-case

#+BEGIN_SRC emacs-lisp
(use-package subword
  :diminish subword-mode
  :init (global-subword-mode t))
#+END_SRC

I find that =zap-up-to-char= normally makes more sense to me than
=zap-to-char=.

#+BEGIN_SRC emacs-lisp
(use-package misc
  :ensure nil
  :bind (("M-z" . zap-up-to-char)
         ("M-Z" . zap-to-char)))
#+END_SRC

Expanding the region by semantic units was something I quite liked
from Sublime Text.  As always, there’s a mode for that.

#+BEGIN_SRC emacs-lisp
(use-package expand-region
  :bind ("C-M-SPC" . er/expand-region)
  :config (setq expand-region-fast-keys-enabled nil))
#+END_SRC

** avy

Avy is a really nice way to move around files, like ace-jump-mode, but
somehow I prefer it.

#+BEGIN_SRC emacs-lisp
(use-package avy
  :bind (("M-g g" . avy-goto-line)
         ("M-g M-g" . avy-goto-line)
         ("C-|" . avy-goto-line)
         ("M-r" . avy-goto-word-1)
         ("C-c SPC" . avy-goto-char-timer))
  :config (progn
            (avy-setup-default)
            (setq avy-all-windows nil
                  avy-keys '(?a ?r ?s ?t ?d ?h ?n ?e ?i ?\;))))
#+END_SRC

*** ace-link

Visit any link.  Despite the name, this works with avy.

#+BEGIN_SRC emacs-lisp
(use-package ace-link
  :after avy
  :config (progn
            (ace-link-setup-default)
            (with-eval-after-load "gnus"
              (bind-key "M-o" #'ace-link-gnus gnus-summary-mode-map)
              (bind-key "M-o" #'ace-link-gnus gnus-article-mode-map))))
#+END_SRC

** goto-chg

This is like popping the mark, only it filters to only change areas
and doesn’t go back to the same place more than once.

#+BEGIN_SRC emacs-lisp
(use-package goto-chg
  :bind ("C-c C-SPC" . goto-last-change))
#+END_SRC

** multiple-cursors

I mentioned before that I’d used Sublime Text before.  Multiple
cursors was one of my favourite features, so I was really happy when I
saw that multiple-cursors was released for Emacs.

#+BEGIN_SRC emacs-lisp
(use-package multiple-cursors
  :defer 1
  :config (progn
            (bind-key "C-." #'mc/mark-next-like-this)
            (bind-key "C-," #'mc/mark-previous-like-this)
            (bind-key "M-<f3>" #'mc/mark-all-like-this-dwim)
            (bind-key "C-<f3>" #'mc/mark-more-like-this-extended)
            (bind-key "C-S-L" #'mc/edit-lines)))
#+END_SRC

** paredit

Balanced parentheses in lisps are nice, but all the refactoring and
movement commands are much more interesting.

#+BEGIN_SRC emacs-lisp
(use-package paredit
  :diminish "()"
  :config (progn
            (add-hook 'lisp-mode-common-hook #'enable-paredit-mode)
            (put #'paredit-forward-delete 'delete-selection 'supersede)
            (put #'paredit-backward-delete 'delete-selection 'supersede)
            (add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode)))
#+END_SRC

** smartparens

I like to use smartparens where paredit isn’t already useful.  Somehow
I didn’t find smartparens’ implementation of paredit style to be as
nice as the real version

#+BEGIN_SRC emacs-lisp
(eval-when-compile (require 'smartparens nil :noerror))
(use-package smartparens-config
  :ensure smartparens
  :config (progn
            (sp-use-smartparens-bindings)
            (setq sp-highlight-pair-overlay nil)
            (fset 'wrap-with-paren "\C-](") ;; `sp-select-next-thing-exchange'
            (bind-key "C-(" #'wrap-with-paren smartparens-mode-map)
            (bind-key "C-)" #'sp-forward-slurp-sexp smartparens-mode-map)
            (bind-key "M-<backspace>" #'backward-kill-word smartparens-mode-map)
            (bind-key "M-?" #'sp-convolute-sexp smartparens-mode-map)
            (bind-key "C-M-t" #'sp-transpose-sexp smartparens-mode-map)
            (bind-key "M-R" #'sp-raise-sexp smartparens-mode-map)
            (bind-key "M-S" #'sp-splice-sexp smartparens-mode-map)
            (bind-key "C-M-s" #'sp-split-sexp smartparens-mode-map)
            (bind-key "M-J" #'sp-join-sexp smartparens-mode-map)
            (bind-key "M-<up>" #'sp-splice-sexp-killing-backward smartparens-mode-map)
            (bind-key "M-<down>" #'sp-splice-sexp-killing-forward smartparens-mode-map)
            (bind-key "C-M-S-k" #'sp-kill-hybrid-sexp smartparens-mode-map)
            (bind-key "C-S-<right>" #'sp-slurp-hybrid-sexp smartparens-mode-map)
            (sp-with-modes '(twig-mode)
              (sp-local-pair "{%" "%}")
              (sp-local-pair "{{" "}}"))
            (show-smartparens-global-mode t)
            (smartparens-global-strict-mode t)
            (add-hook 'lisp-mode-common-hook #'turn-off-smartparens-mode)
            (add-hook 'coffee-mode-hook #'turn-off-smartparens-mode)))
#+END_SRC

** smart-scan

Move between instances of a symbol

#+BEGIN_SRC emacs-lisp
(use-package smartscan
  :config (progn
            (global-smartscan-mode 1)
            (setq smartscan-symbol-selector "symbol")))
#+END_SRC

** move-text

Transposing lines, made easier.

#+BEGIN_SRC emacs-lisp
(use-package move-text
  :config (move-text-default-bindings))
#+END_SRC

** undo-tree

Emacs’ default handling of undo is a bit confusing.  Undo-tree makes
it much clearer.  It’s especially helpful for protoyping and refactoring.

#+BEGIN_SRC emacs-lisp
(use-package undo-tree
  :config (progn
            (global-undo-tree-mode)
            ;; Keep region when undoing in region
            (defadvice undo-tree-undo (around keep-region activate)
              (if (use-region-p)
                  (let ((m (set-marker (make-marker) (mark)))
                        (p (set-marker (make-marker) (point))))
                    ad-do-it
                    (goto-char p)
                    (set-mark m)
                    (set-marker p nil)
                    (set-marker m nil))
                ad-do-it)))
  :diminish undo-tree-mode)
#+END_SRC

** replace

#+BEGIN_SRC emacs-lisp
(with-eval-after-load "replace.el"
  (setq case-replace nil))
#+END_SRC

** visual-regexp

I don’t always remember exactly how Emacs’ regular expressions work,
so this package is pretty useful because it highlights everything in
the buffer for me.

#+BEGIN_SRC emacs-lisp
(use-package visual-regexp
  :bind (("C-c r" . vr/replace)
         ("C-c q" . vr/query-replace)
         ("C-c m" . vc/mc-mark)))
#+END_SRC
* Tangling

Taken from [[https://github.com/larstvei/dot-emacs/blob/master/init.org][larstvei/dot-emacs]].  I changed it so that it would work with
my current dotfiles repository structure and work asynchronously,
thanks to [[https://github.com/jwiegley/emacs-async][jwiegley/emacs-async]].

We can use =C-c C-v t= to run =org-babel-tangle=, which extracts the
code blocks from the current file into a source-specific file (in this
case a =.el=-file).

To avoid doing this each time a change is made we can add a function
to the =after-save-hook= ensuring to always tangle and byte-compile
the =org=-document after changes.

#+BEGIN_SRC emacs-lisp
(use-package async
  :commands (async-start)
  :defer 2)

(defun tangle-if-init ()
  "If the current buffer is 'init.org' the code-blocks are
    tangled, and the tangled file is compiled."

  (when (string-suffix-p "init.org" (buffer-file-name))
    (tangle-init)))

(defun tangle-init-sync ()
  (interactive)
  (message "Tangling init")
  ;; Avoid running hooks when tangling.
  (let ((prog-mode-hook nil)
        (src  (expand-file-name "init.org" user-emacs-directory))
        (dest (expand-file-name "init.el"  user-emacs-directory)))
    (require 'ob-tangle)
    (org-babel-tangle-file src dest)
    (if (byte-compile-file dest)
        (byte-compile-dest-file dest)
      (with-current-buffer byte-compile-log-buffer
        (buffer-string)))))

(defun tangle-init ()
  "Tangle init.org asynchronously."

  (interactive)
  (message "Tangling init")
  (async-start
   (symbol-function #'tangle-init-sync)
   (lambda (result)
     (message "Init tangling completed: %s" result))))
#+END_SRC

# Local Variables:
# eval: (when (fboundp #'tangle-if-init) (add-hook 'after-save-hook #'tangle-if-init))
# End:
* End

Start a server if possible.  A daemon is already a server.
#+BEGIN_SRC emacs-lisp
(run-with-idle-timer 2 nil (lambda ()
                             (unless (daemonp)
                               (require 'server)
                               (unless (server-running-p server-name)
                                 (server-start)))))
(setq gc-cons-threshold 800000
      file-name-handler-alist file-name-handler-alist-backup)
#+END_SRC