summaryrefslogtreecommitdiffstats
path: root/emacs.d
diff options
context:
space:
mode:
authorGravatar Tom Willemsen2011-05-17 00:45:41 +0200
committerGravatar Tom Willemsen2011-05-17 00:45:41 +0200
commita252e892a9a266f780f13f943f4499488bbdcdc1 (patch)
treef8a2629bb9b2908d883b199b8d23960b7ed1559a /emacs.d
parent31549fbf40e6bed44fd60e5da4a350117470a163 (diff)
downloaddotfiles-a252e892a9a266f780f13f943f4499488bbdcdc1.tar.gz
dotfiles-a252e892a9a266f780f13f943f4499488bbdcdc1.zip
EMACS: Added Rainbow delimiters mode
Diffstat (limited to 'emacs.d')
-rw-r--r--emacs.d/10-modules.el2
-rw-r--r--emacs.d/10-naquadah-theme.el16
-rw-r--r--emacs.d/10-settings.el1
-rw-r--r--emacs.d/20-rainbow-delimiters.el4
-rw-r--r--emacs.d/elisp/rainbow-delimiters.el392
5 files changed, 412 insertions, 3 deletions
diff --git a/emacs.d/10-modules.el b/emacs.d/10-modules.el
index 18731d7..b6cd429 100644
--- a/emacs.d/10-modules.el
+++ b/emacs.d/10-modules.el
@@ -1,5 +1,3 @@
-(require 'naquadah-theme)
-
(autoload 'vala-mode "vala-mode"
"A Major mode for editing Vala files" t)
(autoload 'csharp-mode "csharp-mode"
diff --git a/emacs.d/10-naquadah-theme.el b/emacs.d/10-naquadah-theme.el
new file mode 100644
index 0000000..5507800
--- /dev/null
+++ b/emacs.d/10-naquadah-theme.el
@@ -0,0 +1,16 @@
+(require 'naquadah-theme)
+
+;; Extension to the naquadah theme
+(naquadah-theme-set-faces
+ 'naquadah
+ '(rainbow-delimiters-depth-1-face (:foreground gradient-1))
+ '(rainbow-delimiters-depth-2-face (:foreground gradient-2))
+ '(rainbow-delimiters-depth-3-face (:foreground gradient-3))
+ '(rainbow-delimiters-depth-4-face (:foreground gradient-4))
+ '(rainbow-delimiters-depth-5-face (:foreground gradient-5))
+ '(rainbow-delimiters-depth-6-face (:foreground gradient-6))
+ '(rainbow-delimiters-depth-7-face (:foreground gradient-7))
+ '(rainbow-delimiters-depth-8-face (:foreground gradient-8))
+ '(rainbow-delimiters-depth-9-face (:foreground gradient-9))
+ '(rainbow-delimiters-depth-10-face (:foreground gradient-10))
+ '(rainbow-delimiters-depth-11-face (:foreground gradient-11)))
diff --git a/emacs.d/10-settings.el b/emacs.d/10-settings.el
index ac0db1c..42d9ed3 100644
--- a/emacs.d/10-settings.el
+++ b/emacs.d/10-settings.el
@@ -22,7 +22,6 @@
(global-linum-mode t) ; show them in the gutter
(column-number-mode t) ; show column number in splitter
(global-font-lock-mode t) ; show syntax highlighting, old
-(show-paren-mode t) ; show matching parens
(delete-selection-mode t) ; delete selection upon typing
;; Byte-compile elisp files on save
diff --git a/emacs.d/20-rainbow-delimiters.el b/emacs.d/20-rainbow-delimiters.el
new file mode 100644
index 0000000..dbf387f
--- /dev/null
+++ b/emacs.d/20-rainbow-delimiters.el
@@ -0,0 +1,4 @@
+(require 'rainbow-delimiters)
+
+(add-hook 'c-mode-hook 'rainbow-delimiters-mode)
+(add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode)
diff --git a/emacs.d/elisp/rainbow-delimiters.el b/emacs.d/elisp/rainbow-delimiters.el
new file mode 100644
index 0000000..19f1aa0
--- /dev/null
+++ b/emacs.d/elisp/rainbow-delimiters.el
@@ -0,0 +1,392 @@
+;;; rainbow-delimiters.el --- Color nested parentheses, brackets, and braces according to their depth.
+
+;; Copyright (C) 2010-2011 Jeremy L. Rayman.
+;; Author: Jeremy L. Rayman <jeremy.rayman@gmail.com>
+;; Maintainer: Jeremy L. Rayman <jeremy.rayman@gmail.com>
+;; Created: 2010-09-02
+;; Version: 1.2.1
+;; Keywords: faces, convenience, lisp, matching, tools
+;; EmacsWiki: RainbowDelimiters
+;; URL: http://www.emacswiki.org/emacs/rainbow-delimiters.el
+
+;; 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+
+;; This is a "rainbow parentheses" mode which includes support for
+;; parens "()", brackets "[]", and braces "{}". It conveys nesting
+;; depth by using a different face for each level. It colors all
+;; statements at a given level using the same color - if several
+;; statements are all at the same nested depth, they will all be the
+;; same color.
+;;
+;; Great care has been taken to make this mode FAST. You should see no
+;; discernible change in scrolling or editing speed while using it,
+;; even with delimiter-rich languages like Clojure, Lisp, and Scheme.
+;;
+;; The one exception is with extremely large nested data structures
+;; having hundreds of delimiters; in that case there will be a brief
+;; pause to colorize the structure the very first time it is displayed
+;; on screen; from then on editing this structure will perform at full
+;; speed.
+;;
+;; Default colors have been chosen with the philosophy that it's
+;; better be less intrusive than to be more colorful. Color schemes
+;; are always a matter of taste. If you do take the time to design a
+;; new color scheme, please post it on the EmacsWiki page!
+;; URL: http://www.emacswiki.org/emacs/RainbowDelimiters
+
+;;; Installation:
+
+;; 1. Place rainbow-delimiters.el on your emacs load-path.
+;;
+;; 2. Compile the file (necessary for speed):
+;; M-x byte-compile-file <location of rainbow-delimiters.el>
+;;
+;; 3. Add the following to your dot-emacs/init file:
+;; (require 'rainbow-delimiters)
+;;
+;; 4. Add hooks for modes where you want it enabled, for example:
+;; (add-hook 'clojure-mode-hook 'rainbow-delimiters-mode)
+;;
+;; - To activate rainbow-delimiters mode temporarily in a buffer:
+;; M-x rainbow-delimiters-mode
+
+;;; Customization:
+
+;; To customize various options, including the color scheme:
+;; M-x customize-group rainbow-delimiters
+;;
+;; color-theme.el users:
+;; If you use the color-theme package, you can specify custom colors
+;; by adding the appropriate faces to your theme.
+;; - Faces take the form of:
+;; 'rainbow-delimiters-depth-#-face' with # being the depth.
+;; Depth begins at 1, the outermost color.
+;; Faces exist for depths 1-12.
+;; - The unmatched delimiter face is:
+;; 'rainbow-delimiters-unmatched-delimiter-face'
+
+;;; Change Log:
+
+;; 1.0 - Initial release.
+;; 1.1 - Stop tracking each delimiter's depth independently.
+;; This had lead to confusing results when viewing clojure
+;; code. Instead, just color based on current nesting inside
+;; all delimiters combined.
+;; - Added 'all-delimiters' faces to apply a color scheme to
+;; all delimiters at once. Other faces inherit from this group.
+;; 1.1.1 - Change color scheme to a lighter, more subtle style.
+;; 1.1.2: (2011-03-25)
+;; - Add an unmatched-delimiter face and correct problem with
+;; coloring of text following unmatched closing delims.
+;; 1.2: (2011-03-28)
+;; - Unify delimiter faces: all delimiter types now use the same depth
+;; faces, of form 'rainbow-delimiters-depth-#-face'.
+;; 1.2.1: (2011-03-29)
+;; - Conform to ELPA conventions.
+
+;;; TODO:
+
+;; - Add support for nested tags (XML, HTML)
+
+;;; Issues:
+
+;; - Rainbow-delimiters mode does not appear to change the color of
+;; delimiters when Org-mode is enabled.
+
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+
+;;; Customize interface:
+
+(defgroup rainbow-delimiters nil
+ "Color nested parentheses, brackets, and braces according to their depth."
+ :prefix "rainbow-delimiters-"
+ :link '(url-link :tag "Website for rainbow-delimiters (EmacsWiki)"
+ "http://www.emacswiki.org/emacs/RainbowDelimiters")
+ :group 'applications)
+
+(defgroup rainbow-delimiters-faces nil
+ "Faces for each nested depth. Used to color delimiter pairs.
+
+Depths 1-12 are defined. Depth 1 is the outermost delimiter pair."
+ :group 'rainbow-delimiters
+ :link '(custom-group-link "rainbow-delimiters")
+ :prefix 'rainbow-delimiters-faces-)
+
+
+;;; Faces:
+
+;; Unmatched delimiter face:
+(defface rainbow-delimiters-unmatched-face
+ '((t (:foreground "#88090B")))
+ "Face to color unmatched closing delimiters with."
+ :group 'rainbow-delimiters
+ :group 'rainbow-delimiters-faces)
+
+
+;; NOTE: The use of repetitious definitions for depth faces is temporary.
+;; Once the emacs 24 color theme support comes in, this will be reevaluated.
+
+;; Faces for colorizing delimiters at each level:
+(defface rainbow-delimiters-depth-1-face
+ '((t (:foreground "grey55")))
+ "Rainbow-delimiters nested delimiter face, depth 1 - the outermost pair."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-2-face
+ '((t (:foreground "#93a8c6")))
+ "Rainbow-delimiters nested delimiter face, depth 2."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-3-face
+ '((t (:foreground "#b0b1a3")))
+ "Rainbow-delimiters nested delimiter face, depth 3."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-4-face
+ '((t (:foreground "#97b098")))
+ "Rainbow-delimiters nested delimiter face, depth 4."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-5-face
+ '((t (:foreground "#aebed8")))
+ "Rainbow-delimiters nested delimiter face, depth 5."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-6-face
+ '((t (:foreground "#b0b0b3")))
+ "Rainbow-delimiters nested delimiter face, depth 6."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-7-face
+ '((t (:foreground "#90a890")))
+ "Rainbow-delimiters nested delimiter face, depth 7."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-8-face
+ '((t (:foreground "#a2b6da")))
+ "Rainbow-delimiters nested delimiter face, depth 8."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-9-face
+ '((t (:foreground "#9cb6ad")))
+ "Rainbow-delimiters nested delimiter face, depth 9."
+ :group 'rainbow-delimiters-faces)
+
+;; Emacs doesn't sort face names by number correctly above 1-9; trick it into
+;; proper sorting by prepending a _ before the faces with depths over 10.
+(defface rainbow-delimiters-depth-_10-face
+ '((t (:foreground "#83787e")))
+ "Rainbow-delimiters nested delimiter face, depth 10."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-_11-face
+ '((t (:foreground "#e1ddca")))
+ "Rainbow-delimiters nested delimiter face, depth 11."
+ :group 'rainbow-delimiters-faces)
+
+(defface rainbow-delimiters-depth-_12-face
+ '((t (:foreground "#e0c7c7")))
+ "Rainbow-delimiters nested delimiter face, depth 12."
+ :group 'rainbow-delimiters-faces)
+
+;; Variable aliases for faces 10+:
+;; We prepend an underline to numbers 10+ to force customize to sort correctly.
+;; Here we define aliases without the underline for use everywhere else.
+(put 'rainbow-delimiters-depth-10-face
+ 'face-alias
+ 'rainbow-delimiters-depth-_10-face)
+(put 'rainbow-delimiters-depth-11-face
+ 'face-alias
+ 'rainbow-delimiters-depth-_11-face)
+(put 'rainbow-delimiters-depth-12-face
+ 'face-alias
+ 'rainbow-delimiters-depth-_12-face)
+
+
+;;; Face utility functions
+
+;; inlining this function for speed:
+;; see: http://www.gnu.org/s/emacs/manual/html_node/elisp/Compilation-Tips.html
+;; this will cause problems with debugging. To debug, change defsubst -> defun.
+(defsubst rainbow-delimiters-depth-face (depth)
+ "Return face-name 'rainbow-delimiters-depth-DEPTH-face' as a string.
+
+DEPTH is the number of nested levels deep for the delimiter being colorized.
+
+Returns a face namestring the of form 'rainbow-delimiters-depth-DEPTH-face',
+e.g. 'rainbow-delimiters-depth-1-face'."
+ (concat "rainbow-delimiters-depth-" (number-to-string depth) "-face"))
+
+
+;;; Nesting level
+
+;; syntax-table: used with parse-partial-sexp for determining current depth.
+(defvar rainbow-delimiters-delim-syntax-table
+ (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table)))
+ (modify-syntax-entry ?\( "() " table)
+ (modify-syntax-entry ?\) ")( " table)
+ (modify-syntax-entry ?\[ "(]" table)
+ (modify-syntax-entry ?\] ")[" table)
+ (modify-syntax-entry ?\{ "(}" table)
+ (modify-syntax-entry ?\} "){" table)
+ table)
+ "Syntax table for recognizing all supported delimiter types.")
+
+(defun rainbow-delimiters-depth (point)
+ "Return # of nested levels of parens, brackets, braces POINT is inside of."
+ (save-excursion
+ (beginning-of-defun)
+ (let ((depth
+ (with-syntax-table rainbow-delimiters-delim-syntax-table
+ (car (parse-partial-sexp (point) point)))))
+ (if (>= depth 0)
+ depth
+ 0)))) ; ignore negative depths created by unmatched closing parens.
+
+
+;;; Text properties
+
+;; inlining this function for speed:
+;; see: http://www.gnu.org/s/emacs/manual/html_node/elisp/Compilation-Tips.html
+;; this will cause problems with debugging. To debug, change defsubst -> defun.
+(defsubst rainbow-delimiters-propertize-delimiter (point depth)
+ "Colorize delimiter at POINT according to DEPTH.
+
+POINT is the point of character to propertize.
+DEPTH is the nested delimiter depth at POINT, which determines the face to use.
+
+Sets text properties:
+`font-lock-face' to the corresponding delimiter face.
+`rear-nonsticky' to prevent color from bleeding into subsequent characters typed by the user."
+ (with-silent-modifications
+ (let ((delim-face (if (<= depth 0)
+ "rainbow-delimiters-unmatched-face"
+ (rainbow-delimiters-depth-face depth))))
+ ;; (when (eq depth -1) (message "Unmatched delimiter at char %s." point))
+ (add-text-properties point (1+ point)
+ `(font-lock-face ,delim-face
+ rear-nonsticky t)))))
+
+
+(defun rainbow-delimiters-unpropertize-delimiter (point)
+ "Remove text properties set by rainbow-delimiters mode from char at POINT."
+ (remove-text-properties point (1+ point)
+ '(font-lock-face nil
+ rear-nonsticky nil)))
+
+
+(defun rainbow-delimiters-char-ineligible-p (point)
+ "Return t if char at POINT should be skipped, e.g. if inside a comment.
+
+Returns t if char at point meets one of the following conditions:
+- Inside a string.
+- Inside a comment.
+- Is an escaped char, e.g. ?\)"
+ (let ((parse-state (save-excursion
+ (beginning-of-defun)
+ ;; (point) is at beg-of-defun; point is the char location
+ (parse-partial-sexp (point) point))))
+ (or
+ (nth 3 parse-state) ; inside string?
+ (nth 4 parse-state) ; inside comment?
+ (and (eq (char-before point) ?\\) ; escaped char, e.g. ?\) - not counted
+ (and (not (eq (char-before (1- point)) ?\\)) ; special-case: ignore ?\\
+ (eq (char-before (1- point)) ?\?))))))
+;; standard char read syntax '?)' is not tested for because emacs manual states
+;; that punctuation such as delimiters should _always_ use escaped '?\)' form.
+
+
+;;; JIT-Lock functionality
+
+;; Used to skip delimiter-by-delimiter `rainbow-delimiters-propertize-region'.
+(defvar rainbow-delimiters-delim-regex "\\(\(\\|\)\\|\\[\\|\\]\\|\{\\|\}\\)"
+ "Regex matching all opening and closing delimiters we intend to colorize.")
+
+;; main function called by jit-lock:
+(defun rainbow-delimiters-propertize-region (start end)
+ "Colorize delimiters in region between START and END.
+
+Used by jit-lock for dynamic highlighting."
+ (save-excursion
+ (goto-char start)
+ ;; START can be anywhere in buffer; begin depth counts from values at START.
+ (let ((depth (rainbow-delimiters-depth start)))
+ (while (and (< (point) end)
+ (re-search-forward rainbow-delimiters-delim-regex end t))
+ (backward-char) ; re-search-forward places point after delim; go back.
+ (unless (rainbow-delimiters-char-ineligible-p (point))
+ (let ((delim (char-after (point))))
+ (cond ((eq ?\( delim) ; (
+ (setq depth (1+ depth))
+ (rainbow-delimiters-propertize-delimiter (point)
+ depth))
+ ((eq ?\) delim) ; )
+ (rainbow-delimiters-propertize-delimiter (point)
+ depth)
+ (setq depth (or (and (<= depth 0) 0) ; unmatched paren
+ (1- depth))))
+ ((eq ?\[ delim) ; [
+ (setq depth (1+ depth))
+ (rainbow-delimiters-propertize-delimiter (point)
+ depth))
+ ((eq ?\] delim) ; ]
+ (rainbow-delimiters-propertize-delimiter (point)
+ depth)
+ (setq depth (or (and (<= depth 0) 0) ; unmatched bracket
+ (1- depth))))
+ ((eq ?\{ delim) ; {
+ (setq depth (1+ depth))
+ (rainbow-delimiters-propertize-delimiter (point)
+ depth))
+ ((eq ?\} delim) ; }
+ (rainbow-delimiters-propertize-delimiter (point)
+ depth)
+ (setq depth (or (and (<= depth 0) 0) ; unmatched brace
+ (1- depth)))))))
+ ;; move past delimiter so re-search-forward doesn't pick it up again
+ (forward-char)))))
+
+(defun rainbow-delimiters-unpropertize-region (start end)
+ "Remove mode faces from delimiters in region between START and END."
+ (save-excursion
+ (goto-char start)
+ (while (and (< (point) end)
+ (re-search-forward rainbow-delimiters-delim-regex end t))
+ ;; re-search-forward places point 1 further than the delim matched:
+ (rainbow-delimiters-unpropertize-delimiter (1- (point))))))
+
+
+;;; Minor mode:
+
+;;;###autoload
+(define-minor-mode rainbow-delimiters-mode
+ "Color nested parentheses, brackets, and braces according to their depth."
+ nil "" nil ; No modeline lighter - it's already obvious when the mode is on.
+ (if (not rainbow-delimiters-mode)
+ (progn
+ (jit-lock-unregister 'rainbow-delimiters-propertize-region)
+ (rainbow-delimiters-unpropertize-region (point-min) (1- (point-max))))
+ (jit-lock-register 'rainbow-delimiters-propertize-region t)))
+
+
+(provide 'rainbow-delimiters)
+
+;;; rainbow-delimiters.el ends here.