emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 6934762 16/16: Merge commit '0c3a48f05d17f486a0c522f0f9ec3


From: Jackson Ray Hamilton
Subject: [elpa] master 6934762 16/16: Merge commit '0c3a48f05d17f486a0c522f0f9ec316dce24d86d' from context-coloring
Date: Sun, 18 Oct 2015 11:21:54 +0000

branch: master
commit 69347627ae1f60a116b3ef04084093df0fe89456
Merge: 9319a95 0c3a48f
Author: Jackson Hamilton <address@hidden>
Commit: Jackson Hamilton <address@hidden>

    Merge commit '0c3a48f05d17f486a0c522f0f9ec316dce24d86d' from 
context-coloring
---
 packages/context-coloring/README.md                |   27 ++---
 packages/context-coloring/context-coloring.el      |  125 ++++++++++++++++++--
 .../context-coloring/test/context-coloring-test.el |   94 ++++++++++++---
 .../context-coloring/test/fixtures/block-scopes.js |   10 ++
 packages/context-coloring/test/fixtures/global.js  |    2 +-
 .../test/fixtures/initial-level.js                 |    2 +
 .../test/fixtures/{let*.el => let-star.el}         |    0
 7 files changed, 216 insertions(+), 44 deletions(-)

diff --git a/packages/context-coloring/README.md 
b/packages/context-coloring/README.md
index ff92dd9..21f1eb5 100644
--- a/packages/context-coloring/README.md
+++ b/packages/context-coloring/README.md
@@ -16,6 +16,7 @@ By default, comments and strings are still highlighted 
syntactically.
 - Light and dark customizable color schemes.
 - JavaScript support:
   - Script, function and block scopes (and even `catch` block scopes).
+  - Node.js "file-level" scope detection.
 - Emacs Lisp support:
   - `defun`, `lambda`, `let`, `let*`, `cond`, `condition-case`, `defadvice`,
     `dolist`, `quote`, `backquote` and backquote splicing.
@@ -38,32 +39,18 @@ then add the following to your init file:
 (add-hook 'emacs-lisp-mode-hook #'context-coloring-mode)
 
 ;; eval-expression:
-(add-hook 'minibuffer-setup-hook #'context-coloring-mode)
+(add-hook 'eval-expression-minibuffer-setup-hook #'context-coloring-mode) ; 
24.4+
+(add-hook 'minibuffer-setup-hook #'context-coloring-mode)                 ; 
24.3
 ```
 
 ## Color Schemes
 
+The [Zenburn](https://github.com/bbatsov/zenburn-emacs) theme, featured in the
+screenshot above, now supports context coloring.
+
 You can define your own colors by customizing faces like
 `context-coloring-level-N-face`, where N is a number starting from 0.
 
-These are the colors used in the screenshot above:
-
-```lisp
-(custom-theme-set-faces
- 'zenburn
- '(context-coloring-level-0-face  ((t :foreground "#dcdccc")))
- '(context-coloring-level-1-face  ((t :foreground "#93e0e3")))
- '(context-coloring-level-2-face  ((t :foreground "#bfebbf")))
- '(context-coloring-level-3-face  ((t :foreground "#f0dfaf")))
- '(context-coloring-level-4-face  ((t :foreground "#dfaf8f")))
- '(context-coloring-level-5-face  ((t :foreground "#cc9393")))
- '(context-coloring-level-6-face  ((t :foreground "#dc8cc3")))
- '(context-coloring-level-7-face  ((t :foreground "#94bff3")))
- '(context-coloring-level-8-face  ((t :foreground "#9fc59f")))
- '(context-coloring-level-9-face  ((t :foreground "#d0bf8f")))
- '(context-coloring-level-10-face ((t :foreground "#dca3a3"))))
-```
-
 [See here](https://gist.github.com/jacksonrayhamilton/6b89ca3b85182c490816) for
 some color schemes for popular custom themes.
 
@@ -75,3 +62,5 @@ some color schemes for popular custom themes.
   strings using `font-lock`.
 - `context-coloring-javascript-block-scopes` (default: `nil`): If non-nil, also
   color block scopes in the scope hierarchy in JavaScript.
+- `context-coloring-javascript-detect-top-level-scope` (default: `t`): If
+  non-nil, detect when to use file-level scope.
diff --git a/packages/context-coloring/context-coloring.el 
b/packages/context-coloring/context-coloring.el
index 2b1d7af..8d6cacc 100644
--- a/packages/context-coloring/context-coloring.el
+++ b/packages/context-coloring/context-coloring.el
@@ -3,9 +3,9 @@
 ;; Copyright (C) 2014-2015  Free Software Foundation, Inc.
 
 ;; Author: Jackson Ray Hamilton <address@hidden>
-;; Version: 7.0.0
+;; Version: 7.1.0
 ;; Keywords: convenience faces tools
-;; Package-Requires: ((emacs "24.3") (js2-mode "20150126"))
+;; Package-Requires: ((emacs "24.3") (js2-mode "20150713"))
 ;; URL: https://github.com/jacksonrayhamilton/context-coloring
 
 ;; This file is part of GNU Emacs.
@@ -184,6 +184,7 @@ START, END and LENGTH are recorded for later use."
 
 Increase this if your machine is high-performing.  Decrease it if
 it ain't."
+  :type 'float
   :group 'context-coloring)
 
 (make-obsolete-variable
@@ -248,10 +249,12 @@ it ain't."
 
 (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)
@@ -285,8 +288,17 @@ MIN defaults to beginning of buffer.  MAX defaults to end."
         (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.
 
-;;; js2-mode colorization
+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
@@ -297,6 +309,8 @@ MIN defaults to beginning of buffer.  MAX defaults to end."
 
 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
@@ -304,11 +318,11 @@ this for ES6 code; disable it elsewhere."
  'context-coloring-javascript-block-scopes
  "7.0.0")
 
-(defsubst context-coloring-js2-scope-level (scope)
-  "Return the level of SCOPE."
+(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 0)
+         (let ((level initial)
                (current-scope scope)
                enclosing-scope)
            (while (and current-scope
@@ -351,7 +365,7 @@ this for ES6 code; disable it elsewhere."
       context-coloring-point-max)
      level)))
 
-(defun context-coloring-js2-colorize ()
+(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))
@@ -365,7 +379,7 @@ this for ES6 code; disable it elsewhere."
           ((js2-scope-p node)
            (context-coloring-js2-colorize-node
             node
-            (context-coloring-js2-scope-level 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
@@ -378,11 +392,104 @@ this for ES6 code; disable it elsewhere."
              (when (not (eq defining-scope enclosing-scope))
                (context-coloring-js2-colorize-node
                 node
-                (context-coloring-js2-scope-level defining-scope))))))
+                ;; 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
 
diff --git a/packages/context-coloring/test/context-coloring-test.el 
b/packages/context-coloring/test/context-coloring-test.el
index f5633b8..f643e91 100644
--- a/packages/context-coloring/test/context-coloring-test.el
+++ b/packages/context-coloring/test/context-coloring-test.el
@@ -365,21 +365,21 @@ signaled."
 
 ;;; Coloring tests
 
+(defun context-coloring-test-face-to-level (face)
+  "Convert FACE symbol to its corresponding level, or nil."
+  (when face
+    (let* ((face-string (symbol-name face))
+           (matches (string-match
+                     context-coloring-level-face-regexp
+                     face-string)))
+      (when matches
+        (string-to-number (match-string 1 face-string))))))
+
 (defun context-coloring-test-assert-position-level (position level)
   "Assert that POSITION has LEVEL."
-  (let ((face (get-text-property position 'face))
-        actual-level)
-    (when (not (and face
-                    (let* ((face-string (symbol-name face))
-                           (matches (string-match
-                                     context-coloring-level-face-regexp
-                                     face-string)))
-                      (when matches
-                        (setq actual-level (string-to-number
-                                            (substring face-string
-                                                       (match-beginning 1)
-                                                       (match-end 1))))
-                        (= level actual-level)))))
+  (let* ((face (get-text-property position 'face))
+         (actual-level (context-coloring-test-face-to-level face)))
+    (when (not (= level actual-level))
       (ert-fail (format (concat "Expected level at position %s, "
                                 "which is \"%s\", to be %s; "
                                 "but it was %s")
@@ -493,7 +493,7 @@ other non-letters are guaranteed to always be discarded."
   (lambda ()
     (context-coloring-test-assert-coloring "
 (xxxxxxxx () {
-    111 1 1 00000001xxx11
+    111 1 1 0000001xxx11
 }());")))
 
 (context-coloring-test-deftest-javascript block-scopes
@@ -503,6 +503,16 @@ other non-letters are guaranteed to always be discarded."
     11 111 2
         222 12
         222 22
+        22222 12
+    2
+}());
+
+(xxxxxxxx () {
+    'xxx xxxxxx';
+    11 111 2
+        222 12
+        222 22
+        22222 22
     2
 }());"))
   :before (lambda ()
@@ -592,6 +602,59 @@ ssssssssssss0"))
   ;; As long as `add-text-properties' doesn't signal an error, this test 
passes.
   (lambda ()))
 
+(defun context-coloring-test-assert-javascript-elevated-level ()
+  "Assert that the \"initial-level.js\" file has elevated scope."
+  (context-coloring-test-assert-coloring "
+
+111 1 1 0000001xxx11"))
+
+(defun context-coloring-test-assert-javascript-global-level ()
+  "Assert that the \"initial-level.js\" file has global scope."
+  (context-coloring-test-assert-coloring "
+
+000 0 0 0000000xxx00"))
+
+(context-coloring-test-deftest-javascript initial-level
+  (lambda ()
+    (context-coloring-test-assert-javascript-elevated-level))
+  :fixture "initial-level.js"
+  :before (lambda ()
+            (setq context-coloring-initial-level 1))
+  :after (lambda ()
+           (setq context-coloring-initial-level 0)))
+
+(defun context-coloring-test-setup-top-level-scope (string)
+  "Make STRING the first line and colorize again."
+  (goto-char (point-min))
+  (kill-whole-line 0)
+  (insert string)
+  ;; Reparsing triggers recoloring.
+  (js2-reparse))
+
+(context-coloring-test-deftest-javascript top-level-scope
+  (lambda ()
+    (let ((positive-indicators
+           (list "#!/usr/bin/env node"
+                 "/*jslint node: true */"
+                 "// jshint node: true"
+                 "/*eslint-env node */"
+                 "module.exports"
+                 "module.exports.a"
+                 "exports.a"
+                 "require('a')"))
+          (negative-indicators
+           (list "// Blah blah jshint blah."
+                 "module"
+                 "exports"
+                 "var require; require('a')")))
+      (dolist (indicator positive-indicators)
+        (context-coloring-test-setup-top-level-scope indicator)
+        (context-coloring-test-assert-javascript-elevated-level))
+      (dolist (indicator negative-indicators)
+        (context-coloring-test-setup-top-level-scope indicator)
+        (context-coloring-test-assert-javascript-global-level))))
+  :fixture "initial-level.js")
+
 (context-coloring-test-deftest-emacs-lisp defun
   (lambda ()
     (context-coloring-test-assert-coloring "
@@ -699,7 +762,8 @@ ssssssssssss0"))
          22 02
          22 222
     2222 1 1 2 2 2 000022
-  1111 1 1 1 0 0 000011")))
+  1111 1 1 1 0 0 000011"))
+  :fixture "let-star.el")
 
 (context-coloring-test-deftest-emacs-lisp cond
   (lambda ()
diff --git a/packages/context-coloring/test/fixtures/block-scopes.js 
b/packages/context-coloring/test/fixtures/block-scopes.js
index 735ca6f..86e4a13 100644
--- a/packages/context-coloring/test/fixtures/block-scopes.js
+++ b/packages/context-coloring/test/fixtures/block-scopes.js
@@ -2,5 +2,15 @@
     if (1) {
         var a;
         let b;
+        const c;
+    }
+}());
+
+(function () {
+    'use strict';
+    if (1) {
+        var a;
+        let b;
+        const c;
     }
 }());
diff --git a/packages/context-coloring/test/fixtures/global.js 
b/packages/context-coloring/test/fixtures/global.js
index a35619d..3de2147 100644
--- a/packages/context-coloring/test/fixtures/global.js
+++ b/packages/context-coloring/test/fixtures/global.js
@@ -1,3 +1,3 @@
 (function () {
-    var a = require('a');
+    var a = global('a');
 }());
diff --git a/packages/context-coloring/test/fixtures/initial-level.js 
b/packages/context-coloring/test/fixtures/initial-level.js
new file mode 100644
index 0000000..24a4b71
--- /dev/null
+++ b/packages/context-coloring/test/fixtures/initial-level.js
@@ -0,0 +1,2 @@
+
+var a = global('a');
diff --git a/packages/context-coloring/test/fixtures/let*.el 
b/packages/context-coloring/test/fixtures/let-star.el
similarity index 100%
rename from packages/context-coloring/test/fixtures/let*.el
rename to packages/context-coloring/test/fixtures/let-star.el



reply via email to

[Prev in Thread] Current Thread [Next in Thread]