summary refs log tree commit diff stats
path: root/tag-emacs/emacs.d
diff options
context:
space:
mode:
Diffstat (limited to 'tag-emacs/emacs.d')
-rw-r--r--tag-emacs/emacs.d/Cask74
-rw-r--r--tag-emacs/emacs.d/elisp/ap-functions.el47
-rw-r--r--tag-emacs/emacs.d/elisp/php-electric.el218
-rw-r--r--tag-emacs/emacs.d/elisp/shuffle-lines.el20
-rw-r--r--tag-emacs/emacs.d/elisp/xrdb-mode.el544
-rw-r--r--tag-emacs/emacs.d/init.el1170
6 files changed, 2073 insertions, 0 deletions
diff --git a/tag-emacs/emacs.d/Cask b/tag-emacs/emacs.d/Cask
new file mode 100644
index 0000000..8742df0
--- /dev/null
+++ b/tag-emacs/emacs.d/Cask
@@ -0,0 +1,74 @@
+(source org)
+(source melpa)
+(source marmalade)
+(source gnu)
+
+(depends-on "ace-jump-mode")
+(depends-on "ag")
+(depends-on "auto-compile")
+(depends-on "auto-indent-mode")
+(depends-on "autopair")
+(depends-on "bind-key")
+(depends-on "cask")
+(depends-on "cdnjs")
+(depends-on "company")
+(depends-on "confluence")
+(depends-on "control-mode")
+(depends-on "dash")
+(depends-on "dash-at-point")
+(depends-on "deferred")
+(depends-on "diff-hl")
+(depends-on "diminish")
+(depends-on "dired+")
+(depends-on "discover")
+(depends-on "emmet-mode")
+(depends-on "epl")
+(depends-on "expand-region")
+(depends-on "f")
+(depends-on "flx")
+(depends-on "flx-ido")
+(depends-on "framemove")
+(depends-on "geiser")
+(depends-on "ggtags")
+(depends-on "git-commit-mode")
+(depends-on "git-rebase-mode")
+(depends-on "god-mode")
+(depends-on "haskell-mode")
+(depends-on "helm")
+(depends-on "ido-vertical-mode")
+(depends-on "jinja2-mode")
+(depends-on "js2-mode")
+(depends-on "lua-mode")
+(depends-on "magit")
+(depends-on "makey")
+(depends-on "multi-term")
+(depends-on "multiple-cursors")
+(depends-on "mustache-mode")
+(depends-on "nginx-mode")
+(depends-on "org-jira")
+(depends-on "org-journal")
+(depends-on "org-plus-contrib")
+(depends-on "packed")
+(depends-on "pallet")
+(depends-on "paredit")
+(depends-on "php-extras")
+(depends-on "php-mode")
+(depends-on "pkg-info")
+(depends-on "project-persist")
+(depends-on "projectile")
+(depends-on "puppet-mode")
+(depends-on "quickrun")
+(depends-on "redshank")
+(depends-on "s")
+(depends-on "simple-httpd")
+(depends-on "skewer-mode")
+(depends-on "smart-tab")
+(depends-on "smart-tabs-mode")
+(depends-on "smex")
+(depends-on "solarized-theme")
+(depends-on "tup-mode")
+(depends-on "undo-tree")
+(depends-on "use-package")
+(depends-on "web-mode")
+(depends-on "xml-rpc")
+(depends-on "yaml-mode")
\ No newline at end of file
diff --git a/tag-emacs/emacs.d/elisp/ap-functions.el b/tag-emacs/emacs.d/elisp/ap-functions.el
new file mode 100644
index 0000000..bdc7fae
--- /dev/null
+++ b/tag-emacs/emacs.d/elisp/ap-functions.el
@@ -0,0 +1,47 @@
+;;;###autoload
+(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 ""))))
+
+;;;###autoload
+(defun copy-rectangle (start end)
+  "Copy the region-rectangle."
+  (interactive "r")
+  (setq killed-rectangle (extract-rectangle start end)))
+
+;;;###autoload
+(defun eval-and-replace ()
+  "Replace the preceding sexp with its value."
+  (interactive)
+  (backward-kill-sexp)
+  (condition-case nil
+      (prin1 (eval (read (current-kill 0)))
+             (current-buffer))
+    (error (message "Invalid expression")
+           (insert (current-kill 0)))))
+
+;;;###autoload
+(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)))
+
+;;;###autoload
+(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)))
+
+(provide 'ap-functions)
diff --git a/tag-emacs/emacs.d/elisp/php-electric.el b/tag-emacs/emacs.d/elisp/php-electric.el
new file mode 100644
index 0000000..599b2b1
--- /dev/null
+++ b/tag-emacs/emacs.d/elisp/php-electric.el
@@ -0,0 +1,218 @@
+;; -*- Emacs-Lisp -*-
+;;
+;; php-electric.el --- electric submode for the php-mode
+;;
+;; Version: 1.0
+;; Release-Date: Sunday 04 March 2007
+;;
+;; Copyright (C) 2007
+;;   by Nikolay V. Nemshilov aka St. <nemshilov dog gmail . com>
+;;
+;;
+;; License
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 2
+;; of the License, or (at your option) any later version.
+;; 
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;; 
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+;;
+;;
+;; Features:
+;;   * autocompletion of the language contructions
+;;     such as if, for, foreach, etc blocks,
+;;
+;;   * autocompletion of classes, interfaces and functions
+;;     definitions
+;;
+;;   * autocompletion of the paired symbols, like [], (), "",''
+;;
+;;
+;; Usage:
+;;   Nothing magical, just place the file in a directory where
+;;   Emacs can find it, and write
+;;
+;;   (require 'php-electric)
+;;
+;;   in your configuration files ~/.emacs or wherever you keep it.
+;;   Then you can switch on/off the mode by the following command
+;;
+;;   M-x php-electric-mode <RET>
+;;
+;;   If you like to have it switched on automatically, you should
+;;   put the command in your php-mode hook or create new one,
+;;   like that
+;;
+;;   (add-hook 'php-mode-hook '(lambda () (php-electric-mode)))
+;;
+;;   That's it.
+;;
+;;
+;; Changelog:
+;;   Sunday 04 March 2007
+;;     The first version 1.0 has been came out.
+;;
+
+(defgroup php-electric nil
+  "Minor php-electric mode"
+  :group 'php)
+
+;; list of keywords which expandible by the {} pair
+(defconst php-electric-expandible-simple-re
+  "\\(try\\|else\\|do\\)")
+
+;; list of keywords which expandible with the (){} construction
+(defconst php-electric-expandible-as-struct-re
+  "\\(while\\|for\\|foreach\\|if\\|elseif\\|catch\\)")
+
+;; list of keywords which expandible with the name(){} construction
+(defconst php-electric-expandible-as-func-re
+  "\\(function\\)")
+
+;; list of keywords which expandible with the name{} construction
+(defconst php-electric-expandible-as-class-re
+  "\\(class\\|interface\\)")
+
+;; list of the paired chars
+(defvar php-electric-matching-delimeter-alist
+  '((?\[ . ?\])
+    (?\( . ?\))
+    (?\" . ?\")
+    (?\' . ?\')))
+
+;; the minor-mode definition
+(define-minor-mode php-electric-mode
+  "Minor electric-mode for the php-mode"
+  nil
+  "-El"
+  php-mode-map
+  (php-electric-keymap))
+
+;; list of accessible keys
+(defun php-electric-keymap()
+  (define-key php-mode-map " " 'php-electric-space)
+  (define-key php-mode-map "{" 'php-electric-curlies)
+  (define-key php-mode-map "(" 'php-electric-brackets)
+  (define-key php-mode-map "[" 'php-electric-matching-char)
+  (define-key php-mode-map "\"" 'php-electric-matching-char)
+  (define-key php-mode-map "\'" 'php-electric-matching-char))
+
+;; handler for the spaces insertions
+(defun php-electric-space(arg)
+  (interactive "P")
+  (self-insert-command (prefix-numeric-value arg))
+  (if (php-electric-is-code-at-point-p)
+      (if (php-electric-line-is-simple-expandible)
+	  ;; inserting just a pair of curleis
+	  (progn
+	    (insert "{")(php-electric-insert-new-line-and-statement-end))
+	(if (php-electric-line-is-expandible-as-struct)
+	    ;; inserting a structure definition
+	    (progn
+	      (if (not (char-equal ?\( (preceding-char)))
+		  ;; cmd () {  - style construction
+		  (progn
+		    (insert "(")(set-register 98 (point-marker))(insert ") {"))
+
+		;; cmd(  ){ - style construction
+		(progn
+		  (insert " ")(set-register 98 (point-marker))(insert " ){")))
+	      (php-electric-insert-new-line-and-statement-end)
+	      (jump-to-register 98)(set-register 98 nil))
+	  (if (php-electric-line-is-expandible-as-func)
+	      ;; inserting the function expanding
+	      (save-excursion
+		(insert "(){")(php-electric-insert-new-line-and-statement-end))
+	    (if (php-electric-line-is-expandible-as-class)
+		;; inserting the class expanding
+		(save-excursion
+		  (insert "{")(php-electric-insert-new-line-and-statement-end))))))))
+
+;; handler for the { chars
+(defun php-electric-curlies(arg)
+  (interactive "P")
+  (self-insert-command (prefix-numeric-value arg))
+  (if (php-electric-is-code-at-point-p)
+      (progn
+	(php-electric-insert-new-line-and-statement-end))))
+
+;; handler for the ( chars
+(defun php-electric-brackets(arg)
+  (interactive "P")
+
+  (if (php-electric-is-code-at-point-p)
+      ;; checking if it's a statement
+      (if (php-electric-line-is-expandible-as-struct)
+	  (progn (php-electric-space arg))
+	(progn (php-electric-matching-char arg)))
+    (self-insert-command (prefix-numeric-value arg))))
+
+;; handler for the paired chars, [], (), "", ''
+(defun php-electric-matching-char(arg)
+  (interactive "P")
+  (self-insert-command (prefix-numeric-value arg))
+  (if (php-electric-is-code-at-point-p)
+      (save-excursion
+	(insert (cdr (assoc last-command-char
+			    php-electric-matching-delimeter-alist))))))
+
+;; checks if the current pointer situated in a piece of code
+(defun php-electric-is-code-at-point-p()
+  (and php-electric-mode
+       (let* ((properties (text-properties-at (point))))
+	 (and (null (memq 'font-lock-string-face properties))
+	      (null (memq 'font-lock-comment-face properties))))))
+
+;; checks if the current line expandible with a simple {} construction
+(defun php-electric-line-is-simple-expandible()
+  (let* ((php-electric-expandible-simple-real-re
+	  (concat php-electric-expandible-simple-re "\\s-$")))
+    (save-excursion
+      (backward-word 1)
+      (looking-at php-electric-expandible-simple-real-re))))
+
+;; checks if the current line expandible with the (){} construction
+(defun php-electric-line-is-expandible-as-struct()
+  (let* ((php-electric-expandible-as-struct-real-re
+	  (concat php-electric-expandible-as-struct-re "[ ]*$"))
+	 (php-electric-expandible-as-struct-with-bracket-re
+	  (concat php-electric-expandible-as-struct-re "($")))
+    (save-excursion
+      (backward-word 1)
+      (or (looking-at php-electric-expandible-as-struct-real-re)
+	  (looking-at php-electric-expandible-as-struct-with-bracket-re)))))
+
+;; checks if the current line expandible with the name(){} construction
+(defun php-electric-line-is-expandible-as-func()
+  (let* ((php-electric-expandible-as-func-real-re
+	  (concat php-electric-expandible-as-func-re "\\s-$")))
+    (save-excursion
+      (backward-word 1)
+      (looking-at php-electric-expandible-as-func-real-re))))
+
+;; checks if the current line expandible with the name{} construction
+(defun php-electric-line-is-expandible-as-class()
+  (let* ((php-electric-expandible-as-class-real-re
+	  (concat php-electric-expandible-as-class-re "\\s-$")))
+    (save-excursion
+      (backward-word 1)
+      (looking-at php-electric-expandible-as-class-real-re))))
+
+;; "shortcut" to insert \n} construction
+(defun php-electric-insert-new-line-and-statement-end()
+  (newline-and-indent)(set-register 99 (point-marker))
+  (insert "\n}")(indent-according-to-mode)
+  (jump-to-register 99)(set-register 99 nil))
+
+
+(provide 'php-electric)
+
+;; end of the file
\ No newline at end of file
diff --git a/tag-emacs/emacs.d/elisp/shuffle-lines.el b/tag-emacs/emacs.d/elisp/shuffle-lines.el
new file mode 100644
index 0000000..be0a98f
--- /dev/null
+++ b/tag-emacs/emacs.d/elisp/shuffle-lines.el
@@ -0,0 +1,20 @@
+;;;###autoload
+(defun move-line-down ()
+    (interactive)
+    (let ((col (current-column)))
+        (save-excursion
+            (forward-line)
+            (transpose-lines 1))
+        (forward-line)
+        (move-to-column col)))
+
+;;;###autoload
+(defun move-line-up ()
+    (interactive)
+    (let ((col (current-column)))
+        (save-excursion
+            (forward-line)
+            (transpose-lines -1))
+        (move-to-column col)))
+
+(provide 'shuffle-lines)
diff --git a/tag-emacs/emacs.d/elisp/xrdb-mode.el b/tag-emacs/emacs.d/elisp/xrdb-mode.el
new file mode 100644
index 0000000..712f0cb
--- /dev/null
+++ b/tag-emacs/emacs.d/elisp/xrdb-mode.el
@@ -0,0 +1,544 @@
+;;; xrdb-mode.el --- mode for editing X resource database files
+
+;; Copyright (C) 1998,1999,2000 Free Software Foundation, Inc.
+
+;; Author:        1994-2003 Barry A. Warsaw
+;; Maintainer:    barry@python.org
+;; Created:       May 1994
+;; Keywords:      data languages
+
+(defconst xrdb-version "2.31"
+  "`xrdb-mode' version number.")
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 2
+;; of the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; This file provides a major mode for editing X resource database
+;; files.  It includes font-lock definitions and commands for
+;; controlling indentation, re-indenting by subdivisions, and loading
+;; and merging into the the resource database.
+;;
+;; To use, put the following in your .emacs:
+;;
+;; (autoload 'xrdb-mode "xrdb-mode" "Mode for editing X resource files" t)
+;;
+;; You may also want something like:
+;;
+;; (setq auto-mode-alist
+;;       (append '(("\\.Xdefaults$"    . xrdb-mode)
+;;                 ("\\.Xenvironment$" . xrdb-mode)
+;;                 ("\\.Xresources$"   . xrdb-mode)
+;;                 ("*.\\.ad$"         . xrdb-mode)
+;;                 )
+;;               auto-mode-alist))
+
+;;; Credits:
+;;
+;; The database merge feature was inspired by Joel N. Weber II.
+;;
+;; The canonical Web site for xrdb-mode is
+;; <http://www.python.org/emacs/>
+
+;;; Code:
+(require 'custom)
+
+
+
+(defgroup xrdb nil
+  "Support for editing X resource database files"
+  :group 'languages)
+
+(defcustom xrdb-mode-hook nil
+  "*Hook to be run when `xrdb-mode' is entered."
+  :type 'hook
+  :group 'xrdb)
+
+(defcustom xrdb-subdivide-by 'paragraph
+  "*Default alignment subdivision when re-indenting a region or buffer.
+This variable controls how much of the buffer is searched to find a
+goal column on which to align.  Every non-comment line in the region
+defined by this variable is scanned for the first `:' character on the
+line, and this character's column is the line's goal column.  The
+rightmost line goal column in the region is taken as the region's goal
+column.
+
+This variable can take one of the following symbol values:
+
+ `buffer'    - All lines in the buffer are scanned.  This is the
+               slowest option.
+
+ `paragraph' - All lines in the paragraph are scanned.  Paragraphs
+               are delimited by blank lines, comment lines, and page
+               delimiters.
+
+ `page'      - All lines in the page are scanned.  Pages are delimited
+               with `page-delimiter', usually ^L (control-L).
+
+ `line'      - Only the previous non-comment line is scanned.  This is
+               the fastest method.
+
+This variable is used by the various indentation commands, and can be
+overridden in those commands by using \\[universal-argument]."
+  :type '(radio (const :tag "Do not subdivide buffer" buffer)
+                (const :tag "Subdivide by paragraphs" paragraph)
+                (const :tag "Subdivide by pages" page)
+                (const :tag "Each line is independent" line))
+  :group 'xrdb)
+
+(defcustom xrdb-compress-whitespace nil
+  "*Collapse all whitespace to a single space after insertion of `:'."
+  :type 'boolean
+  :group 'xrdb)
+
+(defcustom xrdb-program "xrdb"
+  "*Program to run to load or merge resources in the X resource database."
+  :type 'string
+  :group 'xrdb)
+
+(defcustom xrdb-program-args '("-merge")
+  "*List of string arguments to pass to `xrdb-program'."
+  :type '(repeat string)
+  :group 'xrdb)
+
+(defvar xrdb-master-file nil
+  "If non-nil, merge in the named file instead of the buffer's file.
+The intent is to allow you to set this variable in the file's local
+variable section, e.g.:
+
+    ! Local Variables:
+    ! xrdb-master-file: \"Xdefaults\"
+    ! End:
+
+so that typing \\[xrdb-database-merge-buffer-or-region] in that buffer
+merges the named master file instead of the buffer's file.  Note that
+if the file name has a relative path, the `default-directory' for the
+buffer is prepended to come up with a file name.
+
+You may also want to set `xrdb-program-args' in the local variables
+section as well.")
+(make-variable-buffer-local 'xrdb-master-file)
+
+
+;; Non-user customizable
+(defconst xrdb-comment-re "^[ \t]*[!]"
+  "Regular expression describing the beginning of a comment line.")
+
+
+
+;; utilities
+(defun xrdb-point (position)
+  ;; Returns the value of point at certain commonly referenced POSITIONs.
+  ;; POSITION can be one of the following symbols:
+  ;;
+  ;; bol  -- beginning of line
+  ;; eol  -- end of line
+  ;; bod  -- beginning of defun
+  ;; boi  -- back to indentation
+  ;; ionl -- indentation of next line
+  ;; iopl -- indentation of previous line
+  ;; bonl -- beginning of next line
+  ;; bopl -- beginning of previous line
+  ;; bop  -- beginning of paragraph
+  ;; eop  -- end of paragraph
+  ;; bopg -- beginning of page
+  ;; eopg -- end of page
+  ;;
+  ;; This function does not modify point or mark.
+  (let ((here (point)))
+    (cond
+     ((eq position 'bod)  (beginning-of-defun))
+     ((eq position 'bol)  (beginning-of-line))
+     ((eq position 'eol)  (end-of-line))
+     ((eq position 'boi)  (back-to-indentation))
+     ((eq position 'bonl) (forward-line 1))
+     ((eq position 'bopl) (forward-line -1))
+     ((eq position 'bop)  (forward-paragraph -1))
+     ((eq position 'eop)  (forward-paragraph 1))
+     ((eq position 'bopg)  (forward-page -1))
+     ((eq position 'eopg)  (forward-page 1))
+     (t
+      (error "unknown buffer position requested: %s" position)))
+    (prog1
+        (point)
+      (goto-char here))
+    ))
+
+(defmacro xrdb-safe (&rest body)
+  ;; safely execute BODY, return nil if an error occurred
+  `( (condition-case nil
+         (progn (,@ body))
+       (error nil))))
+
+(defsubst xrdb-skip-to-separator ()
+  ;; skip forward from the beginning of the line to the separator
+  ;; character as given by xrdb-separator-char. Returns t if the
+  ;; char was found, otherwise, nil.
+  (beginning-of-line)
+  (skip-chars-forward "^:" (xrdb-point 'eol))
+  (and (eq (char-after) ?:)
+       (current-column)))
+
+(defsubst xrdb-in-comment-p (&optional lim)
+  (let* ((lim (or lim (xrdb-point 'bod)))
+         (state (parse-partial-sexp lim (point))))
+    (nth 4 state)))
+
+(defsubst xrdb-boi-col ()
+  (let ((here (point)))
+    (goto-char (xrdb-point 'boi))
+    (prog1
+        (current-column)
+      (goto-char here))))
+
+(defvar xrdb-prompt-history nil)
+
+(defun xrdb-prompt-for-subdivision ()
+  (let ((options '(("buffer" . buffer)
+                   ("paragraphs" . paragraph)
+                   ("pages" . page)
+                   ("lines" . line)))
+        (completion-ignore-case t))
+    (cdr (assoc
+          (completing-read "Subdivide alignment by? " options nil t
+                           (cons (format "%s" xrdb-subdivide-by) 0)
+                           'xrdb-prompt-history)
+          options))))
+
+
+;; commands
+(defun xrdb-electric-separator (arg)
+  "Insert a colon, and possibly indent line.
+Numeric argument inserts that many separators.  If the numeric
+argument is not given, or is 1, and the separator is not inserted in a
+comment, then the line is indented according to `xrdb-subdivide-by'."
+  (interactive "P")
+  (self-insert-command (prefix-numeric-value arg))
+  ;; only do electric behavior if arg is not given
+  (or arg
+      (xrdb-in-comment-p)
+      (xrdb-indent-line))
+  ;; compress whitespace
+  (and xrdb-compress-whitespace
+       (just-one-space)))
+
+(defun xrdb-electric-bang (arg)
+  "Insert an exclamation point to start a comment.
+Numeric argument inserts that many exclamation characters.  If the
+numeric argument is not given, or is 1, and the bang character is the
+first character on a line, the line is indented to column zero."
+  (interactive "P")
+  (let ((how-many (prefix-numeric-value arg)))
+    (self-insert-command how-many)
+    (save-excursion
+      (if (and (= how-many 1)
+               (xrdb-in-comment-p)
+               (memq (char-before (xrdb-point 'boi)) '(?\n nil)))
+          (indent-line-to 0)))
+    ))
+
+
+(defun xrdb-indent-line (&optional arg)
+  "Align the current line according to `xrdb-subdivide-by'.
+With optional \\[universal-argument], prompt for subdivision."
+  (interactive "P")
+  (xrdb-align-to-column
+   (xrdb-guess-goal-column (if arg
+                               (xrdb-prompt-for-subdivision)
+                             xrdb-subdivide-by))
+   (xrdb-point 'bol)
+   (xrdb-point 'bonl)))
+
+(defun xrdb-indent-region (start end &optional arg)
+  "Indent all lines in the region according to `xrdb-subdivide-by'.
+With optional \\[universal-argument], prompt for subdivision."
+  (interactive "r\nP")
+  (xrdb-align-to-column
+   (xrdb-guess-goal-column (if arg
+                               (xrdb-prompt-for-subdivision)
+                             xrdb-subdivide-by))
+   start end))
+
+(defun xrdb-indent-page (&optional arg)
+  "Indent all lines in the page according to `xrdb-subdivide-by'.
+With optional \\[universal-argument], prompt for subdivision."
+  (interactive "P")
+  (xrdb-align-to-column
+   (xrdb-guess-goal-column (if arg
+                               (xrdb-prompt-for-subdivision)
+                             xrdb-subdivide-by))
+   (xrdb-point 'bopg)
+   (xrdb-point 'eopg)))
+
+(defun xrdb-indent-paragraph (&optional arg)
+  "Indent all lines in the paragraph according to `xrdb-subdivide-by'.
+With optional \\[universal-argument], prompt for subdivision."
+  (interactive "P")
+  (xrdb-align-to-column
+   (xrdb-guess-goal-column (if arg
+                               (xrdb-prompt-for-subdivision)
+                             xrdb-subdivide-by))
+   (xrdb-point 'bop)
+   (xrdb-point 'eop)))
+
+(defun xrdb-indent-buffer (&optional arg)
+  "Indent all lines in the buffer according to `xrdb-subdivide-by'.
+With optional \\[universal-argument], prompt for subdivision."
+  (interactive "P")
+  (let ((subdivide-by (if arg
+                          (xrdb-prompt-for-subdivision)
+                        xrdb-subdivide-by)))
+    (save-excursion
+      (beginning-of-buffer)
+      (if (eq subdivide-by 'buffer)
+          (xrdb-align-to-column (xrdb-guess-goal-column 'buffer)
+                                (point-min) (point-max))
+        (let (mvfwdfunc indentfunc)
+          (cond
+           ((eq subdivide-by 'paragraph)
+            (setq mvfwdfunc 'forward-paragraph
+                  indentfunc 'xrdb-indent-paragraph))
+           ((eq subdivide-by 'page)
+            (setq mvfwdfunc 'forward-page
+                  indentfunc 'xrdb-indent-page))
+           ((eq subdivide-by 'line)
+            (setq mvfwdfunc 'forward-line
+                  indentfunc 'xrdb-indent-page))
+           (t (error "Illegal alignment subdivision: %s" subdivide-by))
+           )
+          (while (< (point) (point-max))
+            (funcall indentfunc)
+            (funcall mvfwdfunc 1))
+          )))))
+
+
+;; internal alignment functions
+(defun xrdb-align-to-column (goalcol &optional start end)
+  (let ((start (or start (xrdb-point 'bol)))
+        (end (or end (xrdb-point 'bonl))))
+    (save-excursion
+      (save-restriction
+        (narrow-to-region start end)
+        (beginning-of-buffer)
+        (while (< (point) (point-max))
+          (if (and (not (looking-at xrdb-comment-re))
+                   (xrdb-skip-to-separator))
+              (indent-line-to (max 0 (+ goalcol
+                                        (- (current-column))
+                                        (xrdb-boi-col))
+                                   )))
+          (forward-line 1))
+        ))))
+
+(defun xrdb-guess-goal-column (subdivide-by)
+  ;; Returns the goal column of the current line based on SUBDIVIDE-BY,
+  ;; which can be any value allowed by `xrdb-subdivide-by'.
+  (let ((here (point))
+        (goalcol 0))
+    (save-restriction
+      (cond
+       ((eq subdivide-by 'line)
+        (while (and (zerop (forward-line -1))
+                    (or (looking-at xrdb-comment-re)
+                        (not (xrdb-skip-to-separator)))))
+        ;; maybe we didn't find one
+        (if (not (xrdb-skip-to-separator))
+            (goto-char here))
+        (narrow-to-region (xrdb-point 'bol) (xrdb-point 'bonl)))
+       ((eq subdivide-by 'page)
+        (narrow-to-page))
+       ((eq subdivide-by 'paragraph)
+        (narrow-to-region (xrdb-point 'bop) (xrdb-point 'eop)))
+       ((eq subdivide-by 'buffer))
+       (t (error "Illegal alignment subdivision: %s" subdivide-by)))
+      (goto-char (point-min))
+      (while (< (point) (point-max))
+        (if (and (not (looking-at xrdb-comment-re))
+                 (xrdb-skip-to-separator))
+            (setq goalcol (max goalcol (- (current-column) (xrdb-boi-col)))))
+        (forward-line 1)))
+    (goto-char here)
+    goalcol))
+
+
+
+;; major-mode stuff
+(defvar xrdb-mode-abbrev-table nil
+  "Abbreviation table used in `xrdb-mode' buffers.")
+(define-abbrev-table 'xrdb-mode-abbrev-table ())
+
+
+(defvar xrdb-mode-syntax-table nil
+  "Syntax table used in `xrdb-mode' buffers.")
+(if xrdb-mode-syntax-table
+    nil
+  (setq xrdb-mode-syntax-table (make-syntax-table))
+  (modify-syntax-entry ?!  "<"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?\\ "\\"   xrdb-mode-syntax-table)
+  (modify-syntax-entry ?\n ">"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?/  ". 14" xrdb-mode-syntax-table)
+  (modify-syntax-entry ?*  "_ 23" xrdb-mode-syntax-table)
+  (modify-syntax-entry ?.  "_"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?#  "_"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ??  "_"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?<  "("    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?>  ")"    xrdb-mode-syntax-table)
+  )
+
+
+(defvar xrdb-mode-map ()
+  "Keymap used in `xrdb-mode' buffers.")
+(if xrdb-mode-map
+    ()
+  (setq xrdb-mode-map (make-sparse-keymap))
+  ;; make the separator key electric
+  (define-key xrdb-mode-map ":"        'xrdb-electric-separator)
+  (define-key xrdb-mode-map "!"        'xrdb-electric-bang)
+  (define-key xrdb-mode-map "\t"       'xrdb-indent-line)
+  (define-key xrdb-mode-map "\C-c\C-a" 'xrdb-indent-buffer)
+  (define-key xrdb-mode-map "\C-c\C-b" 'xrdb-submit-bug-report)
+  (define-key xrdb-mode-map "\C-c\C-c" 'xrdb-database-merge-buffer-or-region)
+  (define-key xrdb-mode-map "\C-c\C-p" 'xrdb-indent-paragraph)
+  (define-key xrdb-mode-map "\C-c\["   'xrdb-indent-page)
+  (define-key xrdb-mode-map "\C-c\C-r" 'xrdb-indent-region)
+  )
+
+;;;###autoload
+(defun xrdb-mode ()
+  "Major mode for editing xrdb config files"
+  (interactive)
+  (kill-all-local-variables)
+  (set-syntax-table xrdb-mode-syntax-table)
+  (setq major-mode 'xrdb-mode
+        mode-name "xrdb"
+        local-abbrev-table xrdb-mode-abbrev-table)
+  (use-local-map xrdb-mode-map)
+  (setq font-lock-defaults '(xrdb-font-lock-keywords))
+  ;; local variables
+  (make-local-variable 'parse-sexp-ignore-comments)
+  (make-local-variable 'comment-start-skip)
+  (make-local-variable 'comment-start)
+  (make-local-variable 'comment-end)
+  (make-local-variable 'paragraph-start)
+  (make-local-variable 'paragraph-separate)
+  (make-local-variable 'paragraph-ignore-fill-prefix)
+  (make-local-variable 'indent-region-function)
+  ;; now set their values
+  (setq parse-sexp-ignore-comments t
+        comment-start-skip "![ \t]*"
+        comment-start "! "
+        comment-end "")
+  (setq indent-region-function 'xrdb-indent-region
+        paragraph-ignore-fill-prefix t
+        paragraph-start (concat "^[ \t]*$\\|^[ \t]*[!]\\|" page-delimiter)
+        paragraph-separate paragraph-start)
+  (run-hooks 'xrdb-mode-hook))
+
+
+
+;; faces and font-locking
+(defvar xrdb-option-name-face 'xrdb-option-name-face
+  "Face for option name on a line in an X resource db file")
+
+(defvar xrdb-option-value-face 'xrdb-option-value-face
+  "Face for option value on a line in an X resource db file")
+
+(make-face 'xrdb-option-name-face)
+(make-face 'xrdb-option-value-face)
+
+(defun xrdb-font-lock-mode-hook ()
+  (or (face-differs-from-default-p 'xrdb-option-name-face)
+      (copy-face 'font-lock-keyword-face 'xrdb-option-name-face))
+  (or (face-differs-from-default-p 'xrdb-option-value-face)
+      (copy-face 'font-lock-string-face 'xrdb-option-value-face))
+  (remove-hook 'font-lock-mode-hook 'xrdb-font-lock-mode-hook))
+(add-hook 'font-lock-mode-hook 'xrdb-font-lock-mode-hook)
+
+(defvar xrdb-font-lock-keywords
+  (list '("^[ \t]*\\([^\n:]*:\\)[ \t]*\\(.*\\)$"
+          (1 xrdb-option-name-face)
+          (2 xrdb-option-value-face)))
+  "Additional expressions to highlight in X resource db mode.")
+(put 'xrdb-mode 'font-lock-defaults '(xrdb-font-lock-keywords))
+
+
+
+;; merging and manipulating the X resource database
+(defun xrdb-database-merge-buffer-or-region (start end)
+  "Merge the current buffer's resources into the X resource database.
+
+`xrdb-program' is the program to actually call, with the arguments
+specified in `xrdb-program-args'.  This latter can be set to do either
+a merge or a load, etc.  Also, if the file local variable
+`xrdb-master-file' is non-nil, then it is merged instead of the
+buffer's file.
+
+If the current region is active, it is merged instead of the buffer,
+and this overrides any use of `xrdb-master-file'."
+  (interactive
+   ;; the idea here is that if the region is inactive, start and end
+   ;; will be nil, if not passed in programmatically
+   (list (xrdb-safe (and (mark) (region-beginning)))
+         (xrdb-safe (and (mark) (region-end)))))
+  (message "Merging with args: %s..." xrdb-program-args)
+  (let ((outbuf (get-buffer-create "*Shell Command Output*")))
+    ;; I prefer the XEmacs way of doing this, but this is the easiest
+    ;; way to work in both XEmacs and Emacs.
+    (with-current-buffer outbuf (erase-buffer))
+    (cond
+     ((and start end)
+      (apply 'call-process-region start end xrdb-program nil outbuf t
+             xrdb-program-args))
+     (xrdb-master-file
+      (apply 'call-process xrdb-program xrdb-master-file outbuf t
+             xrdb-program-args))
+     (t
+      (apply 'call-process-region (point-min) (point-max) xrdb-program
+             nil outbuf t xrdb-program-args)))
+    (if (not (zerop (with-current-buffer outbuf (buffer-size))))
+        (pop-to-buffer outbuf)))
+  (message "Merging... done"))
+
+
+
+;; submitting bug reports
+
+(defconst xrdb-mode-help-address "tools-help@python.org"
+  "Address for xrdb-mode bug reports.")
+
+(defun xrdb-submit-bug-report ()
+  "Submit via mail a bug report on xrdb-mode."
+  (interactive)
+  ;; load in reporter
+  (require 'reporter)
+  (let ((reporter-prompt-for-summary-p t)
+        (varlist '(xrdb-subdivide-by
+                   xrdb-mode-hook
+                   xrdb-compress-whitespace
+                   )))
+    (and (if (y-or-n-p "Do you want to submit a report on xrdb-mode? ")
+             t
+           (message "")
+           nil)
+         (require 'reporter)
+         (reporter-submit-bug-report
+          xrdb-mode-help-address
+          (format "xrdb-mode %s" xrdb-version)
+          varlist nil nil "Dear Barry,")
+         )))
+
+
+(provide 'xrdb-mode)
+;;; xrdb-mode.el ends here
diff --git a/tag-emacs/emacs.d/init.el b/tag-emacs/emacs.d/init.el
new file mode 100644
index 0000000..76505ad
--- /dev/null
+++ b/tag-emacs/emacs.d/init.el
@@ -0,0 +1,1170 @@
+;; -*- lexical-binding: t; -*-
+;;;; Startup
+;; Do not merge echo-area-message sexp
+(setq inhibit-startup-echo-area-message "alan")
+(setq inhibit-startup-screen t
+      initial-scratch-message ""
+      initial-major-mode 'text-mode
+      user-mail-address "alan@alanpearce.co.uk"
+      user-full-name "Alan Pearce"
+      custom-file "~/.emacs.d/custom.el")
+
+(load custom-file :noerror)
+
+;;; Allow lisps to use a common setup. I don't know why they don't have some lispy mode as their parent, but this is close enough
+(defcustom lisp-common-mode-hook nil
+  "Hook run when entering any Lisp mode."
+  :type 'hook
+  :group 'lisp)
+
+;;;; Environment & Location
+
+(defun env/get-location ()
+  "Return the physical location of the system, or `nil' if unknown"
+  (if (executable-find "netctl")
+      (catch 'found
+        (mapc (lambda (line)
+                (cond
+                 ((string-prefix-p "* home" line) (throw 'found 'home))
+                 ((string-prefix-p "* work" line) (throw 'found 'work))))
+              (process-lines "netctl" "list"))
+        nil)))
+
+(defun env/get-system-type ()
+  "Return the type of computer that is running"
+  (cond
+   ((string-prefix-p "prefect" system-name) 'desktop)
+   ((string-prefix-p "server"  system-name) 'server)
+   ((string-prefix-p "sheldon" system-name) 'laptop)))
+
+(defvar env/location (env/get-location)
+  "The type of location the system is located in
+Values: `work', `home'")
+
+(defvar env/system-type (env/get-system-type)
+  "The type of computer Emacs is running on
+Values: `desktop', `server', `laptop'")
+
+(defun env/recheck-location ()
+  (interactive)
+  (setq env/location (env/get-location)))
+
+(defvar *init-file*
+  (when user-init-file
+    (expand-file-name "init.el"
+                      (file-name-directory (file-truename user-init-file))))
+  "Where the emacs init file really is, passing through symlinks.")
+
+;;;; Package Management
+(add-to-list 'load-path (expand-file-name "elisp/" user-emacs-directory))
+
+(let ((cask-dir (expand-file-name "~/.cask")))
+  (if (file-exists-p cask-dir)
+      (progn
+        (add-to-list 'load-path cask-dir)
+        (require 'cask)
+        (cask-initialize))
+    (eval-and-compile
+      (setq package-archives '(("gnu"       . "http://elpa.gnu.org/packages/")
+                               ("marmalade" . "http://marmalade-repo.org/packages/")
+                               ("melpa"     . "http://melpa.milkbox.net/packages/")
+                               ("org"       . "http://orgmode.org/elpa/")))
+      (package-initialize))
+
+    (when (not package-archive-contents)
+      (package-refresh-contents))
+
+    (mapc (lambda (package-name)
+            (unless (package-installed-p package-name)
+              (package-install package-name)))
+          '(bind-key
+            diminish
+            use-package))))
+
+(require 'use-package)
+
+;;;; Style
+
+(use-package linum
+  :config (setq linum-format " %4d "))
+
+(use-package highlight-symbol
+  :disabled t
+  :config (setq highlight-symbol-idle-delay 0.2))
+
+(use-package whitespace
+  :config (setq whitespace-style
+                '(face
+                  space
+                  tabs
+                  trailing
+                  newline
+                  empty
+                  space-after-tab
+                  tab-mark
+                  space-before-tab
+                  indentation
+                  indentation::space
+                  indentation::tabs)))
+
+(global-font-lock-mode t)
+;; Allow font-lock-mode to do background parsing
+(setq jit-lock-stealth-time 1
+      jit-lock-stealth-load 100
+      jit-lock-chunk-size 1000
+      jit-lock-defer-time 0.01)
+
+(use-package solarized-theme
+  :config (load-theme 'solarized-light t))
+
+(when (or (display-graphic-p)
+          (daemonp))
+
+  (defun use-variable-fonts ()
+    (interactive)
+    (variable-pitch-mode)
+    (setq cursor-type 'bar))
+
+  (cond
+   ((eq window-system 'w32)
+    (let* ((font-size 10)
+           (font-list (font-family-list))
+           (mono-face (cond
+                       ((member "Liberation Mono" font-list)
+                        "Liberation Mono")
+                       ((member "Liberation Sans Mono" font-list)
+                        "Liberation Sans Mono")
+                       ((member "Consolas" font-list)
+                        "Consolas")))
+           (variable-face "Segoe UI")
+           (default-font (concat mono-face "-" (number-to-string font-size))))
+        (when mono-face
+		  (add-to-list 'default-frame-alist `(font . ,default-font))
+		  (set-face-font 'fixed-pitch default-font))
+        (when variable-face
+		  (set-face-font 'variable-pitch (concat variable-face "-"
+                                                   (number-to-string (1+ font-size)))))))
+   ((eq system-type 'darwin)
+    (let* ((font-size 14)
+           (mono-face "Droid Sans Mono")
+           (variable-face "Helvetica_Neue")
+           (default-font (concat mono-face "-" (number-to-string font-size))))
+        (when mono-face
+          (add-to-list 'default-frame-alist `(font . ,default-font)))
+        (when (and variable-face (display-graphic-p))
+          (set-face-font 'variable-pitch (concat variable-face "-"
+                                                 (number-to-string (1+ font-size)))))))))
+
+(let* ((font-height (face-attribute 'default :height))
+	   (small-font-height (max 1 (floor (* .917 font-height)))))
+    (mapc (lambda (item)
+			  (put (car item) 'customized-face (cadr item))
+			  (face-spec-set (car item) (cadr item)))
+          `((linum
+             ((t (:height ,small-font-height
+                          :foreground unspecified
+                          :inherit fringe
+                          :overline nil
+                          :slant normal))))
+            (vertical-border
+             ((t (:foreground unspecified
+                              :background unspecified
+                              :inherit file-name-shadow))))
+            (font-lock-comment-face
+             ((t (:slant normal))))
+            (font-lock-doc-face
+             ((t (:slant normal))))
+            (popup-face
+             ((t (:background unspecified
+                              :foreground unspecified
+                              :inherit linum
+                              :height ,font-height))))
+            (popup-scroll-bar-foreground-face
+             ((t (:background unspecified
+                              :inherit region))))
+            (popup-scroll-bar-background-face
+             ((t (:background unspecified
+                              :inherit popup-face))))
+            (ac-completion-face
+             ((t (:background unspecified
+                              :foreground unspecified
+                              :inherit popup-face))))
+            (ac-candidate-face
+             ((t (:background unspecified
+                              :foreground unspecified
+                              :inherit linum
+                              :height ,font-height))))
+            (ac-selection-face
+             ((t (:background unspecified
+                              :foreground unspecified
+                              :inherit font-lock-variable-name-face
+                              :inverse-video t))))
+            (ac-candidate-mouse-face
+             ((t (:background unspecified
+                              :foreground unspecified
+                              :inherit region))))
+            (ac-dabbrev-menu-face
+             ((t (:background unspecified
+                              :foreground unspecified
+                              :inherit popup-face))))
+            (ac-dabbrev-selection-face
+             ((t (:background unspecified
+                              :foreground unspecified
+                              :inherit ac-selection-face))))
+            (flymake-warnline
+             ((t (:background unspecified
+                              :foreground unspecified
+                              :inherit font-lock-preprocessor-face))))
+            (org-table ((t (:inherit 'fixed-pitch))))
+            (org-formula ((t (:foreground "Firebrick"
+                                          :inherit 'fixed-pitch))))
+            (org-done ((t (:weight normal
+                                   :strike-through t))))
+            (org-headline-done ((t (:strike-through t)))))))
+
+;;;; Autosaves & Backups
+(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))
+        auto-save-file-name-transforms `((".*" ,temporary-file-directory t))
+        backup-by-copying-when-linked t
+        backup-by-copying-when-mismatch t))
+
+;;;; Buffers
+
+(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)))))
+
+(use-package uniquify
+  :config (progn
+            (setq uniquify-buffer-name-style 'reverse
+                  uniquify-separator "/"
+                  uniquify-after-kill-buffer-p t
+                  uniquify-ignore-buffers-re "^\\*")))
+
+(use-package fancy-narrow
+  :config (fancy-narrow-mode 1))
+
+;;;; Communication
+
+(use-package erc
+  :config (progn
+            (setq erc-user-full-name "Alan Pearce"
+                  erc-email-userid "alan@alanpearce.co.uk"
+                  erc-echo-notice-in-minibuffer t
+                  erc-keywords '("alanpearce" "lethalrocks")
+                  erc-autojoin-channels-alist
+                  '(("freenode.net" "#emacs" "##freebsd" "#bufferbloat" "#openwrt" "#lojban" "#zfs" "#introverts")
+                    ("what.cd" "#what.cd")
+                    ("beusergroup.co.uk" "#be")))
+            (add-to-list 'erc-modules 'scrolltobottom)
+            (add-to-list 'erc-modules 'autojoin)
+            (add-to-list 'erc-modules 'match)))
+
+(setq message-send-mail-function 'smtpmail-send-it)
+(setq smtpmail-smtp-server "external.home"
+      smtpmail-smtp-service 587)
+
+(use-package mu4e
+  :if (and (eq env/location 'home)
+           (eq env/system-type 'desktop))
+  :load-path "/usr/share/emacs/site-lisp/mu4e"
+  :commands (mu4e)
+  :config (progn
+            (setq mu4e-get-mail-command "true"
+                  mu4e-update-interval 300
+                  mu4e-sent-folder "/alanpearce/Sent"
+                  mu4e-drafts-folder "/alanpearce/Drafts"
+                  mu4e-refile-folder "/alanpearce/Archive")
+            (bind-key "q" #'bury-buffer mu4e-main-mode-map)
+            (bind-key "d" #'mu4e-headers-mark-for-delete mu4e-headers-mode-map)))
+
+;;;; Completion
+
+(setq completion-styles '(basic initials partial-completion substring)
+      completion-ignore-case t)
+
+(use-package smart-tab
+  :init (global-smart-tab-mode)
+  :config (progn
+            (nconc smart-tab-completion-functions-alist '((php-mode . php-complete-function)))
+            (diminish 'smart-tab-mode "")))
+
+(use-package company
+  :commands (company-mode)
+  :bind (("C-<tab>" . company-complete))
+  :init (progn
+          (add-hook 'prog-mode-hook #'company-mode)
+          (setq company-idle-delay .3
+                company-begin-commands '(self-insert-command))))
+
+;;;; Dates & Times
+
+(use-package calendar
+  :config (progn
+            (setq calendar-week-start-day 1)
+            (calendar-set-date-style 'iso)))
+
+(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))))
+
+;;;; Directory browsing
+(use-package dired
+  :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-bind-jump nil)
+            (when (eq system-type 'darwin)
+              (setq insert-directory-program "/usr/local/bin/gls"))
+            (put 'dired-find-alternate-file 'disabled nil)))
+
+(use-package dired+
+  :config (progn
+            (diredp-toggle-find-file-reuse-dir 1)
+            (dired-omit-mode 1)
+            (setq dired-omit-files "#\\|\\.$")))
+
+;;;; Documentation
+
+(add-to-list 'Info-default-directory-list
+             (concat user-emacs-directory
+                     "info"))
+
+(use-package which-func
+  :init (which-function-mode)
+  :config (setq which-func-modes t))
+
+;;;; Files
+
+(prefer-coding-system 'utf-8-auto-unix)
+(set-default-coding-systems 'utf-8-auto-unix)
+(setq-default buffer-file-coding-system 'utf-8-auto-unix)
+(global-auto-revert-mode 1)
+
+(add-hook 'before-save-hook #'delete-trailing-whitespace)
+
+(defun rename-current-buffer-file ()
+  "Renames current buffer and file it is visiting."
+  (interactive)
+  (let ((name (buffer-name))
+        (filename (buffer-file-name)))
+    (if (not (and filename (file-exists-p filename)))
+        (error "Buffer '%s' is not visiting a file!" name)
+      (let ((new-name (read-file-name "New name: " filename)))
+        (if (get-buffer new-name)
+            (error "A buffer named '%s' already exists!" new-name)
+          (cond
+           ((vc-backend filename) (vc-rename-file filename new-name))
+           (t (rename-file filename new-name t)
+              (rename-buffer new-name)
+              (set-visited-file-name new-name)
+              (set-buffer-modified-p nil)
+              (message "File '%s' successfully renamed to '%s'"
+                       name (file-name-nondirectory new-name)))))))))
+
+(defun delete-current-buffer-file ()
+  "Removes file connected to current buffer and kills buffer."
+  (interactive)
+  (let ((filename (buffer-file-name))
+        (buffer (current-buffer)))
+    (if (not (and filename (file-exists-p filename)))
+        (ido-kill-buffer)
+      (when (yes-or-no-p "Are you sure you want to remove this file? ")
+        (if (vc-backend filename)
+            (vc-delete-file filename)
+          (delete-file filename)
+          (kill-buffer buffer)
+          (message "File '%s' successfully removed" filename))))))
+
+(use-package recentf
+  :init (progn (setq recentf-auto-cleanup 'never
+                     recentf-save-file (expand-file-name "recentf" user-emacs-directory))
+               (recentf-mode 1)))
+
+(use-package saveplace
+  :config (progn (setq-default save-place t)
+                 (setq save-place-file (expand-file-name ".saveplace" user-emacs-directory))))
+
+(use-package tramp
+  :config (progn
+            (setq tramp-default-method (if (eq system-type 'windows-nt) "plinkx" "ssh")
+                  tramp-default-user-alist '(("\\`su\\(do\\)?\\'" nil "root") (nil nil "alan"))
+                  tramp-backup-directory-alist backup-directory-alist
+                  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))
+            (add-to-list 'tramp-default-proxies-alist '("router" nil nil))))
+
+(use-package tramp-sh
+  :config (progn
+            (add-to-list 'tramp-remote-path "/usr/local/sbin")
+            (add-to-list 'tramp-remote-path "~/bin")))
+
+(use-package ediff
+  :config (progn
+            (setq ediff-split-window-function 'split-window-horizontally
+                  ediff-window-setup-function 'ediff-setup-windows-plain)))
+
+;;;; Indentation
+
+(setq-default tab-width 4
+              indent-tabs-mode t)
+(setq tab-stop-list
+      ;; (mapcar (lambda (x)
+      ;;           (* 4 x))
+      ;;         (number-sequence 1 (/ 120 4)))
+      '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120)
+      tab-always-indent 'complete)
+
+(use-package auto-indent-mode
+  :commands (auto-indent-minor-mode
+             auto-indent-mode)
+  :config (progn
+            (setq auto-indent-key-for-end-of-line-then-newline "<C-return>"
+                  auto-indent-key-for-end-of-line-insert-char-then-newline "<C-S-return>"
+                  auto-indent-blank-lines-on-move nil
+                  auto-indent-assign-indent-level 4
+                  auto-indent-backward-delete-char-behavior nil
+                  auto-indent-delete-trailing-whitespace-on-save-file t
+                  auto-indent-mode-untabify-on-yank-or-paste nil)
+            (auto-indent-global-mode)
+            (defun lisp-auto-indent-mode ()
+              (set (make-local-variable 'auto-indent-assign-indent-level) 2))
+            (add-hook 'lisp-common-mode-hook #'lisp-auto-indent-mode)))
+
+(use-package smart-tabs-mode
+  :commands (smart-tabs-mode
+             smart-tabs-mode-enable
+             smart-tabs-advice)
+  :config (progn
+            (smart-tabs-insinuate 'c 'javascript 'cperl 'python)
+            (add-hook 'php-mode-hook #'smart-tabs-mode-enable)))
+
+;;;; Keybindings
+
+(when (eq system-type 'darwin)
+  (set-keyboard-coding-system nil)
+  (setq mac-option-modifier 'meta
+        mac-right-option-modifier 'left
+        mac-control-modifier 'control
+        mac-right-control-modifier 'left
+        mac-command-modifier 'super
+        mac-right-command-modifier 'left
+        mac-function-modifier 'hyper))
+
+(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" #'ucs-insert)
+(bind-key "M-/" #'hippie-expand)
+
+(unbind-key "s-h")
+(unbind-key "s-n")
+(unbind-key "s-p")
+(unbind-key "s-w")
+
+(bind-key "s-x" (define-prefix-command 'super-x-map))
+
+(bind-key "s-," (lambda ()
+                  (interactive)
+                  (jump-to-register ?e)))
+(set-register ?e `(file . ,*init-file*))
+(set-register ?z `(file . ,(expand-file-name ".zshrc" "~")))
+
+;; Enable narrowing functions C-x n
+(put 'narrow-to-defun  'disabled nil)
+(put 'narrow-to-page   'disabled nil)
+(put 'narrow-to-region 'disabled nil)
+
+;;;; Minibuffer
+
+(setq enable-recursive-minibuffers t)
+(minibuffer-depth-indicate-mode t)
+
+(if (daemonp)
+    (defalias 'exit-emacs #'delete-frame)
+  (defalias 'exit-emacs #'save-buffers-kill-emacs))
+
+(use-package lacarte
+  :bind (("M-`" . lacarte-execute-menu-command)))
+
+(use-package helm-config
+  :bind (("C-x i"   . helm-imenu))
+  :config (setq helm-idle-delay .1
+                helm-input-idle-delay .1))
+
+(use-package ido
+  :bind (("C-x b"   . ido-switch-buffer))
+  :init (progn
+          (setq ido-save-directory-list-file (expand-file-name "ido-state" user-emacs-directory))
+          (bind-key* "C-x C-f" #'ido-find-file)
+          (ido-mode 1))
+  :config (progn
+            (setq ido-auto-merge-delay-time 99999
+                  ido-enable-flex-matching t)
+
+            (ido-init-completion-maps)
+            (defun ido-manual-merge ()
+              (interactive)
+              (ido-initiate-auto-merge (current-buffer)))
+            (bind-key "C-c C-s" #'ido-manual-merge ido-file-dir-completion-map)))
+
+(defun ap/ido-projectile-switch-buffer-dwim (force-ido)
+  (interactive "p")
+  (if (and (projectile-project-p) (eq force-ido 1))
+      (call-interactively #'projectile-switch-to-buffer)
+    (call-interactively #'ido-switch-buffer)))
+
+(bind-key "s-x b" #'ap/ido-projectile-switch-buffer-dwim)
+(bind-key "s-x s-b" #'ap/ido-projectile-switch-buffer-dwim)
+
+(use-package ido-vertical-mode
+  :config (ido-vertical-mode 1))
+
+(use-package flx-ido
+  :init (progn
+          (flx-ido-mode 1)))
+
+(use-package smex
+  :bind (("M-x" . smex)
+         ("<apps>" . smex)
+         ("<menu>" . smex)
+         ("M-X" . smex-major-mode-commands)
+         ("C-c M-x" . execute-extended-command))
+  :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"))
+          (smex-initialize)))
+
+;;;; Modeline
+
+(column-number-mode t)
+(size-indication-mode t)
+
+;;;; Modes
+
+;;;; systemd files
+(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))
+
+(use-package xrdb-mode
+  :mode (("\\.Xdefaults\\'" . xrdb-mode)
+         ("\\.Xresources\\'" . xrdb-mode)))
+
+(use-package haskell-mode
+  :mode (("\\.hs\\'" . haskell-mode)
+         ("xmobarrc\\'" . haskell-mode)))
+
+(use-package nginx-mode
+  :mode (("nginx.conf" . nginx-mode)))
+
+(use-package lua-mode
+  :mode (("\\.lua\\'" . lua-mode)))
+
+(use-package puppet-mode
+  :mode (("\\.pp\\'" . puppet-mode))
+  :config (progn
+            (add-hook 'puppet-mode-hook #'autopair-mode)))
+
+(use-package ruby-mode
+  :mode (("\\.rb\\'" . ruby-mode)
+         ("\\.cap\\'" . ruby-mode)))
+
+(use-package yaml-mode
+  :mode (("/group_vars/.*" . yaml-mode)
+         ("/host_vars/.*" . yaml-mode))
+  :config (progn
+            (add-hook 'yaml-mode-hook #'autopair-mode)))
+
+;;;; Planning
+
+(use-package org
+  :bind (("C-c C-a" . org-agenda-list)
+         ("C-c a" . org-agenda)
+         ("C-c l" . org-store-link)
+         ("C-c r" . org-remember))
+  :config (progn
+            (setq org-directory "~/org"
+                  org-agenda-files `(,org-directory)
+
+                  org-default-notes-file (concat org-directory "/notes")
+
+                  ;; Fewer asterisks, doesn't change indentation
+                  org-hide-leading-stars t
+
+                  org-startup-indented t
+
+                  ;; ‘Remember’: new items at top
+                  org-reverse-note-order t
+
+                  org-modules '(org-habit
+                                org-checklist)
+
+                  ;; Add time done to ‘done’ tasks
+                  org-log-done 'time
+
+                  ;; Allow refiling into any org file
+                  org-refile-targets '((org-agenda-files :maxlevel . 3))
+
+                  org-list-allow-alphabetical t
+
+                  org-pretty-entities t
+
+                  org-table-duration-custom-format 'seconds
+
+                  org-export-have-math t
+
+                  org-blank-before-new-entry '((heading . t)
+                                               (plain-list-item . auto))
+                  org-fontify-done-headline t
+
+                  org-replace-disputed-keys t
+                  org-todo-keywords '((sequence "TODO" "STARTED" "|" "DONE")
+                                      (sequence "TOLEARN" "LEARNING" "LEARNED" "|" "MASTERED")
+                                      (sequence "|" "CANCELLED")))
+            (set-register ?o `(file . ,(expand-file-name "organiser.org" org-directory)))
+            (defadvice org-clock-in (after wicked activate)
+              "Mark STARTED when clocked in"
+              (save-excursion
+                (catch 'exit
+                  (org-back-to-heading t)
+                  (if (looking-at org-outline-regexp) (goto-char (1- (match-end 0))))
+                  (if (looking-at (concat " +" org-todo-regexp "\\( +\\|[ \t]*$\\)"))
+                      (org-todo "STARTED")))))))
+
+(use-package org-journal
+  :config (progn
+            (setq org-journal-date-format "%A, %d %B %Y")))
+
+;;;; Programming
+
+(use-package cedet
+  :disabled t
+  :config (progn
+            (semantic-load-enable-code-helpers)
+            (global-semantic-idle-completions-mode t)
+            (global-semantic-highlight-func-mode t)
+            (global-semantic-show-unmatched-syntax-mode t)
+            (global-semantic-decoration-mode t)))
+
+;;;; Projects
+
+(use-package projectile
+  :bind (("C-c C-f" . projectile-find-file)
+         ("s-x s-f" . projectile-find-file))
+  :commands (projectile-global-mode))
+
+(use-package project-persist
+  :commands (project-persist-mode)
+  :bind (("C-c P d" . project-persist-delete)
+         ("C-c P f" . project-persist-find)
+         ("C-c P k" . project-persist-close)
+         ("C-c P n" . project-persist-create)
+         ("C-c P s" . project-persist-save))
+  :init (eval-when-compile
+          (autoload #'pp/settings-get "project-persist"))
+  :config (progn
+            (project-persist-mode t)
+
+            (setq project-persist-auto-save-global t)
+
+            (add-hook 'project-persist-before-load-hook #'kill-all-buffers)
+
+            (defun emacs-process-p (pid)
+              "If pid is the process ID of an emacs process, return t, else nil.
+Also returns nil if pid is nil."
+              (when pid
+                (let ((attributes (process-attributes pid)) (cmd))
+                  (dolist (attr attributes)
+                    (if (string= "comm" (car attr))
+                        (setq cmd (cdr attr))))
+                  (if (and cmd (or (string= "emacs" cmd) (string= "emacs.exe" cmd))) t))))
+
+            (defadvice desktop-owner (after pry-from-cold-dead-hands activate)
+              "Don't allow dead emacsen to own the desktop file."
+              (when (not (emacs-process-p ad-return-value))
+                (setq ad-return-value nil)))
+
+            (defun load-project-desktop ()
+              "Load the project's desktop if available"
+              (ignore-errors
+                (let ((default-directory project-persist-current-project-settings-dir))
+                  (desktop-read))))
+
+            (defun kill-all-buffers ()
+              "Kill all file-based buffers."
+              (interactive)
+              (mapc (lambda (buf)
+                      (when (buffer-file-name buf)
+                        (when (and (buffer-modified-p buf)
+                                   (y-or-n-p (format "Buffer %s is modified - save it?" (buffer-name buf))))
+                          (save-some-buffers nil buf))
+                        (set-buffer-modified-p nil)
+                        (kill-buffer buf)))
+                    (buffer-list)))
+
+            (add-hook 'project-persist-after-close-hook
+                      (lambda ()
+                        (kill-all-buffers)
+                        (projectile-global-mode -1)))
+
+            (add-hook 'project-persist-after-load-hook
+                      (lambda ()
+                        (setq default-directory (pp/settings-get 'root-dir))
+                        (load-project-desktop)
+                        (projectile-global-mode 1)))
+
+            (add-hook 'project-persist-after-save-hook
+                      (lambda ()
+                        (message (format "Saving project desktop (%s)" project-persist-current-project-settings-dir))
+                        (desktop-save project-persist-current-project-settings-dir)))
+))
+
+(use-package vc
+  :config (progn
+            (setq vc-follow-symlinks t)))
+
+(use-package diff-hl
+  :init (progn
+          (global-diff-hl-mode)
+          (add-hook 'magit-refresh-file-buffer-hook #'diff-hl-update)))
+
+(use-package magit
+  :commands (magit-status)
+  :bind (("C-x g" . magit-status)
+         ("s-G" . magit-status))
+  :init (add-hook 'magit-mode-hook #'magit-load-config-extensions))
+
+;;;; Spelling
+(setq ispell-program-name "aspell"
+      ispell-dictionary "british")
+;; (setq ispell-process-directory (expand-file-name "~/"))
+;; If aspell is too slow
+;; If it is still too slow, use ‘ultra’ instead of ‘fast’
+;; (setq ispell-extra-args '(" --sug-mode=fast"))
+(use-package ispell
+  :bind (("<f8>" . ispell-word)))
+
+;;;; Scripting
+
+(add-hook 'after-save-hook
+          #'executable-make-buffer-file-executable-if-script-p)
+
+(use-package sh-script
+  :mode (("\\.zsh\\'" . shell-script-mode))
+  :config (setq sh-shell-file "/usr/bin/env zsh"))
+
+(use-package ntcmd
+  :mode (("\\`.cmd\\'" . ntcmd-mode)
+         ("\\`.bat\\'" . ntcmd-mode)))
+
+;;;; Shells & REPLs
+
+(use-package eshell
+  :bind ("C-c s" . eshell)
+  :config (progn
+            (setq eshell-directory-name "~/.emacs.d/eshell")
+            (use-package em-smart
+              :init (progn
+                      (setq eshell-where-to-jump 'begin
+                            eshell-review-quick-commands nil
+                            eshell-smart-space-goes-to-end t)
+                      (eshell-smart-initialize)))))
+
+(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)
+
+(use-package shell
+  :config (define-key shell-mode-map
+            (kbd "C-d") 'comint-delchar-or-eof-or-kill-buffer))
+
+(use-package multi-term
+  :if (not (eq system-type 'windows-nt))
+  :bind ("C-`" . multi-term-dedicated-toggle))
+
+(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)))
+
+;;;; Text editing
+
+;; Enable upcase and downcase-region
+(put 'upcase-region 'disabled nil)
+(put 'downcase-region 'disabled nil)
+(setq sentence-end-double-space nil
+      line-move-visual nil)
+
+(setq x-select-enable-clipboard t)
+(if (functionp 'x-cut-buffer-or-selection-value)
+    (setq interprogram-paste-function 'x-cut-buffer-or-selection-value))
+
+;; replace highlighted text rather than just inserting at point
+(delete-selection-mode t)
+
+(show-paren-mode t)
+
+(bind-key "S-SPC" #'set-mark-command)
+
+(use-package subword
+  :init (global-subword-mode t))
+
+(use-package misc
+  :bind (("M-z" . zap-up-to-char)
+         ("M-Z" . zap-to-char)))
+
+(use-package ap-functions
+  :commands (ap/remove-extra-cr)
+  :bind (("C-x r M-w" . copy-rectangle)
+         ("M-!" . shell-execute)))
+
+(when (boundp 'x-select-request-type)
+  (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))
+
+(use-package ace-jump-mode
+  :bind (("C-c SPC" . ace-jump-mode))
+  :config (progn
+            (ace-jump-mode-enable-mark-sync)
+            (setq ace-jump-word-mode-use-query-char nil
+                  ace-jump-mode-scope 'window)))
+
+(use-package autopair
+  :commands (autopair-mode
+             autopair-on)
+  :init (progn
+          (add-hook 'prog-mode-hook #'autopair-on)
+          (defun autopair-off ()
+            (autopair-mode -1))
+          (add-hook 'lisp-common-mode-hook #'autopair-off)
+          (setq autopair-blink nil
+                autopair-skip-whitespace nil)))
+
+(use-package expand-region
+  :bind ("C-M-SPC" . er/expand-region))
+
+(use-package goto-chg
+  :bind ("C-x SPC" . goto-last-change))
+
+(use-package multiple-cursors
+  :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)))
+
+(use-package eldoc
+  :config (progn
+            (eldoc-add-command 'paredit-backward-delete 'paredit-close-round)))
+
+(use-package paredit
+  :commands (paredit-mode)
+  :init (progn
+          (add-hook 'lisp-common-mode-hook #'enable-paredit-mode)
+          (put #'paredit-forward-delete 'delete-selection 'supersede)
+          (put #'paredit-backward-delete 'delete-selection 'supersede)
+          (add-hook 'minibuffer-setup-hook #'conditionally-enable-paredit-mode)
+          (defun conditionally-enable-paredit-mode ()
+            "enable paredit-mode during eval-expression"
+            (if (eq this-command 'eval-expression)
+                (paredit-mode 1)))))
+
+(use-package shuffle-lines
+  :bind (("C-S-<up>" . move-line-up)
+         ("C-S-<down>" . move-line-down)))
+
+(use-package smart-forward
+  :bind (("C-M-u" . smart-up)
+         ("C-M-d" . smart-down)
+         ("C-M-p" . smart-backward)
+         ("C-M-n" . smart-forward)))
+
+(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)
+
+;;;; Lisps
+
+(defun ap/lisp-setup ()
+  (run-hooks 'lisp-common-mode-hook)
+  (setq indent-tabs-mode nil)
+  (local-set-key (kbd "RET") #'paredit-newline))
+
+(defun set-common-lisp-indentation ()
+    (set (make-local-variable 'lisp-indent-function)
+         #'common-lisp-indent-function))
+
+(add-hook 'emacs-lisp-mode-hook #'ap/lisp-setup)
+(add-hook 'emacs-lisp-mode-hook #'turn-on-eldoc-mode)
+
+(add-hook 'scheme-mode-hook #'ap/lisp-setup)
+(add-hook 'lisp-mode-hook #'ap/lisp-setup)
+(add-hook 'lisp-mode-hook #'set-common-lisp-indentation)
+
+(use-package elisp-slime-nav
+  :commands elisp-slime-nav-mode
+  :diminish elisp-slime-nav-mode)
+
+(use-package geiser
+  :commands (geiser-mode
+             geiser
+             run-geiser
+             run-racket)
+  :config (use-package quack))
+
+(use-package redshank
+  :init (progn
+          (add-hook 'lisp-common-mode-hook #'turn-on-redshank-mode)))
+
+(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 (executable-find "sbcl"))))
+
+(defun imenu-elisp-sections ()
+  (setq imenu-prev-index-position-function nil)
+  (add-to-list 'imenu-generic-expression '("Sections" "^;;;; \\(.+\\)$" 1) t)
+  (add-to-list 'imenu-generic-expression '("Packages" "^(use-package\\s-+\\(\\(\\sw\\|\\s_\\)+\\)$" 1) t))
+
+(defun init-narrow-to-section ()
+  (interactive)
+  (save-excursion
+    (beginning-of-line)
+    (unless (looking-at "^;;;;")
+      (re-search-backward "^;;;;" nil t))
+    (push-mark)
+    (forward-line)
+    (re-search-forward "^;;;;" nil t)
+    (forward-line -1)
+    (narrow-to-region (region-beginning) (region-end))))
+
+(defun init-imenu (p)
+  (interactive "P")
+  (find-file-existing *init-file*)
+  (widen)
+  (helm-imenu)
+  (if p (init-narrow-to-section)))
+
+(add-hook 'emacs-lisp-mode-hook 'imenu-elisp-sections)
+
+(defun eval-and-replace ()
+  "Replace the preceding sexp with its value."
+  (interactive)
+  (backward-kill-sexp)
+  (condition-case nil
+      (prin1 (eval (read (current-kill 0)))
+             (current-buffer))
+    (error (message "Invalid expression")
+           (insert (current-kill 0)))))
+
+(bind-key "C-c e" #'eval-and-replace)
+
+;;;; Programming
+
+(use-package auto-compile
+  :init (add-hook 'emacs-lisp-mode-hook #'auto-compile-on-save-mode))
+
+(use-package cc-mode
+  :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 '+)))
+
+(use-package quickrun)
+
+;;;; Web Development
+
+(use-package skewer-mode
+  :init (progn
+          (add-hook 'js2-mode-hook #'skewer-mode)
+          (add-hook 'html-mode-hook #'skewer-html-mode)
+          (add-hook 'css-mode-hook #'skewer-css-mode)))
+
+(use-package js2-mode
+  :mode ("\\.js\\'" . js2-mode)
+  :config (progn
+            (defun ap/javascript-setup ()
+			   (autopair-mode -1)
+              (auto-indent-mode -1))
+            (add-hook 'js2-mode-hook #'ap/javascript-setup)
+            (setq js2-basic-offset 4
+                  js2-global-externs '("$"))))
+
+(use-package mustache-mode
+  :mode (("\\.mustache" . mustache-mode)
+         ("\\.mt\\'" . mustache-mode)
+         ("\\.template\\'" . mustache-mode)))
+
+(use-package jinja2-mode
+  :mode (("\\.j2\\'" . jinja2-mode)))
+
+(use-package php-mode
+  :mode ("\\.php\\'" . php-mode)
+  :config (progn
+            (bind-key "C-h C-f" #'php-search-documentation php-mode-map)
+            (unbind-key "C-c C-f" php-mode-map)
+            (unbind-key "C-." php-mode-map)
+            (c-add-style "ap"
+                         '((c-basic-offset . 4)
+                           (c-offsets-alist . ((arglist-cont . php-lineup-arglist)
+                                               (arglist-intro . php-lineup-arglist-intro)
+                                               (arglist-close . php-lineup-arglist-close)
+                                               (topmost-intro-cont . (first c-lineup-cascaded-calls
+                                                                            php-lineup-arglist-intro))
+                                               (brace-list-intro . +)
+                                               (brace-list-entry . c-lineup-cascaded-calls)
+                                               (case-label . 4)
+                                               (statement-case-intro . 4)
+                                               (defun-close . 0)
+                                               (defun-block-intro . +)
+                                               (knr-argdecl . [0])
+                                               (arglist-cont-nonempty . c-lineup-cascaded-calls)
+                                               (statement-cont . php-lineup-hanging-semicolon)))))
+            (defun ap/php-style ()
+              (setq indent-tabs-mode t
+                    c-indent-comments-syntactically-p t)
+              (c-set-style "ap"))
+            (add-hook 'php-mode-hook #'ap/php-style)
+            (add-hook 'php-mode-hook #'turn-on-eldoc-mode)))
+
+(use-package sgml-mode
+  :config (setq sgml-basic-offset 4))
+
+(use-package emmet-mode
+  :config (progn
+            (if (functionp 'web-mode)
+                (add-hook 'web-mode-hook #'emmet-mode))))
+
+(use-package web-mode
+  :mode (("/views/.*\\.php\\'" . web-mode)
+         ("/templates/.*\\.php\\'" . web-mode))
+  :config (setq web-mode-code-indent-offset 4
+                web-mode-css-indent-offset 4
+                web-mode-markup-indent-offset 4
+                web-mode-style-padding 0
+                web-mode-script-padding 0
+                web-mode-comment-style 2
+                web-mode-disable-auto-pairing t))
+
+;;;; Windows & Frames
+
+(setq frame-title-format
+      '(""
+        (:eval (capitalize invocation-name)) ": "
+        (:eval (if (buffer-file-name)
+                   (abbreviate-file-name (buffer-file-name))
+                 "%b"))))
+
+(setq scroll-conservatively 100 ; Keep the cursor position when scrolling
+      scroll-margin 1
+      scroll-preserve-screen-position nil
+      mouse-wheel-scroll-amount '(1 ((shift) . 1) ((control))))
+
+(when menu-bar-mode
+  (menu-bar-mode -1))
+(when scroll-bar-mode
+  (scroll-bar-mode -1)
+  (tooltip-mode -1)
+  (tool-bar-mode -1))
+
+(winner-mode 1)
+
+(use-package windmove
+  :bind (("S-<left>"  . windmove-left)
+         ("S-<right>" . windmove-right)
+         ("S-<up>"    . windmove-up)
+         ("S-<down>"  . windmove-down)))
+
+(if (eq system-type 'darwin)
+    (setq ns-pop-up-frames nil))