[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master 9e14226 135/271: Merge branch 'feature/language-generaliza
From: |
Jackson Ray Hamilton |
Subject: |
[elpa] master 9e14226 135/271: Merge branch 'feature/language-generalization' into develop |
Date: |
Thu, 05 Feb 2015 18:30:33 +0000 |
branch: master
commit 9e142260e6bd7a4a700d3bba050e92e861a8027c
Merge: dc8e99c 6f34a6a
Author: Jackson Ray Hamilton <address@hidden>
Commit: Jackson Ray Hamilton <address@hidden>
Merge branch 'feature/language-generalization' into develop
---
README.md | 30 +++---
benchmark/scenarios.js | 2 +-
context-coloring.el | 121 +++++++++++----------
{bin => languages/javascript/bin}/cli.js | 0
{bin => languages/javascript/bin}/scopifier | 0
{lib => languages/javascript/lib}/escope.js | 0
{lib => languages/javascript/lib}/esprima.js | 0
{lib => languages/javascript/lib}/estraverse.js | 0
scopifier.js => languages/javascript/scopifier.js | 0
screenshot.png | Bin 23970 -> 21829 bytes
test/context-coloring-test.el | 18 +++-
test/specs.js | 2 +-
12 files changed, 102 insertions(+), 71 deletions(-)
diff --git a/README.md b/README.md
index 2c28844..cf1deff 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
<img alt="Screenshot of JavaScript code highlighted by context."
src="screenshot.png" title="Screenshot">
</p>
-Highlights JavaScript code according to function context.
+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,
@@ -12,19 +12,21 @@ Highlights JavaScript code according to function context.
- Identifiers retain the color of the scope in which they were declared.
- Comments are gray.
-JavaScript programmers often leverage closures to bind nearby data to
-functions. Lexical scope information at-a-glance can assist a programmer in
-understanding the overall structure of a program. It can also help curb nasty
-bugs like implicit globals and name shadowing. A rainbow can indicate excessive
+Lexical scope information at-a-glance can assist a programmer in understanding
+the overall structure of a program. It can also help curb nasty bugs like name
+shadowing or unexpected assignment. A rainbow can indicate excessive
complexity. A spot of contrast followed by an assignment expression could be a
-side-effect... or, a specially-constructed object's private state could be
-undergoing change.
+side-effect... or, the state of a closure could be undergoing change.
-This coloring scheme is probably more useful than conventional JavaScript
-*syntax* highlighting. Highlighting keywords can help one to detect spelling
-errors, and highlighting the content between quotation marks can alert one to
-unclosed string literals. But a [linter][] can also spot these errors, along
-with many others, and can be [seamlessly integrated via flycheck][integration].
+This coloring strategy is probably more useful than conventional *syntax*
+highlighting. Highlighting keywords can help one to detect spelling errors, and
+highlighting the content between quotation marks can alert one to unclosed
+string literals. But a [linter][] could also spot those errors, and if
+[integrated via flycheck][integration], an extra spot opens up in your editing
+toolbelt.
+
+Give context coloring a try; you may find that it *changes the way you write
+code*.
## Features
@@ -37,7 +39,9 @@ with many others, and can be [seamlessly integrated via
flycheck][integration].
## Usage
-Requires Emacs 24+ and [Node.js 0.10+][node].
+Requires Emacs 24+.
+
+JavaScript language support requires [Node.js 0.10+][node].
- Clone this repository.
diff --git a/benchmark/scenarios.js b/benchmark/scenarios.js
index 29e55c3..3e4fbeb 100644
--- a/benchmark/scenarios.js
+++ b/benchmark/scenarios.js
@@ -2,7 +2,7 @@
var fs = require('fs'),
path = require('path'),
- scopifier = require('../scopifier'),
+ scopifier = require('../languages/javascript/scopifier'),
jqueryPath = path.join(__dirname, 'fixtures', 'jquery-2.1.1.js'),
lodashPath = path.join(__dirname, 'fixtures', 'lodash-2.4.1.js'),
diff --git a/context-coloring.el b/context-coloring.el
index 4a022ba..b492288 100644
--- a/context-coloring.el
+++ b/context-coloring.el
@@ -1,9 +1,9 @@
-;;; context-coloring.el --- JavaScript syntax highlighting, except not for
syntax. -*- lexical-binding: t; -*-
+;;; context-coloring.el --- Syntax highlighting, except not for syntax. -*-
lexical-binding: t; -*-
;; Copyright (C) 2014 Jackson Ray Hamilton
;; Author: Jackson Ray Hamilton <address@hidden>
-;; Keywords: context coloring highlighting js javascript
+;; Keywords: context coloring syntax highlighting
;; Version: 1.0.0
;; Package-Requires: ((emacs "24"))
@@ -22,15 +22,19 @@
;;; Commentary:
-;; Highlights JavaScript code according to function context.
-;;
-;; Usage:
-;;
-;; Install Node.js 0.10+.
-;; In your ~/.emacs:
-;;
+;; Colors code by scope, rather than by syntax.
+
+;; A range of characters encompassing a scope is colored according to its
level;
+;; the global scope is white, scopes within the global scope are yellow, scopes
+;; within scopes within the global scope are green, etc. Variables defined in
a
+;; parent scope which are referenced from child scopes retain the same color as
+;; the scope in which they are defined; a variable defined in the global scope
+;; will be the same color when referenced from nested scopes.
+
+;; To use, add the following to your ~/.emacs:
+
;; (require 'context-coloring)
-;; (add-hook 'js-mode-hook 'context-coloring-mode)
+;; (add-hook 'js-mode-hook 'context-coloring-mode) ; Requires Node.js 0.10+.
;;; Code:
@@ -91,6 +95,8 @@
"Context coloring face, level 6."
:group 'context-coloring-faces)
+;;; Additional 6 faces as placeholders for potential (insane) levels of
nesting.
+
(defface context-coloring-level-7-face
'((t (:inherit context-coloring-level-1-face)))
"Context coloring face, level 7."
@@ -146,18 +152,32 @@ For example: \"context-coloring-level-1-face\"."
"-face")))
+;;; Constants
+
+(defconst context-coloring-path
+ (file-name-directory (or load-file-name buffer-file-name))
+ "This file's directory.")
+
+
;;; Customizable variables
+(let ((javascript-scopifier `(:type shell-command
+ :executable "node"
+ :command ,(expand-file-name
+ "./languages/javascript/bin/scopifier"
+ context-coloring-path))))
+ (defcustom context-coloring-scopifier-plist
+ `(js-mode ,javascript-scopifier
+ js2-mode ,javascript-scopifier
+ js3-mode ,javascript-scopifier)
+ "Property list mapping major modes to scopification programs."))
+
(defcustom context-coloring-delay 0.25
"Delay between a buffer update and colorization.
Increase this if your machine is high-performing. Decrease it if it ain't."
:group 'context-coloring)
-(defcustom context-coloring-benchmark-colorization nil
- "If non-nil, display how long each colorization took."
- :group 'context-coloring)
-
;;; Local variables
@@ -175,20 +195,9 @@ is a reference to that one process.")
"Indication that the buffer has changed recently, which would
imply that it should be colorized again.")
-(defvar-local context-coloring-start-time nil
- "Used to benchmark colorization time.")
-
;;; Scopification
-(defconst context-coloring-path
- (file-name-directory (or load-file-name buffer-file-name))
- "This file's directory.")
-
-(defconst context-coloring-scopifier-path
- (expand-file-name "./bin/scopifier" context-coloring-path)
- "Path to the external scopifier executable.")
-
(defun context-coloring-apply-tokens (tokens)
"Processes TOKENS to apply context-based coloring to the
current buffer. Tokens are 3 integers: start, end, level. The
@@ -217,11 +226,10 @@ buffer."
"Specialized JSON parser for a flat array of numbers."
(vconcat (mapcar 'string-to-number (split-string (substring input 1 -1)
","))))
-(defun context-coloring-scopify ()
- "Invokes the external scopifier with the current buffer's
-contents, reading the scopifier's response asynchronously and
-applying a parsed list of tokens to
-`context-coloring-apply-tokens'."
+(defun context-coloring-scopify-shell-command (command)
+ "Invokes a scopifier with the current buffer's contents,
+reading the scopifier's response asynchronously and applying a
+parsed list of tokens to `context-coloring-apply-tokens'."
;; Prior running tokenization is implicitly obsolete if this function is
;; called.
@@ -229,45 +237,52 @@ applying a parsed list of tokens to
;; Start the process.
(setq context-coloring-scopifier-process
- (start-process-shell-command "scopifier" nil
context-coloring-scopifier-path))
+ (start-process-shell-command "scopifier" nil command))
(let ((output "")
- (buffer context-coloring-buffer)
- (start-time context-coloring-start-time))
+ (buffer context-coloring-buffer))
;; The process may produce output in multiple chunks. This filter
;; accumulates the chunks into a message.
- (set-process-filter context-coloring-scopifier-process
- (lambda (process chunk)
- (setq output (concat output chunk))))
+ (set-process-filter
+ context-coloring-scopifier-process
+ (lambda (process chunk)
+ (setq output (concat output chunk))))
;; When the process's message is complete, this sentinel parses it as JSON
;; and applies the tokens to the buffer.
- (set-process-sentinel context-coloring-scopifier-process
- (lambda (process event)
- (when (equal "finished\n" event)
- (let ((tokens (context-coloring-parse-array
output)))
- (with-current-buffer buffer
- (context-coloring-apply-tokens tokens))
- (setq context-coloring-scopifier-process nil)
- (when context-coloring-benchmark-colorization
- (message "Colorized (after %f seconds)." (-
(float-time) start-time))))))))
+ (set-process-sentinel
+ context-coloring-scopifier-process
+ (lambda (process event)
+ (when (equal "finished\n" event)
+ (let ((tokens (context-coloring-parse-array output)))
+ (with-current-buffer buffer
+ (context-coloring-apply-tokens tokens))
+ (setq context-coloring-scopifier-process nil))))))
;; Give the process its input so it can begin.
(process-send-region context-coloring-scopifier-process (point-min)
(point-max))
(process-send-eof context-coloring-scopifier-process))
+(defun context-coloring-scopify ()
+ "Determines the optimal track for scopification of the current
+buffer, then scopifies the current buffer."
+ (let ((scopifier (plist-get context-coloring-scopifier-plist major-mode)))
+ (cond ((null scopifier)
+ (message "%s" "Context coloring is not available for this major
mode"))
+ ((eq (plist-get scopifier :type) 'shell-command)
+ (let ((executable (plist-get scopifier :executable)))
+ (if (null (executable-find executable))
+ (message "Context coloring executable \"%s\" not found"
executable)
+ (context-coloring-scopify-shell-command (plist-get scopifier
:command))))))))
+
;;; Colorization
(defun context-coloring-colorize ()
"Colors the current buffer by function context."
(interactive)
- (when (executable-find "node")
- (when context-coloring-benchmark-colorization
- (setq context-coloring-start-time (float-time))
- (message "%s" "Colorizing..."))
- (context-coloring-scopify)))
+ (context-coloring-scopify))
(defun context-coloring-change-function (start end length)
"Registers a change so that a context-colored buffer can be
@@ -291,7 +306,7 @@ colorizing would be redundant."
;;;###autoload
(define-minor-mode context-coloring-mode
- "Context-based code coloring for JavaScript, inspired by Douglas Crockford."
+ "Context-based code coloring, inspired by Douglas Crockford."
nil " Context" nil
(if (not context-coloring-mode)
(progn
@@ -305,10 +320,6 @@ colorizing would be redundant."
;; Remember this buffer. This value should not be dynamically-bound.
(setq context-coloring-buffer (current-buffer))
- ;; Alert the user that the mode is not going to work.
- (if (null (executable-find "node"))
- (message "context-coloring-mode requires Node.js 0.10+ to be
installed"))
-
;; Colorize once initially.
(context-coloring-colorize)
diff --git a/bin/cli.js b/languages/javascript/bin/cli.js
similarity index 100%
rename from bin/cli.js
rename to languages/javascript/bin/cli.js
diff --git a/bin/scopifier b/languages/javascript/bin/scopifier
similarity index 100%
rename from bin/scopifier
rename to languages/javascript/bin/scopifier
diff --git a/lib/escope.js b/languages/javascript/lib/escope.js
similarity index 100%
rename from lib/escope.js
rename to languages/javascript/lib/escope.js
diff --git a/lib/esprima.js b/languages/javascript/lib/esprima.js
similarity index 100%
rename from lib/esprima.js
rename to languages/javascript/lib/esprima.js
diff --git a/lib/estraverse.js b/languages/javascript/lib/estraverse.js
similarity index 100%
rename from lib/estraverse.js
rename to languages/javascript/lib/estraverse.js
diff --git a/scopifier.js b/languages/javascript/scopifier.js
similarity index 100%
rename from scopifier.js
rename to languages/javascript/scopifier.js
diff --git a/screenshot.png b/screenshot.png
index 14b94b6..fe45d9b 100644
Binary files a/screenshot.png and b/screenshot.png differ
diff --git a/test/context-coloring-test.el b/test/context-coloring-test.el
index d997d8b..0cc128c 100644
--- a/test/context-coloring-test.el
+++ b/test/context-coloring-test.el
@@ -17,7 +17,6 @@
FIXTURE."
`(with-temp-buffer
(insert (context-coloring-test-read-file ,fixture))
- (context-coloring-mode)
,@body))
(defun context-coloring-test-region-level-p (start end level)
@@ -31,10 +30,27 @@ FIXTURE."
"-face")))))
(setq i (+ i 1)))))
+(defun context-coloring-test-message-should-be (expected)
+ (with-current-buffer "*Messages*"
+ (let ((messages (split-string (buffer-substring-no-properties (point-min)
(point-max)) "\n")))
+ (let ((message (car (nthcdr (- (length messages) 2) messages))))
+ (should (equal message expected))))))
+
+(ert-deftest context-coloring-test-unsupported-mode ()
+ (context-coloring-test-with-fixture
+ "./fixtures/function-scopes.js"
+
+ (context-coloring-mode)
+ (context-coloring-test-message-should-be
+ "Context coloring is not available for this major mode")))
+
(ert-deftest context-coloring-test-function-scopes ()
(context-coloring-test-with-fixture
"./fixtures/function-scopes.js"
+ (js-mode)
+ (context-coloring-mode)
+
(sleep-for .25) ; Wait for asynchronous coloring to complete.
(context-coloring-test-region-level-p 1 9 0)
diff --git a/test/specs.js b/test/specs.js
index 8eaa15c..d0ad425 100644
--- a/test/specs.js
+++ b/test/specs.js
@@ -5,7 +5,7 @@
var assert = require('assert');
var fs = require('fs');
var path = require('path');
-var scopifier = require('../scopifier');
+var scopifier = require('../languages/javascript/scopifier');
var createEmacsBuffer = require('./createEmacsBuffer');
var threes = require('./threes');
- [elpa] master b4c220a 159/271: Always remove hooks., (continued)
- [elpa] master b4c220a 159/271: Always remove hooks., Jackson Ray Hamilton, 2015/02/05
- [elpa] master e040ca0 181/271: Just use stable emacs., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 9e7ee77 155/271: Add catch test. Don't uncolorize., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 665a54a 167/271: Add more js-mode tests., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 43f2e3b 168/271: Increase reliability of async tests., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 28183e4 188/271: Readme., Jackson Ray Hamilton, 2015/02/05
- [elpa] master bdfdbe4 151/271: Improve benchmarks., Jackson Ray Hamilton, 2015/02/05
- [elpa] master d27f2fe 182/271: Fix callback removal., Jackson Ray Hamilton, 2015/02/05
- [elpa] master cb0644a 136/271: Cleanup JavaScript tests., Jackson Ray Hamilton, 2015/02/05
- [elpa] master c1e9226 171/271: Reorganize lib., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 9e14226 135/271: Merge branch 'feature/language-generalization' into develop,
Jackson Ray Hamilton <=
- [elpa] master 7473cc9 169/271: Improve documentation and error handling for async tests., Jackson Ray Hamilton, 2015/02/05
- [elpa] master b468d1c 166/271: Improve block scope test. Rename and document block scope variable., Jackson Ray Hamilton, 2015/02/05
- [elpa] master d411168 175/271: Revert to single var., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 4c5f3ab 145/271: Fix first-run bug, passing js2-mode test., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 15bfad7 165/271: Renames., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 4d73262 152/271: Speed up local name lookup., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 4fee39d 174/271: Remove .jslintrc files., Jackson Ray Hamilton, 2015/02/05
- [elpa] master 903d938 176/271: Update readme., Jackson Ray Hamilton, 2015/02/05
- [elpa] master d48e8cc 057/271: Add benchmark., Jackson Ray Hamilton, 2015/02/05
- [elpa] master d157167 258/271: Strip headers. Use make dependencies., Jackson Ray Hamilton, 2015/02/05