[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master 6ee4481 25/25: Merge commit '3007b2917d71a7d66eb94876536df
From: |
Jackson Ray Hamilton |
Subject: |
[elpa] master 6ee4481 25/25: Merge commit '3007b2917d71a7d66eb94876536dfd80b0661d40' from context-coloring |
Date: |
Mon, 30 May 2016 22:10:46 +0000 (UTC) |
branch: master
commit 6ee448148df13dc0fa96e3cc3305fd00ea7c8be8
Merge: 5f6e9e7 3007b29
Author: Jackson Ray Hamilton <address@hidden>
Commit: Jackson Ray Hamilton <address@hidden>
Merge commit '3007b2917d71a7d66eb94876536dfd80b0661d40' from
context-coloring
---
packages/context-coloring/.elpaignore | 10 +
packages/context-coloring/.gitignore | 6 +-
packages/context-coloring/Cask | 3 +-
packages/context-coloring/Makefile | 16 +-
.../{benchmark => }/context-coloring-benchmark.el | 27 +-
.../{test => }/context-coloring-coverage.el | 10 +-
...-coloring.el => context-coloring-emacs-lisp.el} | 703 +------------
.../context-coloring-javascript.el | 232 +++++
.../{test => }/context-coloring-test.el | 78 +-
packages/context-coloring/context-coloring.el | 1077 ++------------------
.../{benchmark => }/fixtures/.nosearch | 0
.../fixtures => fixtures/benchmark}/.dir-locals.el | 0
.../fixtures => fixtures/benchmark}/async-0.9.0.js | 0
.../fixtures => fixtures/benchmark}/faces.el | 0
.../benchmark}/jquery-2.1.1.js | 0
.../fixtures => fixtures/benchmark}/lisp.el | 0
.../benchmark}/lodash-2.4.1.js | 0
.../benchmark}/mkdirp-0.5.0.js | 0
.../fixtures => fixtures/benchmark}/simple.el | 0
.../fixtures => fixtures/benchmark}/subr.el | 0
.../fixtures => fixtures/test}/block-scopes.js | 0
.../{test/fixtures => fixtures/test}/catch.js | 0
.../{test/fixtures => fixtures/test}/changed.el | 0
.../{test/fixtures => fixtures/test}/comment.el | 0
.../test}/comments-and-strings.js | 0
.../{test/fixtures => fixtures/test}/cond.el | 0
.../fixtures => fixtures/test}/condition-case.el | 0
.../{test/fixtures => fixtures/test}/defadvice.el | 0
.../{test/fixtures => fixtures/test}/defun.el | 0
.../{test/fixtures => fixtures/test}/dolist.el | 0
.../{test/fixtures => fixtures/test}/empty | 0
.../fixtures => fixtures/test}/empty-varlist.el | 0
.../fixtures => fixtures/test}/function-scopes.js | 0
.../{test/fixtures => fixtures/test}/global.js | 0
.../{test/fixtures => fixtures/test}/ignored.el | 0
.../fixtures => fixtures/test}/initial-level.js | 0
.../{test/fixtures => fixtures/test}/iteration.el | 0
.../{test/fixtures => fixtures/test}/key-names.js | 0
.../{test/fixtures => fixtures/test}/key-values.js | 0
.../{test/fixtures => fixtures/test}/lambda.el | 0
.../{test/fixtures => fixtures/test}/let-star.el | 0
.../{test/fixtures => fixtures/test}/let.el | 0
.../fixtures => fixtures/test}/macroexp-let2.el | 0
.../fixtures => fixtures/test}/property-lookup.js | 0
.../{test/fixtures => fixtures/test}/quote.el | 0
.../{test/fixtures => fixtures/test}/sexp.el | 0
.../{test/fixtures => fixtures/test}/splice.el | 0
.../{test/fixtures => fixtures/test}/string.el | 0
.../test}/unbalanced-parenthesis.el | 0
.../test}/unterminated-comment.js | 0
.../fixtures => fixtures/test}/varlist-spacing.el | 0
51 files changed, 399 insertions(+), 1763 deletions(-)
diff --git a/packages/context-coloring/.elpaignore
b/packages/context-coloring/.elpaignore
new file mode 100644
index 0000000..bad5d87
--- /dev/null
+++ b/packages/context-coloring/.elpaignore
@@ -0,0 +1,10 @@
+.elpaignore
+.gitignore
+.travis.yml
+Cask
+context-coloring-benchmark.el
+context-coloring-coverage.el
+context-coloring-test.el
+fixtures
+Makefile
+screenshot.png
diff --git a/packages/context-coloring/.gitignore
b/packages/context-coloring/.gitignore
index a269508..b9fedca 100644
--- a/packages/context-coloring/.gitignore
+++ b/packages/context-coloring/.gitignore
@@ -1,4 +1,6 @@
+*-autoloads.el
+*-pkg.el
*.elc
.cask/
-/benchmark/logs/
-/test/coverage/
+/benchmark/
+/coverage/
diff --git a/packages/context-coloring/Cask b/packages/context-coloring/Cask
index b1535a9..55ff4c5 100644
--- a/packages/context-coloring/Cask
+++ b/packages/context-coloring/Cask
@@ -2,7 +2,6 @@
(package-file "context-coloring.el")
-(depends-on "js2-mode")
-
(development
+ (depends-on "js2-mode")
(depends-on "undercover"))
diff --git a/packages/context-coloring/Makefile
b/packages/context-coloring/Makefile
index f729409..4519b70 100644
--- a/packages/context-coloring/Makefile
+++ b/packages/context-coloring/Makefile
@@ -1,6 +1,10 @@
EMACS = emacs
CASK = EMACS=${EMACS} cask
DEPENDENCIES = .cask/
+SOURCE_FILES = \
+ context-coloring.el \
+ context-coloring-javascript.el \
+ context-coloring-emacs-lisp.el
all: uncompile compile test
@@ -8,13 +12,13 @@ bench: ${DEPENDENCIES}
${CASK} exec ${EMACS} -Q \
-L . \
-l context-coloring \
- -l benchmark/context-coloring-benchmark.el \
+ -l context-coloring-benchmark \
-f context-coloring-benchmark-run
compile: ${DEPENDENCIES}
${CASK} exec ${EMACS} -Q -batch \
-L . \
- -f batch-byte-compile *.el
+ -f batch-byte-compile ${SOURCE_FILES}
uncompile:
rm -f *.elc
@@ -29,18 +33,18 @@ test: ${DEPENDENCIES}
${CASK} exec ${EMACS} -Q -batch \
-L . \
-l ert \
- -l test/context-coloring-coverage.el \
+ -l context-coloring-coverage \
-f context-coloring-coverage-ci-init \
- -l test/context-coloring-test.el \
+ -l context-coloring-test \
-f ert-run-tests-batch-and-exit
cover: ${DEPENDENCIES}
${CASK} exec ${EMACS} -Q -batch \
-L . \
-l ert \
- -l test/context-coloring-coverage.el \
+ -l context-coloring-coverage \
-f context-coloring-coverage-local-init \
- -l test/context-coloring-test.el \
+ -l context-coloring-test \
-f ert-run-tests-batch-and-exit
.PHONY: all bench compile uncompile clean test cover
diff --git a/packages/context-coloring/benchmark/context-coloring-benchmark.el
b/packages/context-coloring/context-coloring-benchmark.el
similarity index 91%
rename from packages/context-coloring/benchmark/context-coloring-benchmark.el
rename to packages/context-coloring/context-coloring-benchmark.el
index c627249..0c38e85 100644
--- a/packages/context-coloring/benchmark/context-coloring-benchmark.el
+++ b/packages/context-coloring/context-coloring-benchmark.el
@@ -1,6 +1,6 @@
-;;; context-coloring-benchmark.el --- Benchmarks for context coloring -*-
lexical-binding: t; -*-
+;;; context-coloring-benchmark.el --- Benchmarks for context coloring -*-
lexical-binding: t; no-byte-compile: t; -*-
-;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
@@ -26,8 +26,9 @@
;;; Code:
(require 'context-coloring)
+(require 'context-coloring-javascript)
+(require 'context-coloring-emacs-lisp)
(require 'elp)
-(require 'js2-mode)
(defconst context-coloring-benchmark-path
@@ -45,7 +46,7 @@
(elp-results)
(buffer-substring-no-properties (point-min)
(point-max)))
(kill-buffer))))
- (make-directory (context-coloring-benchmark-resolve-path "./logs") t)
+ (make-directory (context-coloring-benchmark-resolve-path "./benchmark") t)
(append-to-file
(with-temp-buffer
(goto-char (point-min))
@@ -73,7 +74,7 @@
(defun context-coloring-benchmark (title fixtures)
"Execute a benchmark titled TITLE against FIXTURES."
(let ((result-file (context-coloring-benchmark-resolve-path
- (format "./logs/results-%s-%s.log"
+ (format "./benchmark/results-%s-%s.log"
title (format-time-string "%s")))))
(mapc
(lambda (path)
@@ -119,10 +120,10 @@
fixtures)))
(defconst context-coloring-benchmark-javascript-fixtures
- '("./fixtures/jquery-2.1.1.js"
- "./fixtures/lodash-2.4.1.js"
- "./fixtures/async-0.9.0.js"
- "./fixtures/mkdirp-0.5.0.js")
+ '("./fixtures/benchmark/jquery-2.1.1.js"
+ "./fixtures/benchmark/lodash-2.4.1.js"
+ "./fixtures/benchmark/async-0.9.0.js"
+ "./fixtures/benchmark/mkdirp-0.5.0.js")
"Arbitrary JavaScript files for performance scrutiny.")
(defun context-coloring-benchmark-js2-mode-run ()
@@ -139,10 +140,10 @@
(remove-hook 'js2-mode-hook #'context-coloring-mode))
(defconst context-coloring-benchmark-emacs-lisp-fixtures
- '("./fixtures/lisp.el"
- "./fixtures/faces.el"
- "./fixtures/subr.el"
- "./fixtures/simple.el")
+ '("./fixtures/benchmark/lisp.el"
+ "./fixtures/benchmark/faces.el"
+ "./fixtures/benchmark/subr.el"
+ "./fixtures/benchmark/simple.el")
"Arbitrary Emacs Lisp files for performance scrutiny.")
(defun context-coloring-benchmark-emacs-lisp-mode-run ()
diff --git a/packages/context-coloring/test/context-coloring-coverage.el
b/packages/context-coloring/context-coloring-coverage.el
similarity index 96%
rename from packages/context-coloring/test/context-coloring-coverage.el
rename to packages/context-coloring/context-coloring-coverage.el
index 107908c..c63dc6b 100644
--- a/packages/context-coloring/test/context-coloring-coverage.el
+++ b/packages/context-coloring/context-coloring-coverage.el
@@ -1,6 +1,6 @@
-;;; context-coloring-coverage.el --- Test coverage for context coloring -*-
lexical-binding: t; -*-
+;;; context-coloring-coverage.el --- Test coverage for context coloring -*-
lexical-binding: t; no-byte-compile: t; -*-
-;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
@@ -111,14 +111,14 @@
(mapcar
#'context-coloring-coverage-format-source-file
(cdr (assq 'source_files coverage-data)))
- "\n"))
+ "\n\n"))
(defun context-coloring-coverage-local-init ()
"Initialize test coverage for local viewing."
(make-directory context-coloring-coverage-output-directory t)
(setq undercover-force-coverage t)
(setenv "COVERALLS_REPO_TOKEN" "noop")
- (undercover "context-coloring.el"
+ (undercover "*.el"
(:report-file context-coloring-coverage-output-file)
(:send-report nil))
(add-hook
@@ -147,7 +147,7 @@
(defun context-coloring-coverage-ci-init ()
"Initialize test coverage for continuous integration."
- (undercover "context-coloring.el")
+ (undercover "*.el")
(require 'context-coloring))
(provide 'context-coloring-coverage)
diff --git a/packages/context-coloring/context-coloring.el
b/packages/context-coloring/context-coloring-emacs-lisp.el
similarity index 53%
copy from packages/context-coloring/context-coloring.el
copy to packages/context-coloring/context-coloring-emacs-lisp.el
index e5b5a73..05caa5a 100644
--- a/packages/context-coloring/context-coloring.el
+++ b/packages/context-coloring/context-coloring-emacs-lisp.el
@@ -1,12 +1,6 @@
-;;; context-coloring.el --- Highlight by scope -*- lexical-binding: t; -*-
+;;; context-coloring-emacs-lisp.el --- Emacs Lisp support -*-
lexical-binding: t; -*-
-;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
-
-;; Author: Jackson Ray Hamilton <address@hidden>
-;; Version: 7.2.1
-;; Keywords: convenience faces tools
-;; Package-Requires: ((emacs "24.3") (js2-mode "20150713"))
-;; URL: https://github.com/jacksonrayhamilton/context-coloring
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
@@ -25,470 +19,11 @@
;;; Commentary:
-;; 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.
-
-;; By default, comments and strings are still highlighted syntactically.
+;; Add Emacs Lisp context coloring support.
;;; Code:
-(require 'js2-mode)
-
-
-;;; Utilities
-
-(defun context-coloring-join (strings delimiter)
- "Join a list of STRINGS with the string DELIMITER."
- (mapconcat #'identity strings delimiter))
-
-
-;;; Faces
-
-(defun context-coloring-defface (level light dark tty)
- "Define a face for LEVEL with LIGHT, DARK and TTY colors."
- (let ((face (intern (format "context-coloring-level-%s-face" level)))
- (doc (format "Context coloring face, level %s." level)))
- (custom-declare-face
- face
- `((((type tty)) (:foreground ,tty))
- (((background light)) (:foreground ,light))
- (((background dark)) (:foreground ,dark)))
- doc
- :group 'context-coloring)))
-
-;; Provide some default colors based off Emacs's defaults.
-(context-coloring-defface 0 "#000000" "#ffffff" nil)
-(context-coloring-defface 1 "#008b8b" "#00ffff" "yellow")
-(context-coloring-defface 2 "#0000ff" "#87cefa" "green")
-(context-coloring-defface 3 "#483d8b" "#b0c4de" "cyan")
-(context-coloring-defface 4 "#a020f0" "#eedd82" "blue")
-(context-coloring-defface 5 "#a0522d" "#98fb98" "magenta")
-(context-coloring-defface 6 "#228b22" "#7fffd4" "red")
-(context-coloring-defface 7 "#3f3f3f" "#cdcdcd" nil)
-
-(defconst context-coloring-default-maximum-face 7
- "Maximum face when there are no custom faces.")
-
-;; Create placeholder faces for users and theme authors.
-(dotimes (level 18)
- (let* ((level (+ level 8))
- (face (intern (format "context-coloring-level-%s-face" level)))
- (doc (format "Context coloring face, level %s." level)))
- (custom-declare-face face nil doc :group 'context-coloring)))
-
-(defvar-local context-coloring-maximum-face nil
- "Dynamic index of the highest face available for coloring.")
-
-(defsubst context-coloring-level-face (level)
- "Return symbol for face with LEVEL."
- ;; `concat' is faster than `format' here.
- (intern-soft
- (concat "context-coloring-level-" (number-to-string level) "-face")))
-
-(defsubst context-coloring-bounded-level-face (level)
- "Return symbol for face with LEVEL, bounded by the maximum."
- (context-coloring-level-face (min level context-coloring-maximum-face)))
-
-(defconst context-coloring-level-face-regexp
- "context-coloring-level-\\([[:digit:]]+\\)-face"
- "Extract a level from a face.")
-
-(defun context-coloring-theme-highest-level (theme)
- "Return the highest coloring level for THEME, or -1."
- (let* ((settings (get theme 'theme-settings))
- (tail settings)
- face-string
- number
- (found -1))
- (while tail
- (and (eq (nth 0 (car tail)) 'theme-face)
- (setq face-string (symbol-name (nth 1 (car tail))))
- (string-match
- context-coloring-level-face-regexp
- face-string)
- (setq number (string-to-number
- (substring face-string
- (match-beginning 1)
- (match-end 1))))
- (> number found)
- (setq found number))
- (setq tail (cdr tail)))
- found))
-
-(defun context-coloring-update-maximum-face ()
- "Save the highest possible face for the current theme."
- (let ((themes (append custom-enabled-themes '(user)))
- (continue t)
- theme
- highest-level)
- (while continue
- (setq theme (car themes))
- (setq themes (cdr themes))
- (setq highest-level (context-coloring-theme-highest-level theme))
- (setq continue (and themes (= highest-level -1))))
- (setq context-coloring-maximum-face
- (cond
- ((= highest-level -1)
- context-coloring-default-maximum-face)
- (t
- highest-level)))))
-
-
-;;; Change detection
-
-(defvar-local context-coloring-changed-p nil
- "Indication that the buffer has changed recently, which implies
-that it should be colored again by
-`context-coloring-maybe-colorize-idle-timer' if that timer is
-being used.")
-
-(defvar-local context-coloring-changed-start nil
- "Beginning of last text that changed.")
-
-(defvar-local context-coloring-changed-end nil
- "End of last text that changed.")
-
-(defvar-local context-coloring-changed-length nil
- "Length of last text that changed.")
-
-(defun context-coloring-change-function (start end length)
- "Register a change so that a buffer can be colorized soon.
-
-START, END and LENGTH are recorded for later use."
- ;; Tokenization is obsolete if there was a change.
- (setq context-coloring-changed-start start)
- (setq context-coloring-changed-end end)
- (setq context-coloring-changed-length length)
- (setq context-coloring-changed-p t))
-
-(defun context-coloring-maybe-colorize-with-buffer (buffer)
- "Color BUFFER and if it has changed."
- (when (and (eq buffer (current-buffer))
- context-coloring-changed-p)
- (context-coloring-colorize-with-buffer buffer)
- (setq context-coloring-changed-p nil)
- (setq context-coloring-changed-start nil)
- (setq context-coloring-changed-end nil)
- (setq context-coloring-changed-length nil)))
-
-(defvar-local context-coloring-maybe-colorize-idle-timer nil
- "The currently-running idle timer for conditional coloring.")
-
-(defvar-local context-coloring-colorize-idle-timer nil
- "The currently-running idle timer for unconditional coloring.")
-
-(defcustom context-coloring-default-delay 0.25
- "Default delay between a buffer update and colorization.
-
-Increase this if your machine is high-performing. Decrease it if
-it ain't."
- :type 'float
- :group 'context-coloring)
-
-(make-obsolete-variable
- 'context-coloring-delay
- 'context-coloring-default-delay
- "6.4.0")
-
-(defun context-coloring-cancel-timer (timer)
- "Cancel TIMER."
- (when timer
- (cancel-timer timer)))
-
-(defun context-coloring-schedule-coloring (time)
- "Schedule coloring to occur once after Emacs is idle for TIME."
- (context-coloring-cancel-timer context-coloring-colorize-idle-timer)
- (setq context-coloring-colorize-idle-timer
- (run-with-idle-timer
- time
- nil
- #'context-coloring-colorize-with-buffer
- (current-buffer))))
-
-(defun context-coloring-setup-idle-change-detection ()
- "Setup idle change detection."
- (let ((dispatch (context-coloring-get-current-dispatch)))
- (add-hook
- 'after-change-functions #'context-coloring-change-function nil t)
- (add-hook
- 'kill-buffer-hook #'context-coloring-teardown-idle-change-detection nil t)
- (setq context-coloring-maybe-colorize-idle-timer
- (run-with-idle-timer
- (or (plist-get dispatch :delay) context-coloring-default-delay)
- t
- #'context-coloring-maybe-colorize-with-buffer
- (current-buffer)))))
-
-(defun context-coloring-teardown-idle-change-detection ()
- "Teardown idle change detection."
- (dolist (timer (list context-coloring-colorize-idle-timer
- context-coloring-maybe-colorize-idle-timer))
- (context-coloring-cancel-timer timer))
- (remove-hook
- 'kill-buffer-hook #'context-coloring-teardown-idle-change-detection t)
- (remove-hook
- 'after-change-functions #'context-coloring-change-function t))
-
-
-;;; Colorization utilities
-
-(defsubst context-coloring-colorize-region (start end level)
- "Color from START (inclusive) to END (exclusive) with LEVEL."
- (add-text-properties
- start
- end
- `(face ,(context-coloring-bounded-level-face level))))
-
-(make-obsolete-variable
- 'context-coloring-comments-and-strings
- "use `context-coloring-syntactic-comments' and
- `context-coloring-syntactic-strings' instead."
- "6.1.0")
-
-(defcustom context-coloring-syntactic-comments t
- "If non-nil, also color comments using `font-lock'."
- :type 'boolean
- :group 'context-coloring)
-
-(defcustom context-coloring-syntactic-strings t
- "If non-nil, also color strings using `font-lock'."
- :type 'boolean
- :group 'context-coloring)
-
-(defun context-coloring-font-lock-syntactic-comment-function (state)
- "Color a comment according to STATE."
- (if (nth 3 state) nil font-lock-comment-face))
-
-(defun context-coloring-font-lock-syntactic-string-function (state)
- "Color a string according to STATE."
- (if (nth 3 state) font-lock-string-face nil))
-
-(defsubst context-coloring-colorize-comments-and-strings (&optional min max)
- "Maybe color comments and strings in buffer from MIN to MAX.
-MIN defaults to beginning of buffer. MAX defaults to end."
- (when (or context-coloring-syntactic-comments
- context-coloring-syntactic-strings)
- (let ((min (or min (point-min)))
- (max (or max (point-max)))
- (font-lock-syntactic-face-function
- (cond
- ((and context-coloring-syntactic-comments
- (not context-coloring-syntactic-strings))
- #'context-coloring-font-lock-syntactic-comment-function)
- ((and context-coloring-syntactic-strings
- (not context-coloring-syntactic-comments))
- #'context-coloring-font-lock-syntactic-string-function)
- (t
- font-lock-syntactic-face-function))))
- (save-excursion
- (font-lock-fontify-syntactically-region min max)
- ;; TODO: Make configurable at the dispatch level.
- (when (eq major-mode 'emacs-lisp-mode)
- (font-lock-fontify-keywords-region min max))))))
-
-(defcustom context-coloring-initial-level 0
- "Scope level at which to start coloring.
-
-If top-level variables and functions do not become global, but
-are scoped to a file (as in Node.js), set this to `1'."
- :type 'integer
- :safe #'integerp
- :group 'context-coloring)
-
-
-;;; JavaScript colorization
-
-(defvar-local context-coloring-js2-scope-level-hash-table nil
- "Associate `js2-scope' structures and with their scope
- levels.")
-
-(defcustom context-coloring-javascript-block-scopes nil
- "If non-nil, also color block scopes in the scope hierarchy in JavaScript.
-
-The block-scoped `let' and `const' are introduced in ES6. Enable
-this for ES6 code; disable it elsewhere."
- :type 'boolean
- :safe #'booleanp
- :group 'context-coloring)
-
-(make-obsolete-variable
- 'context-coloring-js-block-scopes
- 'context-coloring-javascript-block-scopes
- "7.0.0")
-
-(defsubst context-coloring-js2-scope-level (scope initial)
- "Return the level of SCOPE, starting from INITIAL."
- (cond ((gethash scope context-coloring-js2-scope-level-hash-table))
- (t
- (let ((level initial)
- (current-scope scope)
- enclosing-scope)
- (while (and current-scope
- (js2-node-parent current-scope)
- (setq enclosing-scope
- (js2-node-get-enclosing-scope current-scope)))
- (when (or context-coloring-javascript-block-scopes
- (let ((type (js2-scope-type current-scope)))
- (or (= type js2-SCRIPT)
- (= type js2-FUNCTION)
- (= type js2-CATCH))))
- (setq level (+ level 1)))
- (setq current-scope enclosing-scope))
- (puthash scope level
context-coloring-js2-scope-level-hash-table)))))
-
-(defsubst context-coloring-js2-local-name-node-p (node)
- "Determine if NODE represents a local variable."
- (and (js2-name-node-p node)
- (let ((parent (js2-node-parent node)))
- (not (or (and (js2-object-prop-node-p parent)
- (eq node (js2-object-prop-node-left parent)))
- (and (js2-prop-get-node-p parent)
- ;; For nested property lookup, the node on the left is a
- ;; `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
- (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-ast ()
- "Color the buffer using the `js2-mode' abstract syntax tree."
- ;; 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
- (lambda (node end-p)
- (when (null end-p)
- (cond
- ((js2-scope-p node)
- (context-coloring-js2-colorize-node
- node
- (context-coloring-js2-scope-level node
context-coloring-initial-level)))
- ((context-coloring-js2-local-name-node-p node)
- (let* ((enclosing-scope (js2-node-get-enclosing-scope node))
- (defining-scope (js2-get-defining-scope
- enclosing-scope
- (js2-name-node-name node))))
- ;; The tree seems to be walked lexically, so an entire scope will
- ;; be colored, including its name nodes, before they are reached.
- ;; Coloring the nodes defined in that scope would be redundant, so
- ;; don't do it.
- (when (not (eq defining-scope enclosing-scope))
- (context-coloring-js2-colorize-node
- node
- ;; Use `0' as an initial level so global variables are always
at
- ;; the highest level (even if `context-coloring-initial-level'
- ;; specifies an initial level for the rest of the code).
- (context-coloring-js2-scope-level defining-scope 0))))))
- ;; The `t' indicates to search children.
- t)))
- (context-coloring-colorize-comments-and-strings)))
-
-(defconst context-coloring-node-comment-regexp
- (concat
- ;; Ensure the "//" or "/*" comment starts with the directive.
- "\\(//[[:space:]]*\\|/\\*[[:space:]]*\\)"
- ;; Support multiple directive formats.
- "\\("
- ;; JSLint and JSHint support a JSON-like format.
- "\\(jslint\\|jshint\\)[[:space:]].*?node:[[:space:]]*true"
- "\\|"
- ;; ESLint just specifies the option name.
- "eslint-env[[:space:]].*?node"
- "\\)")
- "Match a comment body hinting at a Node.js program.")
-
-;; TODO: Add ES6 module detection.
-(defun context-coloring-js2-top-level-local-p ()
- "Guess whether top-level variables are local.
-For instance, the current file could be a Node.js program."
- (or
- ;; A shebang is a pretty obvious giveaway.
- (string-equal
- "node"
- (save-excursion
- (goto-char (point-min))
- (when (looking-at auto-mode-interpreter-regexp)
- (match-string 2))))
- ;; Otherwise, perform static analysis.
- (progn
- (setq context-coloring-js2-scope-level-hash-table (make-hash-table :test
#'eq))
- (catch 'node-program-p
- (js2-visit-ast
- js2-mode-ast
- (lambda (node end-p)
- (when (null end-p)
- (when
- (cond
- ;; Infer based on inline linter configuration.
- ((js2-comment-node-p node)
- (string-match-p
- context-coloring-node-comment-regexp
- (js2-node-string node)))
- ;; Infer based on the prescence of certain variables.
- ((and (js2-name-node-p node)
- (let ((parent (js2-node-parent node)))
- (not (and (js2-object-prop-node-p parent)
- (eq node (js2-object-prop-node-left
parent))))))
- (let ((name (js2-name-node-name node))
- (parent (js2-node-parent node)))
- (and
- (cond
- ;; Check whether this is "exports.something" or
- ;; "module.exports".
- ((js2-prop-get-node-p parent)
- (and
- (eq node (js2-prop-get-node-left parent))
- (or (string-equal name "exports")
- (let* ((property (js2-prop-get-node-right parent))
- (property-name (js2-name-node-name
property)))
- (and (string-equal name "module")
- (string-equal property-name "exports"))))))
- ;; Check whether it's a "require('module')" call.
- ((js2-call-node-p parent)
- (or (string-equal name "require"))))
- (let* ((enclosing-scope (js2-node-get-enclosing-scope
node))
- (defining-scope (js2-get-defining-scope
- enclosing-scope name)))
- ;; The variable also must be global.
- (null defining-scope))))))
- (throw 'node-program-p t))
- ;; The `t' indicates to search children.
- t)))
- ;; Default to returning nil from the catch body.
- nil))))
-
-(defcustom context-coloring-javascript-detect-top-level-scope t
- "If non-nil, detect when to use file-level scope."
- :type 'boolean
- :group 'context-coloring)
-
-(defun context-coloring-js2-colorize ()
- "Color the buffer using the `js2-mode'."
- (cond
- ;; Increase the initial level if we should.
- ((and context-coloring-javascript-detect-top-level-scope
- (context-coloring-js2-top-level-local-p))
- (let ((context-coloring-initial-level 1))
- (context-coloring-js2-colorize-ast)))
- (t
- (context-coloring-js2-colorize-ast))))
+(require 'context-coloring)
;;; Emacs Lisp colorization
@@ -520,11 +55,16 @@ For instance, the current file could be a Node.js program."
"Move forward through whitespace and comments."
(while (forward-comment 1)))
+(defsubst context-coloring-elisp-colorize-comments-and-strings
+ (&optional min max)
+ "Color comments and strings from MIN to MAX."
+ (context-coloring-colorize-comments-and-strings min max t))
+
(defsubst context-coloring-elisp-forward-sws ()
"Move through whitespace and comments, coloring comments."
(let ((start (point)))
(context-coloring-forward-sws)
- (context-coloring-colorize-comments-and-strings start (point))))
+ (context-coloring-elisp-colorize-comments-and-strings start (point))))
(defsubst context-coloring-elisp-forward-sexp ()
"Skip/ignore missing sexps, coloring comments and strings."
@@ -563,9 +103,6 @@ For instance, the current file could be a Node.js program."
(or (= syntax-code context-coloring-WORD-CODE)
(= syntax-code context-coloring-SYMBOL-CODE)))
-(defvar context-coloring-parse-interruptable-p t
- "Set this to nil to force parse to continue until finished.")
-
(defconst context-coloring-elisp-sexps-per-pause 350
"Pause after this many iterations to check for user input.
If user input is pending, stop the parse. This makes for a
@@ -583,7 +120,7 @@ second.")
(1+ context-coloring-elisp-sexp-count))
(when (and (zerop (% context-coloring-elisp-sexp-count
context-coloring-elisp-sexps-per-pause))
- context-coloring-parse-interruptable-p
+ context-coloring-interruptable-p
(input-pending-p))
(throw 'interrupted t)))
@@ -1074,7 +611,7 @@ It could be a quoted or backquoted expression."
(context-coloring-elisp-increment-sexp-count)
(let ((start (point)))
(forward-sexp)
- (context-coloring-colorize-comments-and-strings start (point))))
+ (context-coloring-elisp-colorize-comments-and-strings start (point))))
;; Elisp has whitespace, words, symbols, open/close parenthesis, expression
;; prefix, string quote, comment starters/enders and escape syntax classes
only.
@@ -1151,6 +688,7 @@ It could be a quoted or backquoted expression."
;; unbalanced. Just swallow them. (`progn' for test coverage.)
(scan-error (progn))))))
+;;;###autoload
(defun context-coloring-elisp-colorize ()
"Color the current Emacs Lisp buffer."
(interactive)
@@ -1159,7 +697,7 @@ It could be a quoted or backquoted expression."
(cond
;; Just colorize the changed region.
(context-coloring-changed-p
- (let* ( ;; Prevent `beginning-of-defun' from making poor assumptions.
+ (let* (;; Prevent `beginning-of-defun' from making poor assumptions.
(open-paren-in-column-0-is-defun-start nil)
;; Seek the beginning and end of the previous and next
;; offscreen defuns, so just enough is colored.
@@ -1184,6 +722,15 @@ It could be a quoted or backquoted expression."
(t
(context-coloring-elisp-colorize-region-initially (point-min)
(point-max)))))))
+;;;###autoload
+(puthash
+ 'emacs-lisp
+ (list :modes '(emacs-lisp-mode lisp-interaction-mode)
+ :colorizer #'context-coloring-elisp-colorize
+ :setup #'context-coloring-setup-idle-change-detection
+ :teardown #'context-coloring-teardown-idle-change-detection)
+ context-coloring-dispatch-hash-table)
+
;;; eval-expression colorization
@@ -1191,6 +738,7 @@ It could be a quoted or backquoted expression."
"Determine expression start in `eval-expression'."
(string-match "\\`Eval: " (buffer-string)))
+;;;###autoload
(defun context-coloring-eval-expression-colorize ()
"Color the `eval-expression' minibuffer prompt as elisp."
(interactive)
@@ -1202,207 +750,24 @@ It could be a quoted or backquoted expression."
(1+ (match-end 0)))
(point-max)))))
-
-;;; Dispatch
-
-(defvar context-coloring-dispatch-hash-table (make-hash-table :test #'eq)
- "Map dispatch strategy names to their property lists.")
-
-(defvar context-coloring-mode-hash-table (make-hash-table :test #'eq)
- "Map major mode names to dispatch property lists.")
-
-(defvar context-coloring-dispatch-predicates '()
- "Functions which may return a dispatch.")
-
-(defun context-coloring-get-current-dispatch ()
- "Return the first dispatch appropriate for the current state."
- (let ((predicates context-coloring-dispatch-predicates)
- (parent major-mode)
- dispatch)
- ;; Maybe a predicate will be satisfied and return a dispatch.
- (while (and predicates
- (not (setq dispatch (funcall (pop predicates))))))
- ;; If not, maybe a major mode (or a derivative) will define a dispatch.
- (when (not dispatch)
- (while (and parent
- (not (setq dispatch (gethash parent
context-coloring-mode-hash-table)))
- (setq parent (get parent 'derived-mode-parent)))))
- dispatch))
-
-(defun context-coloring-define-dispatch (symbol &rest properties)
- "Define a new dispatch named SYMBOL with PROPERTIES.
-
-A \"dispatch\" is a property list describing a strategy for
-coloring a buffer.
-
-PROPERTIES must include one of `:modes' or `:predicate', and a
-`:colorizer'.
-
-`:modes' - List of major modes this dispatch is valid for.
-
-`:predicate' - Function that determines if the dispatch is valid
-for any given state.
-
-`:colorizer' - Function that parses and colors the buffer.
-
-`:delay' - Delay between buffer update and colorization, to
-override `context-coloring-default-delay'.
-
-`:setup' - Arbitrary code to set up this dispatch when
-`context-coloring-mode' is enabled.
-
-`:teardown' - Arbitrary code to tear down this dispatch when
-`context-coloring-mode' is disabled."
- (let ((modes (plist-get properties :modes))
- (predicate (plist-get properties :predicate))
- (colorizer (plist-get properties :colorizer)))
- (when (null (or modes predicate))
- (error "No mode or predicate defined for dispatch"))
- (when (not colorizer)
- (error "No colorizer defined for dispatch"))
- (puthash symbol properties context-coloring-dispatch-hash-table)
- (dolist (mode modes)
- (puthash mode properties context-coloring-mode-hash-table))
- (when predicate
- (push (lambda ()
- (when (funcall predicate)
- properties)) context-coloring-dispatch-predicates))))
-
-(defun context-coloring-dispatch ()
- "Determine how to color the current buffer, and color it."
- (let* ((dispatch (context-coloring-get-current-dispatch))
- (colorizer (plist-get dispatch :colorizer)))
- (catch 'interrupted
- (funcall colorizer))))
-
-
-;;; Colorization
-
-(defun context-coloring-colorize ()
- "Color the current buffer by function context."
- (interactive)
- (context-coloring-update-maximum-face)
- (context-coloring-dispatch))
-
-(defun context-coloring-colorize-with-buffer (buffer)
- "Color BUFFER."
- ;; Don't select deleted buffers.
- (when (get-buffer buffer)
- (with-current-buffer buffer
- (context-coloring-colorize))))
-
-
-;;; Built-in dispatches
-
-(context-coloring-define-dispatch
- 'javascript
- :modes '(js2-mode)
- :colorizer #'context-coloring-js2-colorize
- :setup
- (lambda ()
- (add-hook 'js2-post-parse-callbacks #'context-coloring-colorize nil t))
- :teardown
- (lambda ()
- (remove-hook 'js2-post-parse-callbacks #'context-coloring-colorize t)))
-
-(context-coloring-define-dispatch
- 'emacs-lisp
- :modes '(emacs-lisp-mode)
- :colorizer #'context-coloring-elisp-colorize
- :delay 0.016 ;; Thanks to lazy colorization this can be 60 frames per second.
- :setup #'context-coloring-setup-idle-change-detection
- :teardown #'context-coloring-teardown-idle-change-detection)
-
;; `eval-expression-minibuffer-setup-hook' is not available in Emacs 24.3, so
;; the backwards-compatible recommendation is to use `minibuffer-setup-hook'
and
;; rely on this predicate instead.
+;;;###autoload
(defun context-coloring-eval-expression-predicate ()
"Non-nil if the minibuffer is for `eval-expression'."
;; Kinda better than checking `this-command', because `this-command' changes.
(context-coloring-eval-expression-match))
-(context-coloring-define-dispatch
- 'eval-expression
- :predicate #'context-coloring-eval-expression-predicate
- :colorizer #'context-coloring-eval-expression-colorize
- :delay 0.016
- :setup #'context-coloring-setup-idle-change-detection
- :teardown #'context-coloring-teardown-idle-change-detection)
-
-(defvar context-coloring-ignore-unavailable-predicates
- (list
- #'minibufferp)
- "Cases when \"unavailable\" messages are silenced.
-Necessary in editing states where coloring is only sometimes
-permissible.")
-
-(defun context-coloring-ignore-unavailable-message-p ()
- "Determine if the unavailable message should be silenced."
- (let ((predicates context-coloring-ignore-unavailable-predicates)
- (ignore-p nil))
- (while (and predicates
- (not ignore-p))
- (setq ignore-p (funcall (pop predicates))))
- ignore-p))
-
-
-;;; Minor mode
-
;;;###autoload
-(define-minor-mode context-coloring-mode
- "Toggle contextual code coloring.
-With a prefix argument ARG, enable Context Coloring mode if ARG
-is positive, and disable it otherwise. If called from Lisp,
-enable the mode if ARG is omitted or nil.
-
-Context Coloring mode is a buffer-local minor mode. When
-enabled, code is colored by scope. Scopes are colored
-hierarchically. Variables referenced from nested scopes retain
-the color of their defining scopes. Certain syntax, like
-comments and strings, is still colored with `font-lock'.
-
-The entire buffer is colored initially. Changes to the buffer
-trigger recoloring.
-
-Define your own colors by customizing faces like
-`context-coloring-level-N-face', where N is a number starting
-from 0. If no face is found on a custom theme nor the `user'
-theme, the defaults are used.
-
-New language / major mode support can be added with
-`context-coloring-define-dispatch', which see.
-
-Feature inspired by Douglas Crockford."
- nil " Context" nil
- (cond
- (context-coloring-mode
- ;; Font lock is incompatible with this mode; the converse is also true.
- (font-lock-mode 0)
- (jit-lock-mode nil)
- ;; ...but we do use font-lock functions here.
- (font-lock-set-defaults)
- ;; Safely change the value of this function as necessary.
- (make-local-variable 'font-lock-syntactic-face-function)
- (let ((dispatch (context-coloring-get-current-dispatch)))
- (cond
- (dispatch
- (let ((setup (plist-get dispatch :setup)))
- (when setup
- (funcall setup))
- ;; Colorize once initially.
- (let ((context-coloring-parse-interruptable-p nil))
- (context-coloring-colorize))))
- ((not (context-coloring-ignore-unavailable-message-p))
- (message "Context coloring is unavailable here")))))
- (t
- (let ((dispatch (context-coloring-get-current-dispatch)))
- (when dispatch
- (let ((teardown (plist-get dispatch :teardown)))
- (when teardown
- (funcall teardown)))))
- (font-lock-mode)
- (jit-lock-mode t))))
+(puthash
+ 'eval-expression
+ (list :predicate #'context-coloring-eval-expression-predicate
+ :colorizer #'context-coloring-eval-expression-colorize
+ :setup #'context-coloring-setup-idle-change-detection
+ :teardown #'context-coloring-teardown-idle-change-detection)
+ context-coloring-dispatch-hash-table)
-(provide 'context-coloring)
+(provide 'context-coloring-emacs-lisp)
-;;; context-coloring.el ends here
+;;; context-coloring-emacs-lisp.el ends here
diff --git a/packages/context-coloring/context-coloring-javascript.el
b/packages/context-coloring/context-coloring-javascript.el
new file mode 100644
index 0000000..d145184
--- /dev/null
+++ b/packages/context-coloring/context-coloring-javascript.el
@@ -0,0 +1,232 @@
+;;; context-coloring-javascript.el --- JavaScript support -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; 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:
+
+;; Add JavaScript context coloring support with js2-mode.
+
+;;; Code:
+
+(require 'context-coloring)
+(require 'js2-mode)
+
+
+;;; JavaScript colorization
+
+(defvar-local context-coloring-js2-scope-level-hash-table nil
+ "Associate `js2-scope' structures and with their scope
+ levels.")
+
+(defcustom context-coloring-javascript-block-scopes nil
+ "If non-nil, also color block scopes in the scope hierarchy in JavaScript.
+
+The block-scoped `let' and `const' are introduced in ES6. Enable
+this for ES6 code; disable it elsewhere."
+ :type 'boolean
+ :safe #'booleanp
+ :group 'context-coloring)
+
+(defsubst context-coloring-js2-scope-level (scope initial)
+ "Return the level of SCOPE, starting from INITIAL."
+ (cond ((gethash scope context-coloring-js2-scope-level-hash-table))
+ (t
+ (let ((level initial)
+ (current-scope scope)
+ enclosing-scope)
+ (while (and current-scope
+ (js2-node-parent current-scope)
+ (setq enclosing-scope
+ (js2-node-get-enclosing-scope current-scope)))
+ (when (or context-coloring-javascript-block-scopes
+ (let ((type (js2-scope-type current-scope)))
+ (or (= type js2-SCRIPT)
+ (= type js2-FUNCTION)
+ (= type js2-CATCH))))
+ (setq level (+ level 1)))
+ (setq current-scope enclosing-scope))
+ (puthash scope level
context-coloring-js2-scope-level-hash-table)))))
+
+(defsubst context-coloring-js2-local-name-node-p (node)
+ "Determine if NODE represents a local variable."
+ (and (js2-name-node-p node)
+ (let ((parent (js2-node-parent node)))
+ (not (or (and (js2-object-prop-node-p parent)
+ (eq node (js2-object-prop-node-left parent)))
+ (and (js2-prop-get-node-p parent)
+ ;; For nested property lookup, the node on the left is a
+ ;; `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
+ (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-ast ()
+ "Color the buffer using the `js2-mode' abstract syntax tree."
+ ;; 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
+ (lambda (node end-p)
+ (when (null end-p)
+ (cond
+ ((js2-scope-p node)
+ (context-coloring-js2-colorize-node
+ node
+ (context-coloring-js2-scope-level node
context-coloring-initial-level)))
+ ((context-coloring-js2-local-name-node-p node)
+ (let* ((enclosing-scope (js2-node-get-enclosing-scope node))
+ (defining-scope (js2-get-defining-scope
+ enclosing-scope
+ (js2-name-node-name node))))
+ ;; The tree seems to be walked lexically, so an entire scope will
+ ;; be colored, including its name nodes, before they are reached.
+ ;; Coloring the nodes defined in that scope would be redundant, so
+ ;; don't do it.
+ (when (not (eq defining-scope enclosing-scope))
+ (context-coloring-js2-colorize-node
+ node
+ ;; Use `0' as an initial level so global variables are always
at
+ ;; the highest level (even if `context-coloring-initial-level'
+ ;; specifies an initial level for the rest of the code).
+ (context-coloring-js2-scope-level defining-scope 0))))))
+ ;; The `t' indicates to search children.
+ t)))
+ (context-coloring-colorize-comments-and-strings)))
+
+(defconst context-coloring-node-comment-regexp
+ (concat
+ ;; Ensure the "//" or "/*" comment starts with the directive.
+ "\\(//[[:space:]]*\\|/\\*[[:space:]]*\\)"
+ ;; Support multiple directive formats.
+ "\\("
+ ;; JSLint and JSHint support a JSON-like format.
+ "\\(jslint\\|jshint\\)[[:space:]].*?node:[[:space:]]*true"
+ "\\|"
+ ;; ESLint just specifies the option name.
+ "eslint-env[[:space:]].*?node"
+ "\\)")
+ "Match a comment body hinting at a Node.js program.")
+
+(defun context-coloring-js2-top-level-local-p ()
+ "Guess whether top-level variables are local.
+For instance, the current file could be a Node.js program."
+ (or
+ ;; A shebang is a pretty obvious giveaway.
+ (string-equal
+ "node"
+ (save-excursion
+ (goto-char (point-min))
+ (when (looking-at auto-mode-interpreter-regexp)
+ (match-string 2))))
+ ;; Otherwise, perform static analysis.
+ (progn
+ (setq context-coloring-js2-scope-level-hash-table (make-hash-table :test
#'eq))
+ (catch 'node-program-p
+ (js2-visit-ast
+ js2-mode-ast
+ (lambda (node end-p)
+ (when (null end-p)
+ (when
+ (cond
+ ;; Infer based on inline linter configuration.
+ ((js2-comment-node-p node)
+ (string-match-p
+ context-coloring-node-comment-regexp
+ (js2-node-string node)))
+ ;; Infer based on the prescence of certain variables.
+ ((and (js2-name-node-p node)
+ (let ((parent (js2-node-parent node)))
+ (not (and (js2-object-prop-node-p parent)
+ (eq node (js2-object-prop-node-left
parent))))))
+ (let ((name (js2-name-node-name node))
+ (parent (js2-node-parent node)))
+ (and
+ (cond
+ ;; Check whether this is "exports.something" or
+ ;; "module.exports".
+ ((js2-prop-get-node-p parent)
+ (and
+ (eq node (js2-prop-get-node-left parent))
+ (or (string-equal name "exports")
+ (let* ((property (js2-prop-get-node-right parent))
+ (property-name (js2-name-node-name
property)))
+ (and (string-equal name "module")
+ (string-equal property-name "exports"))))))
+ ;; Check whether it's a "require('module')" call.
+ ((js2-call-node-p parent)
+ (or (string-equal name "require"))))
+ (let* ((enclosing-scope (js2-node-get-enclosing-scope
node))
+ (defining-scope (js2-get-defining-scope
+ enclosing-scope name)))
+ ;; The variable also must be global.
+ (null defining-scope))))))
+ (throw 'node-program-p t))
+ ;; The `t' indicates to search children.
+ t)))
+ ;; Default to returning nil from the catch body.
+ nil))))
+
+(defcustom context-coloring-javascript-detect-top-level-scope t
+ "If non-nil, detect when to use file-level scope."
+ :type 'boolean
+ :group 'context-coloring)
+
+;;;###autoload
+(defun context-coloring-js2-colorize ()
+ "Color the buffer using the `js2-mode'."
+ (cond
+ ;; Increase the initial level if we should.
+ ((and context-coloring-javascript-detect-top-level-scope
+ (context-coloring-js2-top-level-local-p))
+ (let ((context-coloring-initial-level 1))
+ (context-coloring-js2-colorize-ast)))
+ (t
+ (context-coloring-js2-colorize-ast))))
+
+;;;###autoload
+(puthash
+ 'javascript
+ (list :modes '(js2-mode js2-jsx-mode)
+ :colorizer #'context-coloring-js2-colorize
+ :setup
+ (lambda ()
+ (add-hook 'js2-post-parse-callbacks #'context-coloring-colorize nil
t))
+ :teardown
+ (lambda ()
+ (remove-hook 'js2-post-parse-callbacks #'context-coloring-colorize
t)))
+ context-coloring-dispatch-hash-table)
+
+(provide 'context-coloring-javascript)
+
+;;; context-coloring-javascript.el ends here
diff --git a/packages/context-coloring/test/context-coloring-test.el
b/packages/context-coloring/context-coloring-test.el
similarity index 93%
rename from packages/context-coloring/test/context-coloring-test.el
rename to packages/context-coloring/context-coloring-test.el
index c57dce2..1655496 100644
--- a/packages/context-coloring/test/context-coloring-test.el
+++ b/packages/context-coloring/context-coloring-test.el
@@ -1,6 +1,6 @@
-;;; context-coloring-test.el --- Tests for context coloring -*-
lexical-binding: t; -*-
+;;; context-coloring-test.el --- Tests for context coloring -*-
lexical-binding: t; no-byte-compile: t; -*-
-;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
@@ -27,8 +27,9 @@
(require 'cl-lib)
(require 'context-coloring)
+(require 'context-coloring-javascript)
+(require 'context-coloring-emacs-lisp)
(require 'ert)
-(require 'js2-mode)
;;; Test running utilities
@@ -90,9 +91,9 @@ signaled."
(name)
(t "generic"))) name)))
(fixture (cond
- (fixture (format "./fixtures/%s" fixture))
- (,no-fixture "./fixtures/empty")
- (t (format ,(format "./fixtures/%%s.%s" extension)
name)))))
+ (fixture (format "./fixtures/test/%s" fixture))
+ (,no-fixture "./fixtures/test/empty")
+ (t (format ,(format "./fixtures/test/%%s.%s" extension)
name)))))
,@`((let ((enable-context-coloring-mode
,enable-context-coloring-mode))
`(ert-deftest ,test-name ()
(context-coloring-test-with-fixture
@@ -111,8 +112,13 @@ signaled."
:mode #'fundamental-mode
:no-fixture t)
+(defun context-coloring-test-js2-mode ()
+ "Enable js2-mode and parse synchronously."
+ (js2-mode)
+ (js2-reparse))
+
(context-coloring-test-define-deftest javascript
- :mode #'js2-mode
+ :mode #'context-coloring-test-js2-mode
:extension "js"
:enable-context-coloring-mode t
:before-each (lambda ()
@@ -225,10 +231,10 @@ signaled."
(context-coloring-test-deftest mode-startup
(lambda ()
- (context-coloring-define-dispatch
+ (puthash
'mode-startup
- :modes '(context-coloring-test-mode-startup-mode)
- :colorizer #'ignore)
+ (list :modes '(context-coloring-test-mode-startup-mode))
+ context-coloring-dispatch-hash-table)
(context-coloring-test-mode-startup-mode)
(context-coloring-test-assert-causes-coloring
(context-coloring-mode)))
@@ -239,12 +245,12 @@ signaled."
(context-coloring-test-deftest change-detection
(lambda ()
- (context-coloring-define-dispatch
+ (puthash
'idle-change
- :modes '(context-coloring-test-change-detection-mode)
- :colorizer #'ignore
- :setup #'context-coloring-setup-idle-change-detection
- :teardown #'context-coloring-teardown-idle-change-detection)
+ (list :modes '(context-coloring-test-change-detection-mode)
+ :setup #'context-coloring-setup-idle-change-detection
+ :teardown #'context-coloring-teardown-idle-change-detection)
+ context-coloring-dispatch-hash-table)
(context-coloring-test-change-detection-mode)
(context-coloring-mode)
(context-coloring-test-assert-causes-coloring
@@ -262,14 +268,6 @@ signaled."
"Context coloring is unavailable here"
"*Messages*")))
-(context-coloring-test-deftest derived-mode
- (lambda ()
- (lisp-interaction-mode)
- (context-coloring-mode)
- (context-coloring-test-assert-not-message
- "Context coloring is unavailable here"
- "*Messages*")))
-
(context-coloring-test-deftest unavailable-message-ignored
(lambda ()
(minibuffer-with-setup-hook
@@ -283,33 +281,17 @@ signaled."
[?\C-u]
[?\M-!])))))
-(context-coloring-test-define-derived-mode define-dispatch-error)
-
-(context-coloring-test-deftest define-dispatch-error
- (lambda ()
- (context-coloring-test-assert-error
- (lambda ()
- (context-coloring-define-dispatch
- 'define-dispatch-no-modes))
- "No mode or predicate defined for dispatch")
- (context-coloring-test-assert-error
- (lambda ()
- (context-coloring-define-dispatch
- 'define-dispatch-no-strategy
- :modes '(context-coloring-test-define-dispatch-error-mode)))
- "No colorizer defined for dispatch")))
-
(context-coloring-test-define-derived-mode disable-mode)
(context-coloring-test-deftest disable-mode
(lambda ()
(let (torn-down)
- (context-coloring-define-dispatch
+ (puthash
'disable-mode
- :modes '(context-coloring-test-disable-mode-mode)
- :colorizer #'ignore
- :teardown (lambda ()
- (setq torn-down t)))
+ (list :modes '(context-coloring-test-disable-mode-mode)
+ :teardown (lambda ()
+ (setq torn-down t)))
+ context-coloring-dispatch-hash-table)
(context-coloring-test-disable-mode-mode)
(context-coloring-mode)
(context-coloring-mode -1)
@@ -335,10 +317,10 @@ signaled."
(custom-set-faces
'(context-coloring-level-0-face ((t :foreground "#aaaaaa"))))
(enable-theme 'context-coloring-test-custom-theme)
- (context-coloring-define-dispatch
+ (puthash
'theme
- :modes '(context-coloring-test-custom-theme-mode)
- :colorizer #'ignore)
+ (list :modes '(context-coloring-test-custom-theme-mode))
+ context-coloring-dispatch-hash-table)
(context-coloring-test-custom-theme-mode)
(context-coloring-colorize)
(context-coloring-test-assert-maximum-face 1)
@@ -899,7 +881,7 @@ nnnn nn")))
;; the minibuffer's contents. The contents are implicitly submitted,
;; so we have to ignore the errors in the arbitrary test subject
code.
(insert "(ignore-errors (let (a) (message a free)))")
- (context-coloring-colorize)
+ (context-coloring-mode)
(context-coloring-test-assert-coloring "
xxxx: 0000000-000000 1111 111 11111111 1 0000110"))
;; Simulate user input because `call-interactively' is blocking and
diff --git a/packages/context-coloring/context-coloring.el
b/packages/context-coloring/context-coloring.el
index e5b5a73..fd7a816 100644
--- a/packages/context-coloring/context-coloring.el
+++ b/packages/context-coloring/context-coloring.el
@@ -1,11 +1,11 @@
;;; context-coloring.el --- Highlight by scope -*- lexical-binding: t; -*-
-;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
;; Author: Jackson Ray Hamilton <address@hidden>
-;; Version: 7.2.1
+;; Version: 8.0.1
;; Keywords: convenience faces tools
-;; Package-Requires: ((emacs "24.3") (js2-mode "20150713"))
+;; Package-Requires: ((emacs "24.3"))
;; URL: https://github.com/jacksonrayhamilton/context-coloring
;; This file is part of GNU Emacs.
@@ -34,8 +34,6 @@
;;; Code:
-(require 'js2-mode)
-
;;; Utilities
@@ -187,11 +185,6 @@ it ain't."
:type 'float
:group 'context-coloring)
-(make-obsolete-variable
- 'context-coloring-delay
- 'context-coloring-default-delay
- "6.4.0")
-
(defun context-coloring-cancel-timer (timer)
"Cancel TIMER."
(when timer
@@ -241,12 +234,6 @@ it ain't."
end
`(face ,(context-coloring-bounded-level-face level))))
-(make-obsolete-variable
- 'context-coloring-comments-and-strings
- "use `context-coloring-syntactic-comments' and
- `context-coloring-syntactic-strings' instead."
- "6.1.0")
-
(defcustom context-coloring-syntactic-comments t
"If non-nil, also color comments using `font-lock'."
:type 'boolean
@@ -265,9 +252,10 @@ it ain't."
"Color a string according to STATE."
(if (nth 3 state) font-lock-string-face nil))
-(defsubst context-coloring-colorize-comments-and-strings (&optional min max)
+(defsubst context-coloring-colorize-comments-and-strings (&optional min max
keywords-p)
"Maybe color comments and strings in buffer from MIN to MAX.
-MIN defaults to beginning of buffer. MAX defaults to end."
+MIN defaults to beginning of buffer. MAX defaults to end. If
+KEYWORDS-P is non-nil, also color keywords from MIN to MAX."
(when (or context-coloring-syntactic-comments
context-coloring-syntactic-strings)
(let ((min (or min (point-min)))
@@ -284,8 +272,7 @@ MIN defaults to beginning of buffer. MAX defaults to end."
font-lock-syntactic-face-function))))
(save-excursion
(font-lock-fontify-syntactically-region min max)
- ;; TODO: Make configurable at the dispatch level.
- (when (eq major-mode 'emacs-lisp-mode)
+ (when keywords-p
(font-lock-fontify-keywords-region min max))))))
(defcustom context-coloring-initial-level 0
@@ -298,945 +285,17 @@ are scoped to a file (as in Node.js), set this to `1'."
:group 'context-coloring)
-;;; JavaScript colorization
-
-(defvar-local context-coloring-js2-scope-level-hash-table nil
- "Associate `js2-scope' structures and with their scope
- levels.")
-
-(defcustom context-coloring-javascript-block-scopes nil
- "If non-nil, also color block scopes in the scope hierarchy in JavaScript.
-
-The block-scoped `let' and `const' are introduced in ES6. Enable
-this for ES6 code; disable it elsewhere."
- :type 'boolean
- :safe #'booleanp
- :group 'context-coloring)
-
-(make-obsolete-variable
- 'context-coloring-js-block-scopes
- 'context-coloring-javascript-block-scopes
- "7.0.0")
-
-(defsubst context-coloring-js2-scope-level (scope initial)
- "Return the level of SCOPE, starting from INITIAL."
- (cond ((gethash scope context-coloring-js2-scope-level-hash-table))
- (t
- (let ((level initial)
- (current-scope scope)
- enclosing-scope)
- (while (and current-scope
- (js2-node-parent current-scope)
- (setq enclosing-scope
- (js2-node-get-enclosing-scope current-scope)))
- (when (or context-coloring-javascript-block-scopes
- (let ((type (js2-scope-type current-scope)))
- (or (= type js2-SCRIPT)
- (= type js2-FUNCTION)
- (= type js2-CATCH))))
- (setq level (+ level 1)))
- (setq current-scope enclosing-scope))
- (puthash scope level
context-coloring-js2-scope-level-hash-table)))))
-
-(defsubst context-coloring-js2-local-name-node-p (node)
- "Determine if NODE represents a local variable."
- (and (js2-name-node-p node)
- (let ((parent (js2-node-parent node)))
- (not (or (and (js2-object-prop-node-p parent)
- (eq node (js2-object-prop-node-left parent)))
- (and (js2-prop-get-node-p parent)
- ;; For nested property lookup, the node on the left is a
- ;; `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
- (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-ast ()
- "Color the buffer using the `js2-mode' abstract syntax tree."
- ;; 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
- (lambda (node end-p)
- (when (null end-p)
- (cond
- ((js2-scope-p node)
- (context-coloring-js2-colorize-node
- node
- (context-coloring-js2-scope-level node
context-coloring-initial-level)))
- ((context-coloring-js2-local-name-node-p node)
- (let* ((enclosing-scope (js2-node-get-enclosing-scope node))
- (defining-scope (js2-get-defining-scope
- enclosing-scope
- (js2-name-node-name node))))
- ;; The tree seems to be walked lexically, so an entire scope will
- ;; be colored, including its name nodes, before they are reached.
- ;; Coloring the nodes defined in that scope would be redundant, so
- ;; don't do it.
- (when (not (eq defining-scope enclosing-scope))
- (context-coloring-js2-colorize-node
- node
- ;; Use `0' as an initial level so global variables are always
at
- ;; the highest level (even if `context-coloring-initial-level'
- ;; specifies an initial level for the rest of the code).
- (context-coloring-js2-scope-level defining-scope 0))))))
- ;; The `t' indicates to search children.
- t)))
- (context-coloring-colorize-comments-and-strings)))
-
-(defconst context-coloring-node-comment-regexp
- (concat
- ;; Ensure the "//" or "/*" comment starts with the directive.
- "\\(//[[:space:]]*\\|/\\*[[:space:]]*\\)"
- ;; Support multiple directive formats.
- "\\("
- ;; JSLint and JSHint support a JSON-like format.
- "\\(jslint\\|jshint\\)[[:space:]].*?node:[[:space:]]*true"
- "\\|"
- ;; ESLint just specifies the option name.
- "eslint-env[[:space:]].*?node"
- "\\)")
- "Match a comment body hinting at a Node.js program.")
-
-;; TODO: Add ES6 module detection.
-(defun context-coloring-js2-top-level-local-p ()
- "Guess whether top-level variables are local.
-For instance, the current file could be a Node.js program."
- (or
- ;; A shebang is a pretty obvious giveaway.
- (string-equal
- "node"
- (save-excursion
- (goto-char (point-min))
- (when (looking-at auto-mode-interpreter-regexp)
- (match-string 2))))
- ;; Otherwise, perform static analysis.
- (progn
- (setq context-coloring-js2-scope-level-hash-table (make-hash-table :test
#'eq))
- (catch 'node-program-p
- (js2-visit-ast
- js2-mode-ast
- (lambda (node end-p)
- (when (null end-p)
- (when
- (cond
- ;; Infer based on inline linter configuration.
- ((js2-comment-node-p node)
- (string-match-p
- context-coloring-node-comment-regexp
- (js2-node-string node)))
- ;; Infer based on the prescence of certain variables.
- ((and (js2-name-node-p node)
- (let ((parent (js2-node-parent node)))
- (not (and (js2-object-prop-node-p parent)
- (eq node (js2-object-prop-node-left
parent))))))
- (let ((name (js2-name-node-name node))
- (parent (js2-node-parent node)))
- (and
- (cond
- ;; Check whether this is "exports.something" or
- ;; "module.exports".
- ((js2-prop-get-node-p parent)
- (and
- (eq node (js2-prop-get-node-left parent))
- (or (string-equal name "exports")
- (let* ((property (js2-prop-get-node-right parent))
- (property-name (js2-name-node-name
property)))
- (and (string-equal name "module")
- (string-equal property-name "exports"))))))
- ;; Check whether it's a "require('module')" call.
- ((js2-call-node-p parent)
- (or (string-equal name "require"))))
- (let* ((enclosing-scope (js2-node-get-enclosing-scope
node))
- (defining-scope (js2-get-defining-scope
- enclosing-scope name)))
- ;; The variable also must be global.
- (null defining-scope))))))
- (throw 'node-program-p t))
- ;; The `t' indicates to search children.
- t)))
- ;; Default to returning nil from the catch body.
- nil))))
-
-(defcustom context-coloring-javascript-detect-top-level-scope t
- "If non-nil, detect when to use file-level scope."
- :type 'boolean
- :group 'context-coloring)
-
-(defun context-coloring-js2-colorize ()
- "Color the buffer using the `js2-mode'."
- (cond
- ;; Increase the initial level if we should.
- ((and context-coloring-javascript-detect-top-level-scope
- (context-coloring-js2-top-level-local-p))
- (let ((context-coloring-initial-level 1))
- (context-coloring-js2-colorize-ast)))
- (t
- (context-coloring-js2-colorize-ast))))
-
-
-;;; Emacs Lisp colorization
-
-(defconst context-coloring-WORD-CODE 2)
-(defconst context-coloring-SYMBOL-CODE 3)
-(defconst context-coloring-OPEN-PARENTHESIS-CODE 4)
-(defconst context-coloring-CLOSE-PARENTHESIS-CODE 5)
-(defconst context-coloring-EXPRESSION-PREFIX-CODE 6)
-(defconst context-coloring-STRING-QUOTE-CODE 7)
-(defconst context-coloring-ESCAPE-CODE 9)
-(defconst context-coloring-COMMENT-START-CODE 11)
-(defconst context-coloring-COMMENT-END-CODE 12)
-
-(defconst context-coloring-OCTOTHORPE-CHAR (string-to-char "#"))
-(defconst context-coloring-APOSTROPHE-CHAR (string-to-char "'"))
-(defconst context-coloring-OPEN-PARENTHESIS-CHAR (string-to-char "("))
-(defconst context-coloring-COMMA-CHAR (string-to-char ","))
-(defconst context-coloring-AT-CHAR (string-to-char "@"))
-(defconst context-coloring-BACKTICK-CHAR (string-to-char "`"))
-
-(defsubst context-coloring-get-syntax-code ()
- "Get the syntax code at point."
- (syntax-class
- ;; Faster version of `syntax-after':
- (aref (syntax-table) (char-after (point)))))
-
-(defsubst context-coloring-forward-sws ()
- "Move forward through whitespace and comments."
- (while (forward-comment 1)))
-
-(defsubst context-coloring-elisp-forward-sws ()
- "Move through whitespace and comments, coloring comments."
- (let ((start (point)))
- (context-coloring-forward-sws)
- (context-coloring-colorize-comments-and-strings start (point))))
-
-(defsubst context-coloring-elisp-forward-sexp ()
- "Skip/ignore missing sexps, coloring comments and strings."
- (let ((start (point)))
- (when (= (context-coloring-get-syntax-code)
- context-coloring-EXPRESSION-PREFIX-CODE)
- ;; `forward-sexp' does not skip an unfinished expression (e.g. when the
- ;; name of a symbol or the parentheses of a list do not follow a single
- ;; quote).
- (forward-char))
- (condition-case nil
- (forward-sexp)
- (scan-error (context-coloring-forward-sws)))
- (context-coloring-elisp-colorize-comments-and-strings-in-region
- start (point))))
-
-(defsubst context-coloring-exact-regexp (word)
- "Create a regexp matching exactly WORD."
- (concat "\\`" (regexp-quote word) "\\'"))
-
-(defsubst context-coloring-exact-or-regexp (words)
- "Create a regexp matching any exact word in WORDS."
- (context-coloring-join
- (mapcar #'context-coloring-exact-regexp words) "\\|"))
-
-(defconst context-coloring-elisp-ignored-word-regexp
- (context-coloring-join (list "\\`[-+]?[0-9]"
- "\\`[&:].+"
- (context-coloring-exact-or-regexp
- '("t" "nil" "." "?")))
- "\\|")
- "Match symbols that can't be bound as variables.")
-
-(defsubst context-coloring-elisp-identifier-p (syntax-code)
- "Check if SYNTAX-CODE is an elisp identifier constituent."
- (or (= syntax-code context-coloring-WORD-CODE)
- (= syntax-code context-coloring-SYMBOL-CODE)))
-
-(defvar context-coloring-parse-interruptable-p t
- "Set this to nil to force parse to continue until finished.")
-
-(defconst context-coloring-elisp-sexps-per-pause 350
- "Pause after this many iterations to check for user input.
-If user input is pending, stop the parse. This makes for a
-smoother user experience for large files.
-
-This number should trigger pausing at about 60 frames per
-second.")
-
-(defvar context-coloring-elisp-sexp-count 0
- "Current number of sexps leading up to the next pause.")
-
-(defsubst context-coloring-elisp-increment-sexp-count ()
- "Maybe check if the user interrupted the current parse."
- (setq context-coloring-elisp-sexp-count
- (1+ context-coloring-elisp-sexp-count))
- (when (and (zerop (% context-coloring-elisp-sexp-count
- context-coloring-elisp-sexps-per-pause))
- context-coloring-parse-interruptable-p
- (input-pending-p))
- (throw 'interrupted t)))
-
-(defvar context-coloring-elisp-scope-stack '()
- "List of scopes in the current parse.")
-
-(defsubst context-coloring-elisp-make-scope (level)
- "Make a scope object for LEVEL."
- (list
- :level level
- :variables '()))
-
-(defsubst context-coloring-elisp-scope-get-level (scope)
- "Get the level of SCOPE object."
- (plist-get scope :level))
-
-(defsubst context-coloring-elisp-scope-add-variable (scope variable)
- "Add to SCOPE a VARIABLE."
- (plist-put scope :variables (cons variable (plist-get scope :variables))))
-
-(defsubst context-coloring-elisp-scope-has-variable (scope variable)
- "Check if SCOPE has VARIABLE."
- (member variable (plist-get scope :variables)))
-
-(defsubst context-coloring-elisp-get-variable-level (variable)
- "Return the level of VARIABLE, or 0 if it isn't found."
- (let* ((scope-stack context-coloring-elisp-scope-stack)
- scope
- level)
- (while (and scope-stack (not level))
- (setq scope (car scope-stack))
- (cond
- ((context-coloring-elisp-scope-has-variable scope variable)
- (setq level (context-coloring-elisp-scope-get-level scope)))
- (t
- (setq scope-stack (cdr scope-stack)))))
- ;; Assume a global variable.
- (or level 0)))
-
-(defsubst context-coloring-elisp-get-current-scope-level ()
- "Get the nesting level of the current scope."
- (cond
- ((car context-coloring-elisp-scope-stack)
- (context-coloring-elisp-scope-get-level (car
context-coloring-elisp-scope-stack)))
- (t
- 0)))
-
-(defsubst context-coloring-elisp-push-scope ()
- "Add a new scope to the bottom of the scope chain."
- (push (context-coloring-elisp-make-scope
- (1+ (context-coloring-elisp-get-current-scope-level)))
- context-coloring-elisp-scope-stack))
-
-(defsubst context-coloring-elisp-pop-scope ()
- "Remove the scope on the bottom of the scope chain."
- (pop context-coloring-elisp-scope-stack))
-
-(defsubst context-coloring-elisp-add-variable (variable)
- "Add VARIABLE to the current scope."
- (context-coloring-elisp-scope-add-variable
- (car context-coloring-elisp-scope-stack)
- variable))
-
-(defsubst context-coloring-elisp-parse-bindable (callback)
- "Parse the symbol at point.
-If the symbol can be bound, invoke CALLBACK with it."
- (let* ((arg-string (buffer-substring-no-properties
- (point)
- (progn (context-coloring-elisp-forward-sexp)
- (point)))))
- (when (not (string-match-p
- context-coloring-elisp-ignored-word-regexp
- arg-string))
- (funcall callback arg-string))))
-
-(defun context-coloring-elisp-parse-let-varlist (type)
- "Parse the list of variable initializers at point.
-If TYPE is `let', all the variables are bound after all their
-initializers are parsed; if TYPE is `let*', each variable is
-bound immediately after its own initializer is parsed."
- (let ((varlist '())
- syntax-code)
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (setq syntax-code (context-coloring-get-syntax-code))
- (when (context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-parse-bindable
- (lambda (var)
- (push var varlist)))
- (context-coloring-elisp-forward-sws)
- (setq syntax-code (context-coloring-get-syntax-code))
- (when (/= syntax-code context-coloring-CLOSE-PARENTHESIS-CODE)
- (context-coloring-elisp-colorize-sexp)))
- (context-coloring-elisp-forward-sws)
- ;; Skip past the closing parenthesis.
- (forward-char))
- ((context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-parse-bindable
- (lambda (var)
- (push var varlist))))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (when (eq type 'let*)
- (context-coloring-elisp-add-variable (pop varlist)))
- (context-coloring-elisp-forward-sws))
- (when (eq type 'let)
- (while varlist
- (context-coloring-elisp-add-variable (pop varlist))))
- ;; Exit.
- (forward-char)))
-
-(defun context-coloring-elisp-parse-arglist ()
- "Parse the list of function arguments at point."
- (let (syntax-code)
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-parse-bindable
- (lambda (arg)
- (context-coloring-elisp-add-variable arg))))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (context-coloring-elisp-forward-sws))
- ;; Exit.
- (forward-char)))
-
-(defun context-coloring-elisp-skip-callee-name ()
- "Skip past the opening parenthesis and name of a function."
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- ;; Skip past the function name.
- (forward-sexp)
- (context-coloring-elisp-forward-sws))
-
-(defun context-coloring-elisp-colorize-scope (callback)
- "Color the whole scope at point with its one color.
-Handle a header in CALLBACK."
- (let ((start (point))
- (end (progn (forward-sexp)
- (point))))
- (context-coloring-elisp-push-scope)
- ;; Splash the whole thing in one color.
- (context-coloring-colorize-region
- start
- end
- (context-coloring-elisp-get-current-scope-level))
- ;; Even if the parse is interrupted, this region should still be colored
- ;; syntactically.
- (context-coloring-elisp-colorize-comments-and-strings-in-region
- start
- end)
- (goto-char start)
- (context-coloring-elisp-skip-callee-name)
- (funcall callback)
- (context-coloring-elisp-colorize-region (point) (1- end))
- ;; Exit.
- (forward-char)
- (context-coloring-elisp-pop-scope)))
-
-(defun context-coloring-elisp-parse-header (callback)
- "Parse a function header at point with CALLBACK."
- (when (= (context-coloring-get-syntax-code)
context-coloring-OPEN-PARENTHESIS-CODE)
- (funcall callback)))
-
-(defun context-coloring-elisp-colorize-defun-like (callback)
- "Color the defun-like function at point.
-Parse the header with CALLBACK."
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (when (context-coloring-elisp-identifier-p
(context-coloring-get-syntax-code))
- ;; Color the defun's name with the top-level color.
- (context-coloring-colorize-region
- (point)
- (progn (forward-sexp)
- (point))
- 0)
- (context-coloring-elisp-forward-sws)
- (context-coloring-elisp-parse-header callback)))))
-
-(defun context-coloring-elisp-colorize-defun ()
- "Color the `defun' at point."
- (context-coloring-elisp-colorize-defun-like
- 'context-coloring-elisp-parse-arglist))
-
-(defun context-coloring-elisp-colorize-defadvice ()
- "Color the `defadvice' at point."
- (context-coloring-elisp-colorize-defun-like
- (lambda ()
- (let (syntax-code)
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (context-coloring-elisp-parse-arglist))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (context-coloring-elisp-forward-sws))))))
-
-(defun context-coloring-elisp-colorize-lambda-like (callback)
- "Color the lambda-like function at point.
-Parsing the header with CALLBACK."
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (context-coloring-elisp-parse-header callback))))
-
-(defun context-coloring-elisp-colorize-lambda ()
- "Color the `lambda' at point."
- (context-coloring-elisp-colorize-lambda-like
- 'context-coloring-elisp-parse-arglist))
-
-(defun context-coloring-elisp-colorize-let ()
- "Color the `let' at point."
- (context-coloring-elisp-colorize-lambda-like
- (lambda ()
- (context-coloring-elisp-parse-let-varlist 'let))))
-
-(defun context-coloring-elisp-colorize-let* ()
- "Color the `let*' at point."
- (context-coloring-elisp-colorize-lambda-like
- (lambda ()
- (context-coloring-elisp-parse-let-varlist 'let*))))
-
-(defun context-coloring-elisp-colorize-macroexp-let2 ()
- "Color the `macroexp-let2' at point."
- (let (syntax-code
- variable)
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (and
- (progn
- (setq syntax-code (context-coloring-get-syntax-code))
- (context-coloring-elisp-identifier-p syntax-code))
- (progn
- (context-coloring-elisp-colorize-sexp)
- (context-coloring-elisp-forward-sws)
- (setq syntax-code (context-coloring-get-syntax-code))
- (context-coloring-elisp-identifier-p syntax-code))
- (progn
- (context-coloring-elisp-parse-bindable
- (lambda (parsed-variable)
- (setq variable parsed-variable)))
- (context-coloring-elisp-forward-sws)
- (when variable
- (context-coloring-elisp-add-variable variable))))))))
-
-(defun context-coloring-elisp-colorize-cond ()
- "Color the `cond' at point."
- (let (syntax-code)
- (context-coloring-elisp-skip-callee-name)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- ;; Colorize inside the parens.
- (let ((start (point)))
- (forward-sexp)
- (context-coloring-elisp-colorize-region
- (1+ start) (1- (point)))
- ;; Exit.
- (forward-char)))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (context-coloring-elisp-forward-sws))
- ;; Exit.
- (forward-char)))
-
-(defun context-coloring-elisp-colorize-condition-case ()
- "Color the `condition-case' at point."
- (let (syntax-code
- variable
- case-pos
- case-end)
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (setq syntax-code (context-coloring-get-syntax-code))
- ;; Gracefully ignore missing variables.
- (when (context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-parse-bindable
- (lambda (parsed-variable)
- (setq variable parsed-variable)))
- (context-coloring-elisp-forward-sws))
- (context-coloring-elisp-colorize-sexp)
- (context-coloring-elisp-forward-sws)
- ;; Parse the handlers with the error variable in scope.
- (when variable
- (context-coloring-elisp-add-variable variable))
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (setq case-pos (point))
- (context-coloring-elisp-forward-sexp)
- (setq case-end (point))
- (goto-char case-pos)
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (setq syntax-code (context-coloring-get-syntax-code))
- (when (/= syntax-code context-coloring-CLOSE-PARENTHESIS-CODE)
- ;; Skip the condition name(s).
- (context-coloring-elisp-forward-sexp)
- ;; Color the remaining portion of the handler.
- (context-coloring-elisp-colorize-region
- (point)
- (1- case-end)))
- ;; Exit.
- (forward-char))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (context-coloring-elisp-forward-sws))))))
-
-(defun context-coloring-elisp-colorize-dolist ()
- "Color the `dolist' at point."
- (let (syntax-code
- (index 0))
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (setq syntax-code (context-coloring-get-syntax-code))
- (when (= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((and
- (or (= index 0) (= index 2))
- (context-coloring-elisp-identifier-p syntax-code))
- ;; Add the first or third name to the scope.
- (context-coloring-elisp-parse-bindable
- (lambda (variable)
- (context-coloring-elisp-add-variable variable))))
- (t
- ;; Color artifacts.
- (context-coloring-elisp-colorize-sexp)))
- (context-coloring-elisp-forward-sws)
- (setq index (1+ index)))
- ;; Exit.
- (forward-char))))))
-
-(defun context-coloring-elisp-colorize-quote ()
- "Color the `quote' at point."
- (let* ((start (point))
- (end (progn (forward-sexp)
- (point))))
- (context-coloring-colorize-region
- start
- end
- (context-coloring-elisp-get-current-scope-level))
- (context-coloring-elisp-colorize-comments-and-strings-in-region start
end)))
-
-(defvar context-coloring-elisp-callee-dispatch-hash-table
- (let ((table (make-hash-table :test 'equal)))
- (dolist (callee '("defun" "defun*" "defsubst" "defmacro" "cl-defun"
"cl-defsubst" "cl-defmacro"))
- (puthash callee #'context-coloring-elisp-colorize-defun table))
- (dolist (callee '("condition-case" "condition-case-unless-debug"))
- (puthash callee #'context-coloring-elisp-colorize-condition-case table))
- (dolist (callee '("dolist" "dotimes"))
- (puthash callee #'context-coloring-elisp-colorize-dolist table))
- (dolist (callee '("let" "gv-letplace"))
- (puthash callee #'context-coloring-elisp-colorize-let table))
- (puthash "let*" #'context-coloring-elisp-colorize-let* table)
- (puthash "macroexp-let2" #'context-coloring-elisp-colorize-macroexp-let2
table)
- (puthash "lambda" #'context-coloring-elisp-colorize-lambda table)
- (puthash "cond" #'context-coloring-elisp-colorize-cond table)
- (puthash "defadvice" #'context-coloring-elisp-colorize-defadvice table)
- (puthash "quote" #'context-coloring-elisp-colorize-quote table)
- (puthash "backquote" #'context-coloring-elisp-colorize-backquote table)
- table)
- "Map function names to their coloring functions.")
-
-(defun context-coloring-elisp-colorize-parenthesized-sexp ()
- "Color the sexp enclosed by parenthesis at point."
- (context-coloring-elisp-increment-sexp-count)
- (let* ((start (point))
- (end (progn (forward-sexp)
- (point)))
- (syntax-code (progn (goto-char start)
- (forward-char)
- ;; Coloring is unnecessary here, it'll happen
- ;; presently.
- (context-coloring-forward-sws)
- (context-coloring-get-syntax-code)))
- dispatch-function)
- ;; Figure out if the sexp is a special form.
- (cond
- ((and (context-coloring-elisp-identifier-p syntax-code)
- (setq dispatch-function (gethash
- (buffer-substring-no-properties
- (point)
- (progn (forward-sexp)
- (point)))
-
context-coloring-elisp-callee-dispatch-hash-table)))
- (goto-char start)
- (funcall dispatch-function))
- ;; Not a special form; just colorize the remaining region.
- (t
- (context-coloring-colorize-region
- start
- end
- (context-coloring-elisp-get-current-scope-level))
- (context-coloring-elisp-colorize-region (point) (1- end))
- (forward-char)))))
-
-(defun context-coloring-elisp-colorize-symbol ()
- "Color the symbol at point."
- (context-coloring-elisp-increment-sexp-count)
- (let* ((symbol-pos (point))
- (symbol-end (progn (forward-sexp)
- (point)))
- (symbol-string (buffer-substring-no-properties
- symbol-pos
- symbol-end)))
- (cond
- ((string-match-p context-coloring-elisp-ignored-word-regexp
symbol-string))
- (t
- (context-coloring-colorize-region
- symbol-pos
- symbol-end
- (context-coloring-elisp-get-variable-level
- symbol-string))))))
-
-(defun context-coloring-elisp-colorize-backquote-form ()
- "Color the backquote form at point."
- (let ((start (point))
- (end (progn (forward-sexp)
- (point)))
- char)
- (goto-char start)
- (while (> end (progn (forward-char)
- (point)))
- (setq char (char-after))
- (when (= char context-coloring-COMMA-CHAR)
- (forward-char)
- (when (= (char-after) context-coloring-AT-CHAR)
- ;; If we don't do this "@" could be interpreted as a symbol.
- (forward-char))
- (context-coloring-elisp-forward-sws)
- (context-coloring-elisp-colorize-sexp)))
- ;; We could probably do this as part of the above loop but it'd be
- ;; repetitive.
- (context-coloring-elisp-colorize-comments-and-strings-in-region
- start end)))
-
-(defun context-coloring-elisp-colorize-backquote ()
- "Color the `backquote' at point."
- (context-coloring-elisp-skip-callee-name)
- (context-coloring-elisp-colorize-backquote-form)
- ;; Exit.
- (forward-char))
-
-(defun context-coloring-elisp-colorize-expression-prefix ()
- "Color the expression prefix and expression at point.
-It could be a quoted or backquoted expression."
- (context-coloring-elisp-increment-sexp-count)
- (cond
- ((/= (char-after) context-coloring-BACKTICK-CHAR)
- (context-coloring-elisp-forward-sexp))
- (t
- (context-coloring-elisp-colorize-backquote-form))))
-
-(defun context-coloring-elisp-colorize-comment ()
- "Color the comment at point."
- (context-coloring-elisp-increment-sexp-count)
- (context-coloring-elisp-forward-sws))
-
-(defun context-coloring-elisp-colorize-string ()
- "Color the string at point."
- (context-coloring-elisp-increment-sexp-count)
- (let ((start (point)))
- (forward-sexp)
- (context-coloring-colorize-comments-and-strings start (point))))
-
-;; Elisp has whitespace, words, symbols, open/close parenthesis, expression
-;; prefix, string quote, comment starters/enders and escape syntax classes
only.
-
-(defun context-coloring-elisp-colorize-sexp ()
- "Color the sexp at point."
- (let ((syntax-code (context-coloring-get-syntax-code)))
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (context-coloring-elisp-colorize-parenthesized-sexp))
- ((context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-colorize-symbol))
- ((= syntax-code context-coloring-EXPRESSION-PREFIX-CODE)
- (context-coloring-elisp-colorize-expression-prefix))
- ((= syntax-code context-coloring-STRING-QUOTE-CODE)
- (context-coloring-elisp-colorize-string))
- ((= syntax-code context-coloring-ESCAPE-CODE)
- (forward-char 2)))))
-
-(defun context-coloring-elisp-colorize-comments-and-strings-in-region (start
end)
- "Color comments and strings between START and END."
- (let (syntax-code)
- (goto-char start)
- (while (> end (progn (skip-syntax-forward "^\"<\\" end)
- (point)))
- (setq syntax-code (context-coloring-get-syntax-code))
- (cond
- ((= syntax-code context-coloring-STRING-QUOTE-CODE)
- (context-coloring-elisp-colorize-string))
- ((= syntax-code context-coloring-COMMENT-START-CODE)
- (context-coloring-elisp-colorize-comment))
- ((= syntax-code context-coloring-ESCAPE-CODE)
- (forward-char 2))))))
-
-(defun context-coloring-elisp-colorize-region (start end)
- "Color everything between START and END."
- (let (syntax-code)
- (goto-char start)
- (while (> end (progn (skip-syntax-forward "^w_('\"<\\" end)
- (point)))
- (setq syntax-code (context-coloring-get-syntax-code))
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (context-coloring-elisp-colorize-parenthesized-sexp))
- ((context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-colorize-symbol))
- ((= syntax-code context-coloring-EXPRESSION-PREFIX-CODE)
- (context-coloring-elisp-colorize-expression-prefix))
- ((= syntax-code context-coloring-STRING-QUOTE-CODE)
- (context-coloring-elisp-colorize-string))
- ((= syntax-code context-coloring-COMMENT-START-CODE)
- (context-coloring-elisp-colorize-comment))
- ((= syntax-code context-coloring-ESCAPE-CODE)
- (forward-char 2))))))
-
-(defun context-coloring-elisp-colorize-region-initially (start end)
- "Begin coloring everything between START and END."
- (setq context-coloring-elisp-sexp-count 0)
- (setq context-coloring-elisp-scope-stack '())
- (let ((inhibit-point-motion-hooks t)
- (case-fold-search nil)
- ;; This is a recursive-descent parser, so give it a big stack.
- (max-lisp-eval-depth (max max-lisp-eval-depth 3000))
- (max-specpdl-size (max max-specpdl-size 3000)))
- (context-coloring-elisp-colorize-region start end)))
-
-(defun context-coloring-elisp-colorize-guard (callback)
- "Silently color in CALLBACK."
- (with-silent-modifications
- (save-excursion
- (condition-case nil
- (funcall callback)
- ;; Scan errors can happen virtually anywhere if parenthesis are
- ;; unbalanced. Just swallow them. (`progn' for test coverage.)
- (scan-error (progn))))))
-
-(defun context-coloring-elisp-colorize ()
- "Color the current Emacs Lisp buffer."
- (interactive)
- (context-coloring-elisp-colorize-guard
- (lambda ()
- (cond
- ;; Just colorize the changed region.
- (context-coloring-changed-p
- (let* ( ;; Prevent `beginning-of-defun' from making poor assumptions.
- (open-paren-in-column-0-is-defun-start nil)
- ;; Seek the beginning and end of the previous and next
- ;; offscreen defuns, so just enough is colored.
- (start (progn (goto-char context-coloring-changed-start)
- (while (and (< (point-min) (point))
- (pos-visible-in-window-p))
- (end-of-line 0))
- (beginning-of-defun)
- (point)))
- (end (progn (goto-char context-coloring-changed-end)
- (while (and (> (point-max) (point))
- (pos-visible-in-window-p))
- (forward-line 1))
- (end-of-defun)
- (point))))
- (context-coloring-elisp-colorize-region-initially start end)
- ;; Fast coloring is nice, but if the code is not well-formed
- ;; (e.g. an unclosed string literal is parsed at any time) then
- ;; there could be leftover incorrectly-colored code offscreen. So
- ;; do a clean sweep as soon as appropriate.
- (context-coloring-schedule-coloring context-coloring-default-delay)))
- (t
- (context-coloring-elisp-colorize-region-initially (point-min)
(point-max)))))))
-
-
-;;; eval-expression colorization
-
-(defun context-coloring-eval-expression-match ()
- "Determine expression start in `eval-expression'."
- (string-match "\\`Eval: " (buffer-string)))
-
-(defun context-coloring-eval-expression-colorize ()
- "Color the `eval-expression' minibuffer prompt as elisp."
- (interactive)
- (context-coloring-elisp-colorize-guard
- (lambda ()
- (context-coloring-elisp-colorize-region-initially
- (progn
- (context-coloring-eval-expression-match)
- (1+ (match-end 0)))
- (point-max)))))
-
-
;;; Dispatch
+;;;###autoload
(defvar context-coloring-dispatch-hash-table (make-hash-table :test #'eq)
- "Map dispatch strategy names to their property lists.")
-
-(defvar context-coloring-mode-hash-table (make-hash-table :test #'eq)
- "Map major mode names to dispatch property lists.")
-
-(defvar context-coloring-dispatch-predicates '()
- "Functions which may return a dispatch.")
-
-(defun context-coloring-get-current-dispatch ()
- "Return the first dispatch appropriate for the current state."
- (let ((predicates context-coloring-dispatch-predicates)
- (parent major-mode)
- dispatch)
- ;; Maybe a predicate will be satisfied and return a dispatch.
- (while (and predicates
- (not (setq dispatch (funcall (pop predicates))))))
- ;; If not, maybe a major mode (or a derivative) will define a dispatch.
- (when (not dispatch)
- (while (and parent
- (not (setq dispatch (gethash parent
context-coloring-mode-hash-table)))
- (setq parent (get parent 'derived-mode-parent)))))
- dispatch))
-
-(defun context-coloring-define-dispatch (symbol &rest properties)
- "Define a new dispatch named SYMBOL with PROPERTIES.
+ "Map dispatch strategy names to their property lists.
A \"dispatch\" is a property list describing a strategy for
coloring a buffer.
-PROPERTIES must include one of `:modes' or `:predicate', and a
-`:colorizer'.
+Its properties must include one of `:modes' or `:predicate', and
+a `:colorizer'.
`:modes' - List of major modes this dispatch is valid for.
@@ -1252,28 +311,48 @@ override `context-coloring-default-delay'.
`context-coloring-mode' is enabled.
`:teardown' - Arbitrary code to tear down this dispatch when
-`context-coloring-mode' is disabled."
- (let ((modes (plist-get properties :modes))
- (predicate (plist-get properties :predicate))
- (colorizer (plist-get properties :colorizer)))
- (when (null (or modes predicate))
- (error "No mode or predicate defined for dispatch"))
- (when (not colorizer)
- (error "No colorizer defined for dispatch"))
- (puthash symbol properties context-coloring-dispatch-hash-table)
- (dolist (mode modes)
- (puthash mode properties context-coloring-mode-hash-table))
- (when predicate
- (push (lambda ()
- (when (funcall predicate)
- properties)) context-coloring-dispatch-predicates))))
+`context-coloring-mode' is disabled.")
+
+(defun context-coloring-find-dispatch (predicate)
+ "Find the first dispatch satisfying PREDICATE."
+ (let (found)
+ (maphash
+ (lambda (_ dispatch)
+ (when (and (not found)
+ (funcall predicate dispatch))
+ (setq found dispatch)))
+ context-coloring-dispatch-hash-table)
+ found))
+
+(defun context-coloring-get-current-dispatch ()
+ "Return the first dispatch appropriate for the current state."
+ (cond
+ ;; Maybe a predicate will be satisfied.
+ ((context-coloring-find-dispatch
+ (lambda (dispatch)
+ (let ((predicate (plist-get dispatch :predicate)))
+ (and predicate (funcall predicate))))))
+ ;; If not, maybe a major mode (or a derivative) will.
+ ((context-coloring-find-dispatch
+ (lambda (dispatch)
+ (let ((modes (plist-get dispatch :modes))
+ match)
+ (while (and modes (not match))
+ (setq match (eq (pop modes) major-mode)))
+ match))))))
+
+(defun context-coloring-before-colorize ()
+ "Set up environment for colorization."
+ (context-coloring-update-maximum-face))
(defun context-coloring-dispatch ()
"Determine how to color the current buffer, and color it."
(let* ((dispatch (context-coloring-get-current-dispatch))
(colorizer (plist-get dispatch :colorizer)))
- (catch 'interrupted
- (funcall colorizer))))
+ (context-coloring-before-colorize)
+ (when colorizer
+ (catch 'interrupted
+ (funcall colorizer)))))
;;; Colorization
@@ -1281,7 +360,6 @@ override `context-coloring-default-delay'.
(defun context-coloring-colorize ()
"Color the current buffer by function context."
(interactive)
- (context-coloring-update-maximum-face)
(context-coloring-dispatch))
(defun context-coloring-colorize-with-buffer (buffer)
@@ -1292,42 +370,7 @@ override `context-coloring-default-delay'.
(context-coloring-colorize))))
-;;; Built-in dispatches
-
-(context-coloring-define-dispatch
- 'javascript
- :modes '(js2-mode)
- :colorizer #'context-coloring-js2-colorize
- :setup
- (lambda ()
- (add-hook 'js2-post-parse-callbacks #'context-coloring-colorize nil t))
- :teardown
- (lambda ()
- (remove-hook 'js2-post-parse-callbacks #'context-coloring-colorize t)))
-
-(context-coloring-define-dispatch
- 'emacs-lisp
- :modes '(emacs-lisp-mode)
- :colorizer #'context-coloring-elisp-colorize
- :delay 0.016 ;; Thanks to lazy colorization this can be 60 frames per second.
- :setup #'context-coloring-setup-idle-change-detection
- :teardown #'context-coloring-teardown-idle-change-detection)
-
-;; `eval-expression-minibuffer-setup-hook' is not available in Emacs 24.3, so
-;; the backwards-compatible recommendation is to use `minibuffer-setup-hook'
and
-;; rely on this predicate instead.
-(defun context-coloring-eval-expression-predicate ()
- "Non-nil if the minibuffer is for `eval-expression'."
- ;; Kinda better than checking `this-command', because `this-command' changes.
- (context-coloring-eval-expression-match))
-
-(context-coloring-define-dispatch
- 'eval-expression
- :predicate #'context-coloring-eval-expression-predicate
- :colorizer #'context-coloring-eval-expression-colorize
- :delay 0.016
- :setup #'context-coloring-setup-idle-change-detection
- :teardown #'context-coloring-teardown-idle-change-detection)
+;;; Minor mode
(defvar context-coloring-ignore-unavailable-predicates
(list
@@ -1345,8 +388,8 @@ permissible.")
(setq ignore-p (funcall (pop predicates))))
ignore-p))
-
-;;; Minor mode
+(defvar context-coloring-interruptable-p t
+ "When non-nil, coloring may be interrupted by user input.")
;;;###autoload
(define-minor-mode context-coloring-mode
@@ -1376,21 +419,20 @@ Feature inspired by Douglas Crockford."
nil " Context" nil
(cond
(context-coloring-mode
- ;; Font lock is incompatible with this mode; the converse is also true.
- (font-lock-mode 0)
- (jit-lock-mode nil)
- ;; ...but we do use font-lock functions here.
- (font-lock-set-defaults)
- ;; Safely change the value of this function as necessary.
- (make-local-variable 'font-lock-syntactic-face-function)
(let ((dispatch (context-coloring-get-current-dispatch)))
(cond
(dispatch
+ ;; Font lock is incompatible with this mode; the converse is also true.
+ (font-lock-mode 0)
+ ;; ...but we do use font-lock functions here.
+ (font-lock-set-defaults)
+ ;; Safely change the value of this function as necessary.
+ (make-local-variable 'font-lock-syntactic-face-function)
(let ((setup (plist-get dispatch :setup)))
(when setup
(funcall setup))
;; Colorize once initially.
- (let ((context-coloring-parse-interruptable-p nil))
+ (let ((context-coloring-interruptable-p nil))
(context-coloring-colorize))))
((not (context-coloring-ignore-unavailable-message-p))
(message "Context coloring is unavailable here")))))
@@ -1400,8 +442,7 @@ Feature inspired by Douglas Crockford."
(let ((teardown (plist-get dispatch :teardown)))
(when teardown
(funcall teardown)))))
- (font-lock-mode)
- (jit-lock-mode t))))
+ (turn-on-font-lock-if-desired))))
(provide 'context-coloring)
diff --git a/packages/context-coloring/benchmark/fixtures/.nosearch
b/packages/context-coloring/fixtures/.nosearch
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/.nosearch
rename to packages/context-coloring/fixtures/.nosearch
diff --git a/packages/context-coloring/benchmark/fixtures/.dir-locals.el
b/packages/context-coloring/fixtures/benchmark/.dir-locals.el
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/.dir-locals.el
rename to packages/context-coloring/fixtures/benchmark/.dir-locals.el
diff --git a/packages/context-coloring/benchmark/fixtures/async-0.9.0.js
b/packages/context-coloring/fixtures/benchmark/async-0.9.0.js
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/async-0.9.0.js
rename to packages/context-coloring/fixtures/benchmark/async-0.9.0.js
diff --git a/packages/context-coloring/benchmark/fixtures/faces.el
b/packages/context-coloring/fixtures/benchmark/faces.el
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/faces.el
rename to packages/context-coloring/fixtures/benchmark/faces.el
diff --git a/packages/context-coloring/benchmark/fixtures/jquery-2.1.1.js
b/packages/context-coloring/fixtures/benchmark/jquery-2.1.1.js
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/jquery-2.1.1.js
rename to packages/context-coloring/fixtures/benchmark/jquery-2.1.1.js
diff --git a/packages/context-coloring/benchmark/fixtures/lisp.el
b/packages/context-coloring/fixtures/benchmark/lisp.el
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/lisp.el
rename to packages/context-coloring/fixtures/benchmark/lisp.el
diff --git a/packages/context-coloring/benchmark/fixtures/lodash-2.4.1.js
b/packages/context-coloring/fixtures/benchmark/lodash-2.4.1.js
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/lodash-2.4.1.js
rename to packages/context-coloring/fixtures/benchmark/lodash-2.4.1.js
diff --git a/packages/context-coloring/benchmark/fixtures/mkdirp-0.5.0.js
b/packages/context-coloring/fixtures/benchmark/mkdirp-0.5.0.js
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/mkdirp-0.5.0.js
rename to packages/context-coloring/fixtures/benchmark/mkdirp-0.5.0.js
diff --git a/packages/context-coloring/benchmark/fixtures/simple.el
b/packages/context-coloring/fixtures/benchmark/simple.el
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/simple.el
rename to packages/context-coloring/fixtures/benchmark/simple.el
diff --git a/packages/context-coloring/benchmark/fixtures/subr.el
b/packages/context-coloring/fixtures/benchmark/subr.el
similarity index 100%
rename from packages/context-coloring/benchmark/fixtures/subr.el
rename to packages/context-coloring/fixtures/benchmark/subr.el
diff --git a/packages/context-coloring/test/fixtures/block-scopes.js
b/packages/context-coloring/fixtures/test/block-scopes.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/block-scopes.js
rename to packages/context-coloring/fixtures/test/block-scopes.js
diff --git a/packages/context-coloring/test/fixtures/catch.js
b/packages/context-coloring/fixtures/test/catch.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/catch.js
rename to packages/context-coloring/fixtures/test/catch.js
diff --git a/packages/context-coloring/test/fixtures/changed.el
b/packages/context-coloring/fixtures/test/changed.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/changed.el
rename to packages/context-coloring/fixtures/test/changed.el
diff --git a/packages/context-coloring/test/fixtures/comment.el
b/packages/context-coloring/fixtures/test/comment.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/comment.el
rename to packages/context-coloring/fixtures/test/comment.el
diff --git a/packages/context-coloring/test/fixtures/comments-and-strings.js
b/packages/context-coloring/fixtures/test/comments-and-strings.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/comments-and-strings.js
rename to packages/context-coloring/fixtures/test/comments-and-strings.js
diff --git a/packages/context-coloring/test/fixtures/cond.el
b/packages/context-coloring/fixtures/test/cond.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/cond.el
rename to packages/context-coloring/fixtures/test/cond.el
diff --git a/packages/context-coloring/test/fixtures/condition-case.el
b/packages/context-coloring/fixtures/test/condition-case.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/condition-case.el
rename to packages/context-coloring/fixtures/test/condition-case.el
diff --git a/packages/context-coloring/test/fixtures/defadvice.el
b/packages/context-coloring/fixtures/test/defadvice.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/defadvice.el
rename to packages/context-coloring/fixtures/test/defadvice.el
diff --git a/packages/context-coloring/test/fixtures/defun.el
b/packages/context-coloring/fixtures/test/defun.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/defun.el
rename to packages/context-coloring/fixtures/test/defun.el
diff --git a/packages/context-coloring/test/fixtures/dolist.el
b/packages/context-coloring/fixtures/test/dolist.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/dolist.el
rename to packages/context-coloring/fixtures/test/dolist.el
diff --git a/packages/context-coloring/test/fixtures/empty
b/packages/context-coloring/fixtures/test/empty
similarity index 100%
rename from packages/context-coloring/test/fixtures/empty
rename to packages/context-coloring/fixtures/test/empty
diff --git a/packages/context-coloring/test/fixtures/empty-varlist.el
b/packages/context-coloring/fixtures/test/empty-varlist.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/empty-varlist.el
rename to packages/context-coloring/fixtures/test/empty-varlist.el
diff --git a/packages/context-coloring/test/fixtures/function-scopes.js
b/packages/context-coloring/fixtures/test/function-scopes.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/function-scopes.js
rename to packages/context-coloring/fixtures/test/function-scopes.js
diff --git a/packages/context-coloring/test/fixtures/global.js
b/packages/context-coloring/fixtures/test/global.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/global.js
rename to packages/context-coloring/fixtures/test/global.js
diff --git a/packages/context-coloring/test/fixtures/ignored.el
b/packages/context-coloring/fixtures/test/ignored.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/ignored.el
rename to packages/context-coloring/fixtures/test/ignored.el
diff --git a/packages/context-coloring/test/fixtures/initial-level.js
b/packages/context-coloring/fixtures/test/initial-level.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/initial-level.js
rename to packages/context-coloring/fixtures/test/initial-level.js
diff --git a/packages/context-coloring/test/fixtures/iteration.el
b/packages/context-coloring/fixtures/test/iteration.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/iteration.el
rename to packages/context-coloring/fixtures/test/iteration.el
diff --git a/packages/context-coloring/test/fixtures/key-names.js
b/packages/context-coloring/fixtures/test/key-names.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/key-names.js
rename to packages/context-coloring/fixtures/test/key-names.js
diff --git a/packages/context-coloring/test/fixtures/key-values.js
b/packages/context-coloring/fixtures/test/key-values.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/key-values.js
rename to packages/context-coloring/fixtures/test/key-values.js
diff --git a/packages/context-coloring/test/fixtures/lambda.el
b/packages/context-coloring/fixtures/test/lambda.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/lambda.el
rename to packages/context-coloring/fixtures/test/lambda.el
diff --git a/packages/context-coloring/test/fixtures/let-star.el
b/packages/context-coloring/fixtures/test/let-star.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/let-star.el
rename to packages/context-coloring/fixtures/test/let-star.el
diff --git a/packages/context-coloring/test/fixtures/let.el
b/packages/context-coloring/fixtures/test/let.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/let.el
rename to packages/context-coloring/fixtures/test/let.el
diff --git a/packages/context-coloring/test/fixtures/macroexp-let2.el
b/packages/context-coloring/fixtures/test/macroexp-let2.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/macroexp-let2.el
rename to packages/context-coloring/fixtures/test/macroexp-let2.el
diff --git a/packages/context-coloring/test/fixtures/property-lookup.js
b/packages/context-coloring/fixtures/test/property-lookup.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/property-lookup.js
rename to packages/context-coloring/fixtures/test/property-lookup.js
diff --git a/packages/context-coloring/test/fixtures/quote.el
b/packages/context-coloring/fixtures/test/quote.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/quote.el
rename to packages/context-coloring/fixtures/test/quote.el
diff --git a/packages/context-coloring/test/fixtures/sexp.el
b/packages/context-coloring/fixtures/test/sexp.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/sexp.el
rename to packages/context-coloring/fixtures/test/sexp.el
diff --git a/packages/context-coloring/test/fixtures/splice.el
b/packages/context-coloring/fixtures/test/splice.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/splice.el
rename to packages/context-coloring/fixtures/test/splice.el
diff --git a/packages/context-coloring/test/fixtures/string.el
b/packages/context-coloring/fixtures/test/string.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/string.el
rename to packages/context-coloring/fixtures/test/string.el
diff --git a/packages/context-coloring/test/fixtures/unbalanced-parenthesis.el
b/packages/context-coloring/fixtures/test/unbalanced-parenthesis.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/unbalanced-parenthesis.el
rename to packages/context-coloring/fixtures/test/unbalanced-parenthesis.el
diff --git a/packages/context-coloring/test/fixtures/unterminated-comment.js
b/packages/context-coloring/fixtures/test/unterminated-comment.js
similarity index 100%
rename from packages/context-coloring/test/fixtures/unterminated-comment.js
rename to packages/context-coloring/fixtures/test/unterminated-comment.js
diff --git a/packages/context-coloring/test/fixtures/varlist-spacing.el
b/packages/context-coloring/fixtures/test/varlist-spacing.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/varlist-spacing.el
rename to packages/context-coloring/fixtures/test/varlist-spacing.el
diff --git a/packages/context-coloring/test/fixtures/.nosearch
b/packages/context-coloring/test/fixtures/.nosearch
deleted file mode 100644
index e69de29..0000000
- [elpa] master d745846 07/25: Make js2-mode a development dependency., (continued)
- [elpa] master d745846 07/25: Make js2-mode a development dependency., Jackson Ray Hamilton, 2016/05/30
- [elpa] master 455a743 22/25: Version 8.0.0., Jackson Ray Hamilton, 2016/05/30
- [elpa] master a164992 23/25: Don't byte compile development files., Jackson Ray Hamilton, 2016/05/30
- [elpa] master f9a2481 06/25: Autoload dispatches., Jackson Ray Hamilton, 2016/05/30
- [elpa] master 968d9f2 12/25: Make keywords in comments and strings coloring customizable., Jackson Ray Hamilton, 2016/05/30
- [elpa] master f654157 04/25: Update copyright years., Jackson Ray Hamilton, 2016/05/30
- [elpa] master 4c9a3fc 16/25: Reorganize files., Jackson Ray Hamilton, 2016/05/30
- [elpa] master 5f51ad4 03/25: Don't use derived-mode-parent dispatches., Jackson Ray Hamilton, 2016/05/30
- [elpa] master a42b53e 05/25: Separate language support into separate features., Jackson Ray Hamilton, 2016/05/30
- [elpa] master 1cb5b98 11/25: Merge branch 'plugins', Jackson Ray Hamilton, 2016/05/30
- [elpa] master 6ee4481 25/25: Merge commit '3007b2917d71a7d66eb94876536dfd80b0661d40' from context-coloring,
Jackson Ray Hamilton <=