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

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

[elpa] master b35380b 019/271: Vastly improve idle timer strategy.


From: Jackson Ray Hamilton
Subject: [elpa] master b35380b 019/271: Vastly improve idle timer strategy.
Date: Thu, 05 Feb 2015 18:29:28 +0000

branch: master
commit b35380b1fb4ecba989ff4016adbe1411fe519c37
Author: Jackson Ray Hamilton <address@hidden>
Commit: Jackson Ray Hamilton <address@hidden>

    Vastly improve idle timer strategy.
---
 context-coloring.el    |   96 +++++++++++++++++++++++++++++++----------------
 scripts/tokenizer.js   |   19 +++------
 test/fixtures/monad.js |    2 +
 3 files changed, 71 insertions(+), 46 deletions(-)

diff --git a/context-coloring.el b/context-coloring.el
index 1785ccb..feba386 100644
--- a/context-coloring.el
+++ b/context-coloring.el
@@ -1,3 +1,5 @@
+;; -*- lexical-binding: t -*-
+
 (require 'json)
 
 ;;; Faces
@@ -55,11 +57,12 @@
   "Number of faces defined for highlighting delimiter levels.
 Determines depth at which to cycle through faces again.")
 
+
 ;;; Face utility functions
 
 (defun context-coloring-level-face (depth)
-  "Return face-name for DEPTH as a string 'context-coloring-depth-DEPTH-face'.
-For example: 'context-coloring-depth-1-face'."
+  "Return face-name for DEPTH as a string 
\"context-coloring-depth-DEPTH-face\".
+For example: \"context-coloring-depth-1-face\"."
   (intern-soft
    (concat "context-coloring-depth-"
            (number-to-string
@@ -75,49 +78,69 @@ For example: 'context-coloring-depth-1-face'."
            "-face")))
 
 
-;;; The coloring
+;;; Path constants
 
 (defconst context-coloring-path
-  (file-name-directory (or load-file-name buffer-file-name)))
+  (file-name-directory (or load-file-name buffer-file-name))
+  "This file's directory.")
 
 (defconst context-coloring-tokenizer-path
-  (expand-file-name "./bin/tokenizer" context-coloring-path))
+  (expand-file-name "./bin/tokenizer" context-coloring-path)
+  "Path to the external tokenizer executable.")
+
+
+;;; Tokenization functions
 
 (defun context-coloring-apply-tokens (tokens)
+  "Processes TOKENS to apply context-based coloring to the current buffer."
   (with-silent-modifications
     (dolist (token tokens)
       (let ((start (cdr (assoc 's token)))
             (end (cdr (assoc 'e token)))
             (face (context-coloring-level-face (cdr (assoc 'l token)))))
-        (add-text-properties start end `(face ,face rear-nonsticky t))))))
-
-(defun context-coloring-tokenizer-filter (process chunk)
-  (setq context-coloring-tokenizer-output
-        (concat context-coloring-tokenizer-output chunk)))
-
-(defun context-coloring-tokenizer-sentinel (process event)
-  (when (equal "finished\n" event)
-    (let ((tokens (let ((json-array-type 'list))
-                    (json-read-from-string 
context-coloring-tokenizer-output))))
-      (setq context-coloring-tokenizer-output nil)
-      (context-coloring-apply-tokens tokens))))
-
-(defun context-coloring-tokenize ()
-  ;; Only continue if there is no concurrent tokenization going on.
-  (when (eq context-coloring-tokenizer-output nil)
-    (let ((tokenizer-process (start-process-shell-command
-                              "tokenizer"
-                              nil
-                              context-coloring-tokenizer-path)))
-      (setq context-coloring-tokenizer-output "")
-      (set-process-filter tokenizer-process 'context-coloring-tokenizer-filter)
-      (set-process-sentinel tokenizer-process 
'context-coloring-tokenizer-sentinel)
-      (process-send-region tokenizer-process (point-min) (point-max))
-      (process-send-eof tokenizer-process))))
+        (add-text-properties start end `(font-lock-face ,face rear-nonsticky 
t))))))
+
+(defun context-coloring-tokenize (function)
+  "Invokes the external tokenizer with the current buffer's
+contents, reading the tokenizer's response asynchronously and
+calling FUNCTION with the parsed list of tokens."
+  (let ((tokenizer-process (start-process-shell-command
+                            "tokenizer"
+                            nil
+                            context-coloring-tokenizer-path))
+        (output ""))
+
+    ;; The process may produce output in multiple chunks. The chunks
+    ;; collectively form a message.
+    (set-process-filter tokenizer-process
+                        (lambda (process chunk)
+                          (setq output (concat output chunk))))
+
+    ;; When the message is complete, parse it as JSON and apply the tokens.
+    (set-process-sentinel tokenizer-process
+                          (lambda (process event)
+                            (when (equal "finished\n" event)
+                              (let ((tokens (let ((json-array-type 'list))
+                                              (json-read-from-string output))))
+                                (funcall function tokens)))))
+
+    ;; Give the process its input.
+    (process-send-region tokenizer-process (point-min) (point-max))
+    (process-send-eof tokenizer-process)))
+
+
+;;; Colorization functions
 
 (defun context-coloring-colorize-buffer ()
   (interactive)
-  (context-coloring-tokenize))
+  (context-coloring-tokenize 'context-coloring-apply-tokens))
+
+(defun context-coloring-idle-timer ()
+  (when (eq context-coloring-buffer (window-buffer (selected-window)))
+    (context-coloring-colorize-buffer)))
+
+(defun context-coloring-after-change (start end length)
+  (setq context-coloring-changed t))
 
 
 ;;; Minor mode
@@ -129,9 +152,16 @@ For example: 'context-coloring-depth-1-face'."
   (if (not context-coloring-mode)
       (progn
         (cancel-timer context-coloring-colorize-buffer-timer))
-    (set (make-local-variable 'context-coloring-tokenizer-output) nil)
+
+    ;; Colorize once initially. Why this doesn't work, I cannot say.
+    ;; (context-coloring-colorize-buffer)
+
+    ;; Preserve a reference to this buffer.
+    (set (make-local-variable 'context-coloring-buffer) (current-buffer))
+
+    ;; Only recolor idly.
     (set (make-local-variable 'context-coloring-colorize-buffer-timer)
-         (run-with-idle-timer 0.25 t 'context-coloring-colorize-buffer))))
+         (run-with-idle-timer 1 t 'context-coloring-idle-timer))))
 
 ;;;###autoload
 (defun context-coloring-mode-enable ()
diff --git a/scripts/tokenizer.js b/scripts/tokenizer.js
index 5475953..5b33944 100644
--- a/scripts/tokenizer.js
+++ b/scripts/tokenizer.js
@@ -35,8 +35,7 @@ process.stdin.on('readable', function () {
 });
 
 process.stdin.on('end', function () {
-    var data, totals, out, i, tokens, length, cap, token, origin, level, total,
-        previous;
+    var data, totals, out, i, tokens, length, cap, token, origin, level, total;
 
     // Generate a syntax tree for the input.
     JSLINT(whole);
@@ -75,17 +74,11 @@ process.stdin.on('end', function () {
         }
         total = totals[token.line - 1];
 
-        previous = out[out.length - 1];
-
-        if (previous && previous.l === level) {
-            previous.e = cap(total + token.thru);
-        } else {
-            out.push({
-                l: level,
-                s: cap(total + token.from),
-                e: cap(total + token.thru)
-            });
-        }
+        out.push({
+            l: level,
+            s: cap(total + token.from),
+            e: cap(total + token.thru)
+        });
 
         i += 1;
     }
diff --git a/test/fixtures/monad.js b/test/fixtures/monad.js
index ed47fa0..7646f0d 100644
--- a/test/fixtures/monad.js
+++ b/test/fixtures/monad.js
@@ -2,7 +2,9 @@
 
     'use strict';
 
+    // This is my monad.
     function MONAD() {
+        // My monad returns things.
         return function unit(value) {
             var monad = Object.create(null);
             monad.bind = function (func) {



reply via email to

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