]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/context-coloring/context-coloring.el
Merge commit '283a006be8e96c7e011dedddb460b289d335a9fb' from context-coloring
[gnu-emacs-elpa] / packages / context-coloring / context-coloring.el
index cd1b97a50acc56784f3e4295b81f804031f1b9af..d73773a41a4280c5599faa72f52b3563c4f94173 100644 (file)
@@ -1,11 +1,11 @@
-;;; context-coloring.el --- Syntax highlighting, except not for syntax. -*- lexical-binding: t; -*-
+;;; context-coloring.el --- Highlight by scope  -*- lexical-binding: t; -*-
 
 ;; Copyright (C) 2014-2015  Free Software Foundation, Inc.
 
 ;; Author: Jackson Ray Hamilton <jackson@jacksonrayhamilton.com>
-;; URL: https://github.com/jacksonrayhamilton/context-coloring
-;; Keywords: context coloring syntax highlighting
-;; Version: 6.2.0
+;; Version: 6.2.1
+;; Keywords: convenience faces tools
+;; Homepage: https://github.com/jacksonrayhamilton/context-coloring
 ;; Package-Requires: ((emacs "24") (js2-mode "20150126"))
 
 ;; This file is part of GNU Emacs.
 
 ;;; Commentary:
 
-;; Highlights code according to function context.
+;; Highlights code by scope.  Top-level scopes are one color, second-level
+;; scopes are another color, and so on.  Variables retain the color of the scope
+;; in which they are defined.  A variable defined in an outer scope referenced
+;; by an inner scope is colored the same as the outer scope.
 
-;; - Code in the global scope is one color.  Code in functions within the global
-;;   scope is a different color, and code within such functions is another
-;;   color, and so on.
-;; - Identifiers retain the color of the scope in which they are declared.
+;; By default, comments and strings are still highlighted syntactically.
 
-;; Lexical scope information at-a-glance can assist a programmer in
-;; understanding the overall structure of a program.  It can help to curb nasty
-;; bugs like name shadowing.  A rainbow can indicate excessive complexity.
-;; State change within a closure is easily monitored.
-
-;; By default, Context Coloring still highlights comments and strings
-;; syntactically.  It is still easy to differentiate code from non-code, and
-;; strings cannot be confused for variables.
-
-;; To use, add the following to your ~/.emacs:
+;; To use with js2-mode, add the following to your init file:
 
 ;; (require 'context-coloring)
 ;; (add-hook 'js2-mode-hook 'context-coloring-mode)
 
-;; js-mode or js3-mode support requires Node.js 0.10+ and the scopifier
-;; executable.
+;; To use with js-mode or js3-mode, install Node.js 0.10+ and the scopifier
+;; executable:
 
 ;; $ npm install -g scopifier
 
   "Join a list of STRINGS with the string DELIMITER."
   (mapconcat 'identity strings delimiter))
 
+(defsubst context-coloring-trim-right (string)
+  "Remove leading whitespace from STRING."
+  (if (string-match "[ \t\n\r]+\\'" string)
+      (replace-match "" t t string)
+    string))
+
+(defsubst context-coloring-trim-left (string)
+  "Remove trailing whitespace from STRING."
+  (if (string-match "\\`[ \t\n\r]+" string)
+      (replace-match "" t t string)
+    string))
+
+(defsubst context-coloring-trim (string)
+  "Remove leading and trailing whitespace from STRING."
+  (context-coloring-trim-left (context-coloring-trim-right string)))
+
 
 ;;; Faces
 
@@ -89,12 +96,12 @@ backgrounds."
   (context-coloring-defface level nil "#3f3f3f" "#cdcdcd"))
 
 (context-coloring-defface 0 nil       "#000000" "#ffffff")
-(context-coloring-defface 1 "yellow"  "#007f80" "#ffff80")
-(context-coloring-defface 2 "green"   "#001580" "#cdfacd")
-(context-coloring-defface 3 "cyan"    "#550080" "#d8d8ff")
-(context-coloring-defface 4 "blue"    "#802b00" "#e7c7ff")
-(context-coloring-defface 5 "magenta" "#6a8000" "#ffcdcd")
-(context-coloring-defface 6 "red"     "#008000" "#ffe390")
+(context-coloring-defface 1 "yellow"  "#008b8b" "#00ffff")
+(context-coloring-defface 2 "green"   "#0000ff" "#87cefa")
+(context-coloring-defface 3 "cyan"    "#483d8b" "#b0c4de")
+(context-coloring-defface 4 "blue"    "#a020f0" "#eedd82")
+(context-coloring-defface 5 "magenta" "#a0522d" "#98fb98")
+(context-coloring-defface 6 "red"     "#228b22" "#7fffd4")
 (context-coloring-defface-neutral 7)
 
 (defvar context-coloring-maximum-face nil
@@ -237,12 +244,20 @@ variable."
                        ;; `js2-prop-get-node', so this always works.
                        (eq node (js2-prop-get-node-right parent))))))))
 
+(defvar-local context-coloring-point-max nil
+  "Cached value of `point-max'.")
+
 (defsubst context-coloring-js2-colorize-node (node level)
   "Color NODE with the color for LEVEL."
   (let ((start (js2-node-abs-pos node)))
     (context-coloring-colorize-region
      start
-     (+ start (js2-node-len node)) ; End
+     (min
+      ;; End
+      (+ start (js2-node-len node))
+      ;; Somes nodes (like the ast when there is an unterminated multiline
+      ;; comment) will stretch to the value of `point-max'.
+      context-coloring-point-max)
      level)))
 
 (defun context-coloring-js2-colorize ()
@@ -250,6 +265,7 @@ variable."
 generated by `js2-mode'."
   ;; Reset the hash table; the old one could be obsolete.
   (setq context-coloring-js2-scope-level-hash-table (make-hash-table :test 'eq))
+  (setq context-coloring-point-max (point-max))
   (with-silent-modifications
     (js2-visit-ast
      js2-mode-ast
@@ -298,8 +314,13 @@ element."
 
 (defun context-coloring-parse-array (array)
   "Parse ARRAY as a flat JSON array of numbers."
-  (vconcat
-   (mapcar 'string-to-number (split-string (substring array 1 -1) ","))))
+  (let ((braceless (substring (context-coloring-trim array) 1 -1)))
+    (cond
+     ((> (length braceless) 0)
+      (vconcat
+       (mapcar 'string-to-number (split-string braceless ","))))
+     (t
+      (vector)))))
 
 (defvar-local context-coloring-scopifier-process nil
   "The single scopifier process that can be running.")
@@ -375,15 +396,6 @@ Invoke CALLBACK when complete."
 (defvar context-coloring-mode-hash-table (make-hash-table :test 'eq)
   "Map major mode names to dispatch property lists.")
 
-(defun context-coloring-select-dispatch (mode dispatch)
-  "Use DISPATCH for MODE."
-  (puthash
-   mode
-   (gethash
-    dispatch
-    context-coloring-dispatch-hash-table)
-   context-coloring-mode-hash-table))
-
 (defun context-coloring-define-dispatch (symbol &rest properties)
   "Define a new dispatch named SYMBOL with PROPERTIES.
 
@@ -479,12 +491,18 @@ elisp tracks, and asynchronously for shell command tracks."
 
 ;;; Colorization
 
+(defvar context-coloring-colorize-hook nil
+  "Hooks to run after coloring a buffer.")
+
 (defun context-coloring-colorize (&optional callback)
   "Color the current buffer by function context.
 
 Invoke CALLBACK when complete; see `context-coloring-dispatch'."
   (interactive)
-  (context-coloring-dispatch callback))
+  (context-coloring-dispatch
+   (lambda ()
+     (when callback (funcall callback))
+     (run-hooks 'context-coloring-colorize-hook))))
 
 (defvar-local context-coloring-changed nil
   "Indication that the buffer has changed recently, which implies
@@ -648,7 +666,9 @@ which must already exist and which *should* already be enabled."
   (let* ((properties (gethash theme context-coloring-theme-hash-table))
          (colors (plist-get properties :colors))
          (level -1))
-    (setq context-coloring-maximum-face (- (length colors) 1))
+    ;; Only clobber when we have to.
+    (when (custom-theme-enabled-p theme)
+      (setq context-coloring-maximum-face (- (length colors) 1)))
     (apply
      'custom-theme-set-faces
      theme
@@ -746,7 +766,7 @@ precedence, i.e. the car of `custom-enabled-themes'."
   (when (and (not (eq theme 'user)) ; Called internally by `enable-theme'.
              (custom-theme-p theme) ; Guard against non-existent themes.
              (context-coloring-theme-p theme))
-    (when (= (length custom-enabled-themes) 0)
+    (when (= (length custom-enabled-themes) 1)
       ;; Cache because we can't reliably figure it out in reverse.
       (setq context-coloring-original-maximum-face
             context-coloring-maximum-face))