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

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

[elpa] master f7230f0 3/5: Merge branch 'versioning'


From: Jackson Ray Hamilton
Subject: [elpa] master f7230f0 3/5: Merge branch 'versioning'
Date: Mon, 23 Mar 2015 03:36:59 +0000

branch: master
commit f7230f089729a0d5b7238476b7915657ac6f179c
Merge: f062d5a dd88ce5
Author: Jackson Ray Hamilton <address@hidden>
Commit: Jackson Ray Hamilton <address@hidden>

    Merge branch 'versioning'
---
 context-coloring.el           |  205 ++++++++++++++++++++++++++++++-----------
 test/binaries/outta-date      |    5 +
 test/context-coloring-test.el |   44 ++++++++-
 3 files changed, 194 insertions(+), 60 deletions(-)

diff --git a/context-coloring.el b/context-coloring.el
index 02537c6..e09b863 100644
--- a/context-coloring.el
+++ b/context-coloring.el
@@ -62,6 +62,13 @@
   "Reference to this buffer (for timers).")
 
 
+;;; 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 tty light dark)
@@ -303,12 +310,9 @@ element."
     (delete-process context-coloring-scopifier-process)
     (setq context-coloring-scopifier-process nil)))
 
-(defun context-coloring-scopify-shell-command (command &optional callback)
-  "Invoke a scopifier via COMMAND with the current buffer's contents,
-read the scopifier's response asynchronously and apply a parsed
-list of tokens to `context-coloring-apply-tokens'.
-
-Invoke CALLBACK when complete."
+(defun context-coloring-scopify-shell-command (command callback)
+  "Invoke a scopifier via COMMAND, read its response
+asynchronously and invoke CALLBACK with its output."
 
   ;; Prior running tokenization is implicitly obsolete if this function is
   ;; called.
@@ -318,8 +322,7 @@ Invoke CALLBACK when complete."
   (setq context-coloring-scopifier-process
         (start-process-shell-command "scopifier" nil command))
 
-  (let ((output "")
-        (buffer context-coloring-buffer))
+  (let ((output ""))
 
     ;; The process may produce output in multiple chunks.  This filter
     ;; accumulates the chunks into a message.
@@ -334,19 +337,34 @@ Invoke CALLBACK when complete."
      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 callback (funcall callback)))))))
+         (funcall callback output))))))
 
-  ;; Give the process its input so it can begin.
+(defun context-coloring-send-buffer-to-scopifier ()
+  "Give the scopifier process its input so it can begin
+scopifying."
   (process-send-region
    context-coloring-scopifier-process
    (point-min) (point-max))
   (process-send-eof
    context-coloring-scopifier-process))
 
+(defun context-coloring-scopify-and-colorize (command &optional callback)
+  "Invoke a scopifier via COMMAND with the current buffer's contents,
+read the scopifier's response asynchronously and apply a parsed
+list of tokens to `context-coloring-apply-tokens'.
+
+Invoke CALLBACK when complete."
+  (let ((buffer context-coloring-buffer))
+    (context-coloring-scopify-shell-command
+     command
+     (lambda (output)
+       (let ((tokens (context-coloring-parse-array output)))
+         (with-current-buffer buffer
+           (context-coloring-apply-tokens tokens))
+         (setq context-coloring-scopifier-process nil)
+         (when callback (funcall callback))))))
+  (context-coloring-send-buffer-to-scopifier))
+
 
 ;;; Dispatch
 
@@ -395,6 +413,11 @@ buffer a returns a flat vector of start, end and level 
data.
 sent via stdin, and with a flat JSON array of start, end and
 level data returned via stdout.
 
+`:version' - Minimum required version that should be printed when
+executing `:command' with a \"--version\" flag.  The version
+should be numeric, e.g. \"2\", \"19700101\", \"1.2.3\",
+\"v1.2.3\" etc.
+
 `:setup' - Arbitrary code to set up this dispatch when
 `context-coloring-mode' is enabled.
 
@@ -419,7 +442,8 @@ level data returned via stdout.
  'javascript-node
  :modes '(js-mode js3-mode)
  :executable "scopifier"
- :command "scopifier")
+ :command "scopifier"
+ :version "v1.1.1")
 
 (context-coloring-define-dispatch
  'javascript-js2
@@ -438,27 +462,19 @@ the current buffer, then execute it.
 
 Invoke CALLBACK when complete.  It is invoked synchronously for
 elisp tracks, and asynchronously for shell command tracks."
-  (let ((dispatch (gethash major-mode context-coloring-mode-hash-table)))
-    (when (null dispatch)
-      (message "%s" "Context coloring is not available for this major mode"))
-    (let (colorizer
-          scopifier
-          command
-          executable)
-      (cond
-       ((setq colorizer (plist-get dispatch :colorizer))
-        (funcall colorizer)
-        (when callback (funcall callback)))
-       ((setq scopifier (plist-get dispatch :scopifier))
-        (context-coloring-apply-tokens (funcall scopifier))
-        (when callback (funcall callback)))
-       ((setq command (plist-get dispatch :command))
-        (setq executable (plist-get dispatch :executable))
-        (if (and executable
-                 (null (executable-find executable)))
-            (progn
-              (message "Executable \"%s\" not found" executable))
-          (context-coloring-scopify-shell-command command callback)))))))
+  (let ((dispatch (gethash major-mode context-coloring-mode-hash-table))
+        colorizer
+        scopifier
+        command)
+    (cond
+     ((setq colorizer (plist-get dispatch :colorizer))
+      (funcall colorizer)
+      (when callback (funcall callback)))
+     ((setq scopifier (plist-get dispatch :scopifier))
+      (context-coloring-apply-tokens (funcall scopifier))
+      (when callback (funcall callback)))
+     ((setq command (plist-get dispatch :command))
+      (context-coloring-scopify-and-colorize command callback)))))
 
 
 ;;; Colorization
@@ -468,9 +484,7 @@ elisp tracks, and asynchronously for shell command tracks."
 
 Invoke CALLBACK when complete; see `context-coloring-dispatch'."
   (interactive)
-  (context-coloring-dispatch
-   (lambda ()
-     (when callback (funcall callback)))))
+  (context-coloring-dispatch callback))
 
 (defvar-local context-coloring-changed nil
   "Indication that the buffer has changed recently, which implies
@@ -492,6 +506,59 @@ used.")
     (context-coloring-colorize)))
 
 
+;;; Versioning
+
+(defun context-coloring-parse-version (string)
+  "Extract segments of a version STRING into a list.  \"v1.0.0\"
+produces (1 0 0), \"19700101\" produces (19700101), etc."
+  (let (version)
+    (while (string-match "[0-9]+" string)
+      (setq version (append version
+                            (list (string-to-number (match-string 0 string)))))
+      (setq string (substring string (match-end 0))))
+    version))
+
+(defun context-coloring-check-version (expected actual)
+  "Check that version EXPECTED is less than or equal to ACTUAL."
+  (let ((expected (context-coloring-parse-version expected))
+        (actual (context-coloring-parse-version actual))
+        (continue t)
+        (acceptable t))
+    (while (and continue expected)
+      (let ((an-expected (car expected))
+            (an-actual (car actual)))
+        (cond
+         ((> an-actual an-expected)
+          (setq acceptable t)
+          (setq continue nil))
+         ((< an-actual an-expected)
+          (setq acceptable nil)
+          (setq continue nil))))
+      (setq expected (cdr expected))
+      (setq actual (cdr actual)))
+    acceptable))
+
+(defvar context-coloring-check-scopifier-version-hook nil
+  "Hooks to run after checking the scopifier version.")
+
+(defun context-coloring-check-scopifier-version (&optional callback)
+  "Asynchronously invoke CALLBACK with a predicate indicating
+whether the current scopifier version satisfies the minimum
+version number required for the current major mode."
+  (let ((dispatch (gethash major-mode context-coloring-mode-hash-table)))
+    (when dispatch
+      (let ((version (plist-get dispatch :version))
+            (command (plist-get dispatch :command)))
+        (context-coloring-scopify-shell-command
+         (context-coloring-join (list command "--version") " ")
+         (lambda (output)
+           (if (context-coloring-check-version version output)
+               (progn
+                 (when callback (funcall callback t)))
+             (when callback (funcall callback nil)))
+           (run-hooks 'context-coloring-check-scopifier-version-hook)))))))
+
+
 ;;; Themes
 
 (defvar context-coloring-theme-hash-table (make-hash-table :test 'eq)
@@ -846,6 +913,16 @@ it ain't.
 Supported modes: `js-mode', `js3-mode'"
   :group 'context-coloring)
 
+(defun context-coloring-setup-idle-change-detection ()
+  "Setup idle change detection."
+  (add-hook
+   'after-change-functions 'context-coloring-change-function nil t)
+  (setq context-coloring-colorize-idle-timer
+        (run-with-idle-timer
+         context-coloring-delay
+         t
+         'context-coloring-maybe-colorize)))
+
 ;;;###autoload
 (define-minor-mode context-coloring-mode
   "Context-based code coloring, inspired by Douglas Crockford."
@@ -878,23 +955,39 @@ Supported modes: `js-mode', `js3-mode'"
     (make-local-variable 'font-lock-syntactic-face-function)
 
     (let ((dispatch (gethash major-mode context-coloring-mode-hash-table)))
-      (when dispatch
-        (let ((command (plist-get dispatch :command))
-              (setup (plist-get dispatch :setup)))
-          (when command
-            ;; Shell commands recolor on change, idly.
-            (add-hook
-             'after-change-functions 'context-coloring-change-function nil t)
-            (setq context-coloring-colorize-idle-timer
-                  (run-with-idle-timer
-                   context-coloring-delay
-                   t
-                   'context-coloring-maybe-colorize)))
-          (when setup
-            (funcall setup)))))
-
-    ;; Colorize once initially.
-    (context-coloring-colorize)))
+      (if dispatch
+          (progn
+            (let ((command (plist-get dispatch :command))
+                  (version (plist-get dispatch :version))
+                  (executable (plist-get dispatch :executable))
+                  (setup (plist-get dispatch :setup))
+                  (colorize-initially-p t))
+              (when command
+                ;; Shell commands recolor on change, idly.
+                (cond
+                 ((and executable
+                       (null (executable-find executable)))
+                  (message "Executable \"%s\" not found" executable)
+                  (setq colorize-initially-p nil))
+                 (version
+                  (context-coloring-check-scopifier-version
+                   (lambda (sufficient-p)
+                     (if sufficient-p
+                         (progn
+                           (context-coloring-setup-idle-change-detection)
+                           (context-coloring-colorize))
+                       (message "Update to the minimum version of \"%s\" (%s)"
+                                executable version))))
+                  (setq colorize-initially-p nil))
+                 (t
+                  (context-coloring-setup-idle-change-detection))))
+              (when setup
+                (funcall setup))
+              ;; Colorize once initially.
+              (when colorize-initially-p
+                (context-coloring-colorize))))
+        (when (null dispatch)
+          (message "Context coloring is not available for this major 
mode"))))))
 
 (provide 'context-coloring)
 
diff --git a/test/binaries/outta-date b/test/binaries/outta-date
new file mode 100755
index 0000000..3ac2dd5
--- /dev/null
+++ b/test/binaries/outta-date
@@ -0,0 +1,5 @@
+#!/usr/bin/env node
+
+'use strict';
+
+console.log('v2.0.4');
diff --git a/test/context-coloring-test.el b/test/context-coloring-test.el
index 903da68..cbd2002 100644
--- a/test/context-coloring-test.el
+++ b/test/context-coloring-test.el
@@ -54,7 +54,8 @@
   (setq context-coloring-comments-and-strings t)
   (setq context-coloring-syntactic-comments nil)
   (setq context-coloring-syntactic-strings nil)
-  (setq context-coloring-js-block-scopes nil))
+  (setq context-coloring-js-block-scopes nil)
+  (setq context-coloring-check-scopifier-version-hook nil))
 
 (defmacro context-coloring-test-with-fixture (fixture &rest body)
   "With the relative FIXTURE, evaluate BODY in a temporary
@@ -136,7 +137,8 @@ in the typical format."
         (function-name (intern-soft
                         (format "context-coloring-test-js-%s" name)))
         (setup-function-name (intern-soft
-                              (format "context-coloring-test-js-%s-setup" 
name))))
+                              (format
+                               "context-coloring-test-js-%s-setup" name))))
     `(ert-deftest-async ,test-name (done)
                         (context-coloring-test-js-mode
                          ,fixture
@@ -156,7 +158,8 @@ format."
         (function-name (intern-soft
                         (format "context-coloring-test-js-%s" name)))
         (setup-function-name (intern-soft
-                              (format "context-coloring-test-js-%s-setup" 
name))))
+                              (format
+                               "context-coloring-test-js-%s-setup" name))))
     `(ert-deftest ,test-name ()
        (context-coloring-test-js2-mode
         ,fixture
@@ -287,7 +290,8 @@ is FOREGROUND, or the inverse if NEGATE is non-nil."
                                 "but it %s.")
                         level
                         (if negate "not " "") foreground
-                        (if negate "did" (format "was `%s'" 
actual-foreground)))))))
+                        (if negate
+                            "did" (format "was `%s'" actual-foreground)))))))
 
 (defun context-coloring-test-assert-not-face (&rest arguments)
   "Assert that LEVEL does not have a face with `:foreground'
@@ -307,6 +311,38 @@ FOREGROUND.  Apply ARGUMENTS to
     "Context coloring is not available for this major mode"
     "*Messages*")))
 
+(define-derived-mode
+  context-coloring-test-unsupported-version-mode
+  fundamental-mode
+  "Testing"
+  "Prevent `context-coloring-test-unsupported-version' from
+  having any unintentional side-effects on mode support.")
+
+(ert-deftest-async context-coloring-test-unsupported-version (done)
+  (context-coloring-define-dispatch
+   'outta-date
+   :modes '(context-coloring-test-unsupported-version-mode)
+   :executable "node"
+   :command "node test/binaries/outta-date"
+   :version "v2.1.3")
+  (context-coloring-test-with-fixture-async
+   "./fixtures/function-scopes.js"
+   (lambda (teardown)
+     (context-coloring-test-unsupported-version-mode)
+     (add-hook
+      'context-coloring-check-scopifier-version-hook
+      (lambda ()
+        (unwind-protect
+            (progn
+              ;; Normally the executable would be something like "outta-date"
+              ;; rather than "node".
+              (context-coloring-test-assert-message
+               "Update to the minimum version of \"node\" (v2.1.3)"
+               "*Messages*"))
+          (funcall teardown))
+        (funcall done)))
+     (context-coloring-mode))))
+
 (defvar context-coloring-test-theme-index 0
   "Unique index for unique theme names.")
 



reply via email to

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