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

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

[elpa] master e387aaf 45/79: Merge branch 'server' into elisp


From: Jackson Ray Hamilton
Subject: [elpa] master e387aaf 45/79: Merge branch 'server' into elisp
Date: Sun, 14 Jun 2015 00:05:35 +0000

branch: master
commit e387aaf3cdf32ce809227ce6380133f1a6950f3a
Merge: 59492ab 5661ed0
Author: Jackson Ray Hamilton <address@hidden>
Commit: Jackson Ray Hamilton <address@hidden>

    Merge branch 'server' into elisp
---
 context-coloring.el |  154 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 124 insertions(+), 30 deletions(-)

diff --git a/context-coloring.el b/context-coloring.el
index 0f823d8..e3470eb 100644
--- a/context-coloring.el
+++ b/context-coloring.el
@@ -748,43 +748,50 @@ to colorize the buffer."
       (with-silent-modifications
         (context-coloring-apply-tokens braceless)))))
 
+(defvar-local context-coloring-scopifier-cancel-function nil
+  "Kills the current scopification process.")
+
 (defvar-local context-coloring-scopifier-process nil
   "The single scopifier process that can be running.")
 
-(defun context-coloring-kill-scopifier ()
-  "Kill the currently-running scopifier process."
+(defun context-coloring-cancel-scopification ()
+  "Stop the currently-running scopifier from scopifying."
+  (when context-coloring-scopifier-cancel-function
+    (funcall context-coloring-scopifier-cancel-function)
+    (setq context-coloring-scopifier-cancel-function nil))
   (when (not (null context-coloring-scopifier-process))
     (delete-process context-coloring-scopifier-process)
     (setq context-coloring-scopifier-process nil)))
 
-(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.
-  (context-coloring-kill-scopifier)
-
-  ;; Start the process.
-  (setq context-coloring-scopifier-process
-        (start-process-shell-command "scopifier" nil command))
-
-  (let ((output ""))
-
+(defun context-coloring-shell-command (command callback)
+  "Invoke COMMAND, read its response asynchronously and invoke
+CALLBACK with its output.  Return the command process."
+  (let ((process (start-process-shell-command "context-coloring-process" nil 
command))
+        (output ""))
     ;; The process may produce output in multiple chunks.  This filter
     ;; accumulates the chunks into a message.
     (set-process-filter
-     context-coloring-scopifier-process
+     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
+     process
      (lambda (_process event)
        (when (equal "finished\n" event)
-         (funcall callback output))))))
+         (funcall callback output))))
+    process))
+
+(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.
+  (context-coloring-cancel-scopification)
+  ;; Start the process.
+  (setq context-coloring-scopifier-process
+        (context-coloring-shell-command command callback)))
 
 (defun context-coloring-send-buffer-to-scopifier ()
   "Give the scopifier process its input so it can begin
@@ -795,6 +802,80 @@ scopifying."
   (process-send-eof
    context-coloring-scopifier-process))
 
+(defun context-coloring-start-scopifier-server (command host port callback)
+  (let* ((connect
+          (lambda ()
+            (let ((stream (open-network-stream "context-coloring-stream" nil 
host port)))
+              (funcall callback stream)))))
+    ;; Try to connect in case a server is running, otherwise start one.
+    (condition-case nil
+        (progn
+          (funcall connect))
+      (error
+       (let ((server (start-process-shell-command
+                      "context-coloring-scopifier-server" nil
+                      (context-coloring-join
+                       (list command
+                             "--server"
+                             "--host" host
+                             "--port" (number-to-string port))
+                       " ")))
+             (output ""))
+         ;; Connect as soon as the "listening" message is printed.
+         (set-process-filter
+          server
+          (lambda (_process chunk)
+            (setq output (concat output chunk))
+            (when (string-match-p (format "^Scopifier listening at %s:%s$" 
host port) output)
+              (funcall connect)))))))))
+
+(defun context-coloring-send-buffer-to-scopifier-server (command host port 
callback)
+  (context-coloring-start-scopifier-server
+   command host port
+   (lambda (process)
+     (let* ((body (buffer-substring-no-properties (point-min) (point-max)))
+            (header (concat "POST / HTTP/1.0\r\n"
+                            "Host: localhost\r\n"
+                            "Content-Type: application/x-www-form-urlencoded"
+                            "; charset=UTF8\r\n"
+                            (format "Content-Length: %d\r\n" (length body))
+                            "\r\n"))
+            (output "")
+            (active t))
+       (set-process-filter
+        process
+        (lambda (_process chunk)
+          (setq output (concat output chunk))))
+       (set-process-sentinel
+        process
+        (lambda (_process event)
+          (when (and (equal "connection broken by remote peer\n" event)
+                     active)
+            ;; Strip the response headers.
+            (string-match "\r\n\r\n" output)
+            (setq output (substring-no-properties output (match-end 0)))
+            (funcall callback output))))
+       (process-send-string process (concat header body "\r\n"))
+       (setq context-coloring-scopifier-cancel-function
+             (lambda ()
+               "Cancel this scopification."
+               (setq active nil)))))))
+
+(defun context-coloring-scopify-and-colorize-server (command host port 
&optional callback)
+  "Contact or start a scopifier server via COMMAND at HOST and
+PORT 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 (current-buffer)))
+    (context-coloring-send-buffer-to-scopifier-server
+     command host port
+     (lambda (output)
+       (with-current-buffer buffer
+         (context-coloring-parse-array output))
+       (when callback (funcall callback))))))
+
 (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
@@ -834,11 +915,12 @@ Invoke CALLBACK when complete."
   "Define a new dispatch named SYMBOL with PROPERTIES.
 
 A \"dispatch\" is a property list describing a strategy for
-coloring a buffer.  There are two possible strategies: Parse and
-color in a single function (`:colorizer') or parse with a shell
-command that returns scope data (`:command').  In the latter
-case, the scope data will be used to automatically color the
-buffer.
+coloring a buffer.  There are three possible strategies: Parse
+and color in a single function (`:colorizer'), parse with a shell
+command that returns scope data (`:command'), or parse with a
+server that returns scope data (`:command', `:host' and `:port').
+In the latter two cases, the scope data will be used to
+automatically color the buffer.
 
 PROPERTIES must include `:modes' and one of `:colorizer',
 `:scopifier' or `:command'.
@@ -855,6 +937,10 @@ colors the buffer.
 sent via stdin, and with a flat JSON array of start, end and
 level data returned via stdout.
 
+`:host' - Hostname of the scopifier server, e.g. \"localhost\".
+
+`:port' - Port number of the scopifier server, e.g. 80, 1337.
+
 `: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\",
@@ -902,7 +988,7 @@ used.")
 (defun context-coloring-change-function (_start _end _length)
   "Register a change so that a buffer can be colorized soon."
   ;; Tokenization is obsolete if there was a change.
-  (context-coloring-kill-scopifier)
+  (context-coloring-cancel-scopification)
   (setq context-coloring-changed t))
 
 (defun context-coloring-maybe-colorize (buffer)
@@ -956,7 +1042,7 @@ version number required for the current major mode."
     (when dispatch
       (let ((version (plist-get dispatch :version))
             (command (plist-get dispatch :command)))
-        (context-coloring-scopify-shell-command
+        (context-coloring-shell-command
          (context-coloring-join (list command "--version") " ")
          (lambda (output)
            (if (context-coloring-check-version version output)
@@ -1337,7 +1423,7 @@ Supported modes: `js-mode', `js3-mode', `emacs-lisp-mode'"
 
 (defun context-coloring-teardown-idle-change-detection ()
   "Teardown idle change detection."
-  (context-coloring-kill-scopifier)
+  (context-coloring-cancel-scopification)
   (when context-coloring-colorize-idle-timer
     (cancel-timer context-coloring-colorize-idle-timer))
   (remove-hook
@@ -1353,7 +1439,9 @@ Supported modes: `js-mode', `js3-mode', `emacs-lisp-mode'"
  :modes '(js-mode js3-mode)
  :executable "scopifier"
  :command "scopifier"
- :version "v1.1.1")
+ :version "v1.1.1" ; TODO: v1.2.0
+ :host "localhost"
+ :port 6969)
 
 (context-coloring-define-dispatch
  'javascript-js2
@@ -1382,6 +1470,8 @@ elisp tracks, and asynchronously for shell command 
tracks."
   (let* ((dispatch (context-coloring-get-dispatch-for-mode major-mode))
          (colorizer (plist-get dispatch :colorizer))
          (command (plist-get dispatch :command))
+         (host (plist-get dispatch :host))
+         (port (plist-get dispatch :port))
          interrupted-p)
     (cond
      (colorizer
@@ -1394,7 +1484,11 @@ elisp tracks, and asynchronously for shell command 
tracks."
        (t
         (when callback (funcall callback)))))
      (command
-      (context-coloring-scopify-and-colorize command callback)))))
+      (cond
+       ((and host port)
+        (context-coloring-scopify-and-colorize-server command host port 
callback))
+       (t
+        (context-coloring-scopify-and-colorize command callback)))))))
 
 
 ;;; Minor mode



reply via email to

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