diff options
Diffstat (limited to 'tag-emacs')
-rw-r--r-- | tag-emacs/emacs.d/Cask | 74 | ||||
-rw-r--r-- | tag-emacs/emacs.d/elisp/ap-functions.el | 47 | ||||
-rw-r--r-- | tag-emacs/emacs.d/elisp/php-electric.el | 218 | ||||
-rw-r--r-- | tag-emacs/emacs.d/elisp/shuffle-lines.el | 20 | ||||
-rw-r--r-- | tag-emacs/emacs.d/elisp/xrdb-mode.el | 544 | ||||
-rw-r--r-- | tag-emacs/emacs.d/init.el | 1170 |
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)) |