branch: master commit a0fefc428654b3db02d863662b7f099bde3d6416 Author: Jackson Ray Hamilton <jack...@jacksonrayhamilton.com> Commit: Jackson Ray Hamilton <jack...@jacksonrayhamilton.com>
Add themes. Prepare for ELPA. Version 3.1.0. --- .elpaignore | 13 +++ README.md | 58 +++++++++------ benchmark/context-coloring-benchmark.el | 4 +- context-coloring-themes.el | 122 +++++++++++++++++++++++++++++++ context-coloring.el | 46 ++++++++--- languages/javascript/binaries/cli.js | 21 ----- languages/javascript/binaries/scopifier | 35 +++++++++- languages/javascript/scopifier.js | 19 +++-- libraries/js2-mode.el | 9 ++- test/context-coloring-test.el | 4 +- 10 files changed, 258 insertions(+), 73 deletions(-) diff --git a/.elpaignore b/.elpaignore new file mode 100644 index 0000000..5b2e6d9 --- /dev/null +++ b/.elpaignore @@ -0,0 +1,13 @@ +.elpaignore +.gitignore +.jshintrc +.travis.yml +Makefile +README.md +benchmark +libraries/.dir-locals.el +libraries/ert-async.el +libraries/js2-mode.el +scopifier.png +screenshot.png +test diff --git a/README.md b/README.md index af1be13..c31f895 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,20 @@ code*. - Light and dark (customizable) color schemes. - Very fast for files under 1000 lines. -## Usage +## Installation Requires Emacs 24+. JavaScript language support requires either [js2-mode][] or [Node.js 0.10+][node], respectively. +### ELPA + +- `M-x package-refresh-contents RET` +- `M-x package-install RET context-coloring RET` + +### Git + - Clone this repository. ```bash @@ -65,28 +72,30 @@ make compile ## Customizing -You can adjust the colors to your liking using `context-coloring-set-colors`. - -I like to take the colors from an existing theme and use those to create a -rainbow that matches that theme. Here's an example for [`zenburn`][zenburn] (which is the -theme used in the screenshot above). +Built-in themes are accessible via `context-coloring-load-theme`. Available +themes are: `monokai`, `solarized`, `tango` and `zenburn`. ```lisp -;; ~/.emacs -(load-theme 'zenburn t) (require 'context-coloring) -(context-coloring-set-colors - "#DCDCCC" - "#93E0E3" - "#BFEBBF" - "#F0DFAF" - "#DFAF8F" - "#CC9393" - "#DC8CC3" - "#94BFF3" - "#9FC59F" - "#D0BF8F" - "#DCA3A3") +(context-coloring-load-theme 'zenburn) +``` + +You can define your own themes, too: + +```lisp +(context-coloring-define-theme + 'zenburn + :colors '("#DCDCCC" + "#93E0E3" + "#BFEBBF" + "#F0DFAF" + "#DFAF8F" + "#CC9393" + "#DC8CC3" + "#94BFF3" + "#9FC59F" + "#D0BF8F" + "#DCA3A3")) ``` ## Extending @@ -127,10 +136,11 @@ into an array like the one above. For example, a Ruby scopifier might be defined and implemented like this: ```lisp -(context-coloring-define-dispatch 'ruby - :modes '(ruby-mode) - :executable "ruby" - :command "/home/username/scopifier") +(context-coloring-define-dispatch + 'ruby + :modes '(ruby-mode) + :executable "ruby" + :command "/home/username/scopifier") ``` ```ruby diff --git a/benchmark/context-coloring-benchmark.el b/benchmark/context-coloring-benchmark.el index cc5b221..004b66f 100644 --- a/benchmark/context-coloring-benchmark.el +++ b/benchmark/context-coloring-benchmark.el @@ -1,6 +1,8 @@ ;;; benchmark/context-coloring-benchmark.el --- Benchmarks for context coloring. -*- lexical-binding: t; -*- -;; Copyright (C) 2014 Jackson Ray Hamilton +;; Copyright (C) 2014-2015 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 diff --git a/context-coloring-themes.el b/context-coloring-themes.el new file mode 100644 index 0000000..a964169 --- /dev/null +++ b/context-coloring-themes.el @@ -0,0 +1,122 @@ +;;; context-coloring-themes.el --- Color schemes for Context Coloring. -*- lexical-binding: t; -*- + +;; Copyright (C) 2014-2015 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: + +;; An assortment of color schemes for Context Coloring, many of which are based +;; on existing color themes and custom themes. + +;; To use, simply call `context-coloring-load-theme': + +;; (require 'context-coloring) +;; (context-coloring-load-theme 'zenburn) + +;;; Code: + +(defvar context-coloring-theme-hash-table (make-hash-table :test 'eq) + "Mapping of theme names to theme properties.") + +(defun context-coloring-define-theme (theme &rest properties) + "Define a theme named THEME for coloring scope levels. +PROPERTIES is a property list specifiying the following details: + +`:colors': List of colors that this theme uses." + (puthash + theme + (lambda () + (apply 'context-coloring-set-colors (plist-get properties :colors))) + context-coloring-theme-hash-table)) + +(defun context-coloring-load-theme (theme) + "Apply THEME's colors and other properties for context +coloring." + (let ((function (gethash theme context-coloring-theme-hash-table))) + (when (null function) + (error (format "No such theme `%s'" theme))) + (funcall function))) + +(context-coloring-define-theme + 'monokai + :colors '("#F8F8F2" + "#66D9EF" + "#A1EFE4" + "#A6E22E" + "#E6DB74" + "#FD971F" + "#F92672" + "#FD5FF0" + "#AE81FF")) + +(context-coloring-define-theme + 'solarized + :colors '("#839496" + "#268bd2" + "#2aa198" + "#859900" + "#b58900" + "#cb4b16" + "#dc322f" + "#d33682" + "#6c71c4" + "#69B7F0" + "#69CABF" + "#B4C342" + "#DEB542" + "#F2804F" + "#FF6E64" + "#F771AC" + "#9EA0E5")) + +(context-coloring-define-theme + 'tango + :colors '("#2e3436" + "#346604" + "#204a87" + "#5c3566" + "#a40000" + "#b35000" + "#c4a000" + "#8ae234" + "#8cc4ff" + "#ad7fa8" + "#ef2929" + "#fcaf3e" + "#fce94f")) + +(context-coloring-define-theme + 'zenburn + :colors '("#DCDCCC" + "#93E0E3" + "#BFEBBF" + "#F0DFAF" + "#DFAF8F" + "#CC9393" + "#DC8CC3" + "#94BFF3" + "#9FC59F" + "#D0BF8F" + "#DCA3A3")) + +(provide 'context-coloring-themes) + +;; Local Variables: +;; eval: (when (fboundp 'rainbow-mode) (rainbow-mode 1)) +;; End: + +;;; context-coloring-themes.el ends here diff --git a/context-coloring.el b/context-coloring.el index 40465f8..cd5a8b4 100644 --- a/context-coloring.el +++ b/context-coloring.el @@ -1,11 +1,14 @@ ;;; context-coloring.el --- Syntax highlighting, except not for syntax. -*- lexical-binding: t; -*- -;; Copyright (C) 2014 Jackson Ray Hamilton +;; Copyright (C) 2014-2015 Free Software Foundation, Inc. ;; Author: Jackson Ray Hamilton <jack...@jacksonrayhamilton.com> +;; URL: https://github.com/jacksonrayhamilton/context-coloring ;; Keywords: context coloring syntax highlighting -;; Version: 3.0.0 -;; Package-Requires: ((emacs "24") (js2-mode "20141228")) +;; Version: 3.1.0 +;; Package-Requires: ((emacs "24") (js2-mode "20150126")) + +;; 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 @@ -24,6 +27,20 @@ ;; Highlights code according to function context. +;; - Code in the global scope is one color. Code in functions within the global +;; scope is a different color, and code within such functions is another +;; color, and so on. +;; - Identifiers retain the color of the scope in which they are declared. + +;; Lexical scope information at-a-glance can assist a programmer in +;; understanding the overall structure of a program. It can help to curb nasty +;; bugs like name shadowing. A rainbow can indicate excessive complexity. State +;; change within a closure is easily monitored. + +;; By default, Context Coloring still highlights comments and strings +;; syntactically. It is still easy to differentiate code from non-code, and +;; strings cannot be confused for variables. + ;; To use, add the following to your ~/.emacs: ;; (require 'context-coloring) @@ -31,6 +48,7 @@ ;;; Code: +(require 'context-coloring-themes) (require 'js2-mode) @@ -377,16 +395,18 @@ level data returned via stdout." (when (null (gethash mode context-coloring-mode-hash-table)) (puthash mode properties context-coloring-mode-hash-table))))) -(context-coloring-define-dispatch 'javascript-node - :modes '(js-mode js3-mode) - :executable "node" - :command (expand-file-name - "./languages/javascript/binaries/scopifier" - context-coloring-path)) - -(context-coloring-define-dispatch 'javascript-js2 - :modes '(js2-mode) - :colorizer 'context-coloring-js2-colorize) +(context-coloring-define-dispatch + 'javascript-node + :modes '(js-mode js3-mode) + :executable "node" + :command (expand-file-name + "./languages/javascript/binaries/scopifier" + context-coloring-path)) + +(context-coloring-define-dispatch + 'javascript-js2 + :modes '(js2-mode) + :colorizer 'context-coloring-js2-colorize) (defun context-coloring-dispatch (&optional callback) "Determines the optimal track for scopification / colorization diff --git a/languages/javascript/binaries/cli.js b/languages/javascript/binaries/cli.js deleted file mode 100644 index 1a059bc..0000000 --- a/languages/javascript/binaries/cli.js +++ /dev/null @@ -1,21 +0,0 @@ -// Reads a JavaScript file from stdin. - -// Writes an array of tokens to stdout. - -'use strict'; - -var scopifier = require('../scopifier'), - whole = ''; - -process.stdin.setEncoding('utf8'); - -process.stdin.on('readable', function () { - var chunk = process.stdin.read(); - if (chunk !== null) { - whole += chunk; - } -}); - -process.stdin.on('end', function () { - console.log(JSON.stringify(scopifier(whole))); -}); diff --git a/languages/javascript/binaries/scopifier b/languages/javascript/binaries/scopifier index 9610016..82ea34e 100755 --- a/languages/javascript/binaries/scopifier +++ b/languages/javascript/binaries/scopifier @@ -1,3 +1,36 @@ #!/usr/bin/env node + +// Copyright (C) 2014-2015 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/>. + 'use strict'; -require('./cli.js'); \ No newline at end of file + +var scopifier = require('../scopifier'), + whole = ''; + +process.stdin.setEncoding('utf8'); + +process.stdin.on('readable', function () { + var chunk = process.stdin.read(); + if (chunk !== null) { + whole += chunk; + } +}); + +process.stdin.on('end', function () { + console.log(JSON.stringify(scopifier(whole))); +}); diff --git a/languages/javascript/scopifier.js b/languages/javascript/scopifier.js index becbcc7..fd3549a 100644 --- a/languages/javascript/scopifier.js +++ b/languages/javascript/scopifier.js @@ -1,4 +1,6 @@ -// Copyright (C) 2014 Jackson Ray Hamilton +// Copyright (C) 2014-2015 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 @@ -21,9 +23,6 @@ var escope = require('./libraries/escope'), // Given code, returns an array of tokens for context-coloring. function scopifier(code) { - // Strip BOM. - code = code.replace(/^\ufeff/g, ''); - var analyzedScopes, ast, definition, @@ -41,6 +40,9 @@ function scopifier(code) { tokens, variable; + // Strip BOM. + code = code.replace(/^\ufeff/g, ''); + // Gracefully handle parse errors by doing nothing. try { ast = esprima.parse(code, { @@ -69,7 +71,7 @@ function scopifier(code) { // Base case. scope.level = 0; } - // We've only given the scope a level for posterity's sake. We're + // We've only given the scope a level for posterity's sake. We're // done now. if (!scope.functionExpressionScope) { range = scope.block.range; @@ -97,10 +99,9 @@ function scopifier(code) { reference = scope.references[j]; range = reference.identifier.range; isDefined = false; - // Determine if a definition already exists for the - // range. (escope detects variables twice if they are - // declared and initialized simultaneously; this filters - // them.) + // Determine if a definition already exists for the range. + // (escope detects variables twice if they are declared and + // initialized simultaneously; this filters them.) for (k = 0; k < definitionsCount; k += 1) { pointer = definitionsIndex + (k * 3); if (tokens[pointer] === range[0] + 1 && diff --git a/libraries/js2-mode.el b/libraries/js2-mode.el index 5a7f650..c332cfc 100644 --- a/libraries/js2-mode.el +++ b/libraries/js2-mode.el @@ -101,7 +101,7 @@ (mapcar 'symbol-name '(Array Boolean Date Error EvalError Function Infinity JSON Math NaN Number Object RangeError ReferenceError RegExp - String SyntaxError TypeError URIError arguments + String SyntaxError TypeError URIError decodeURI decodeURIComponent encodeURI encodeURIComponent escape eval isFinite isNaN parseFloat parseInt undefined unescape)) @@ -2325,8 +2325,11 @@ Returns `js2-scope' in which NAME is defined, or nil if not found." result (continue t)) (while (and scope continue) - (if (and (setq table (js2-scope-symbol-table scope)) - (assq sym table)) + (if (or + (and (setq table (js2-scope-symbol-table scope)) + (assq sym table)) + (and (eq sym 'arguments) + (js2-function-node-p scope))) (setq continue nil result scope) (setq scope (js2-scope-parent-scope scope)))) diff --git a/test/context-coloring-test.el b/test/context-coloring-test.el index 93fea64..4c62d7a 100644 --- a/test/context-coloring-test.el +++ b/test/context-coloring-test.el @@ -1,6 +1,8 @@ ;;; test/context-coloring-test.el --- Tests for context coloring. -*- lexical-binding: t; -*- -;; Copyright (C) 2014 Jackson Ray Hamilton +;; Copyright (C) 2014-2015 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