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

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

[elpa] externals/eglot 33ae871 09/69: More flexible jrpc.el and improve


From: João Távora
Subject: [elpa] externals/eglot 33ae871 09/69: More flexible jrpc.el and improve eglot.el's doc
Date: Fri, 22 Jun 2018 11:54:54 -0400 (EDT)

branch: externals/eglot
commit 33ae871b957fe9727ee3230c64ccec693cdb52fd
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>

    More flexible jrpc.el and improve eglot.el's doc
    
    Generalize and rework CONTACT arg to jrpc-connect
    
    * eglot.el (eglot--command-history): Tweak docstring.
    (eglot--interactive): Rework.
    (eglot): Rework docstring. COMMAND is now CONTACT.
    (eglot--connect): Use new jrpc-connect protocol.
    (eglot-server-programs): Reword doc.
    
    * jrpc.el (jrpc--make-process): Use new form of CONTACT.
    (jrpc-connect): Explain new semantics of CONTACT.
---
 eglot.el | 66 +++++++++++++++++++++++++++++++++++++---------------------------
 jrpc.el  | 53 ++++++++++++++++++++++++++-------------------------
 2 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/eglot.el b/eglot.el
index 13c1b49..4f2e25b 100644
--- a/eglot.el
+++ b/eglot.el
@@ -75,7 +75,9 @@
                                 (sh-mode . ("bash-language-server" "start"))
                                 (php-mode . ("php" "vendor/felixfbecker/\
 language-server/bin/php-language-server.php")))
-  "Alist mapping major modes to server executables.")
+  "Alist of (MAJOR-MODE . CONTACT) mapping major modes to server executables.
+CONTACT can be anything accepted by that parameter in the
+function `eglot', which see.")
 
 (defface eglot-mode-line
   '((t (:inherit font-lock-constant-face :weight bold)))
@@ -198,7 +200,7 @@ called interactively."
    :experimental (jrpc-obj)))
 
 (defvar eglot--command-history nil
-  "History of COMMAND arguments to `eglot'.")
+  "History of CONTACT arguments to `eglot'.")
 
 (defun eglot--interactive ()
   "Helper for `eglot'."
@@ -213,6 +215,7 @@ called interactively."
               (mapcar #'symbol-name (eglot--all-major-modes)) nil t
               (symbol-name guessed-mode) nil (symbol-name guessed-mode) nil)))
            (t guessed-mode)))
+         (project (or (project-current) `(transient . ,default-directory)))
          (guessed-command (cdr (assoc managed-mode eglot-server-programs)))
          (base-prompt "[eglot] Enter program to execute (or <host>:<port>): ")
          (prompt
@@ -222,26 +225,30 @@ called interactively."
                                  managed-mode)
                          "\n" base-prompt))
                 ((and (listp guessed-command)
+                      (not (integerp (cadr guessed-command)))
                       (not (executable-find (car guessed-command))))
                  (concat (format "[eglot] I guess you want to run `%s'"
                                  (combine-and-quote-strings guessed-command))
                          (format ", but I can't find `%s' in PATH!"
                                  (car guessed-command))
-                         "\n" base-prompt)))))
-    (list
-     managed-mode
-     (or (project-current) `(transient . ,default-directory))
-     (if prompt
-         (split-string-and-unquote
-          (read-shell-command prompt
-                              (if (listp guessed-command)
-                                  (combine-and-quote-strings guessed-command))
-                              'eglot-command-history))
-       guessed-command)
-     t)))
+                         "\n" base-prompt))))
+         (contact
+          (cond ((not prompt) guessed-command)
+                (t
+                 (let ((string (read-shell-command
+                                prompt
+                                (if (listp guessed-command)
+                                    (combine-and-quote-strings 
guessed-command))
+                                'eglot-command-history)))
+                   (if (and string (string-match
+                                    "^\\([^\s\t]+\\):\\([[:digit:]]+\\)$"
+                                    (string-trim string)))
+                       (list (match-string 1 string) (match-string 2 string))
+                     (split-string-and-unquote string)))))))
+    (list managed-mode project contact t)))
 
 ;;;###autoload
-(defun eglot (managed-major-mode project command &optional interactive)
+(defun eglot (managed-major-mode project contact &optional interactive)
   "Manage a project with a Language Server Protocol (LSP) server.
 
 The LSP server is started (or contacted) via COMMAND.  If this
@@ -253,7 +260,7 @@ code-analysis via `xref-find-definitions', `flymake-mode',
 `eldoc-mode', `completion-at-point', among others.
 
 Interactively, the command attempts to guess MANAGED-MAJOR-MODE
-from current buffer, COMMAND from `eglot-server-programs' and
+from current buffer, CONTACT from `eglot-server-programs' and
 PROJECT from `project-current'.  If it can't guess, the user is
 prompted.  With a single \\[universal-argument] prefix arg, it
 always prompt for COMMAND.  With two \\[universal-argument]
@@ -261,11 +268,14 @@ prefix args, also prompts for MANAGED-MAJOR-MODE.
 
 PROJECT is a project instance as returned by `project-current'.
 
-COMMAND is a list of strings, an executable program and
-optionally its arguments.  If the first and only string in the
-list is of the form \"<host>:<port>\" it is taken as an
-indication to connect to a server instead of starting one.  This
-is also know as the server's \"contact\".
+CONTACT is a list of strings (COMMAND [ARGS...]) specifying how
+to start a server subprocess to connect to.  If the second
+element in the list is an integer number instead of a string, the
+list is interpreted as (HOST PORT [PARAMETERS...]) to connect to
+an existing server via TCP, the remaining PARAMETERS being given
+as `open-network-stream's optional arguments.  CONTACT can also
+be a function of no arguments returning a live connected process
+object.
 
 MANAGED-MAJOR-MODE is an Emacs major mode.
 
@@ -282,7 +292,7 @@ INTERACTIVE is t if called interactively."
         (let ((proc (eglot--connect project
                                     managed-major-mode
                                     (format "%s/%s" short-name 
managed-major-mode)
-                                    command)))
+                                    contact)))
           (eglot--message "Connected! Process `%s' now \
 managing `%s' buffers in project `%s'."
                           proc managed-major-mode short-name)
@@ -310,13 +320,13 @@ Builds a function from METHOD, passes it PROC, ID and 
PARAMS."
   (let* ((handler-sym (intern (concat "eglot--server-" method))))
     (if (functionp handler-sym)
         (apply handler-sym proc (append params (if id `(:id ,id))))
-      (jrpc-reply
-                  proc id
+      (jrpc-reply proc id
                   :error (jrpc-obj :code -32601 :message "Unimplemented")))))
 
-(defun eglot--connect (project managed-major-mode name command)
-  (let ((proc (jrpc-connect name command #'eglot--dispatch 
#'eglot--on-shutdown))
-        success)
+(defun eglot--connect (project managed-major-mode name contact)
+  (let* ((contact (if (functionp contact) (funcall contact) contact))
+         (proc (jrpc-connect name contact #'eglot--dispatch 
#'eglot--on-shutdown))
+         success)
     (setf (eglot--project proc) project)
     (setf (eglot--major-mode proc)managed-major-mode)
     (push proc (gethash project eglot--processes-by-project))
@@ -350,7 +360,7 @@ Builds a function from METHOD, passes it PROC, ID and 
PARAMS."
                                           (null eglot-autoreconnect)))))))
           (setq success proc))
       (unless (or success (not (process-live-p proc)) (eglot--moribund proc))
-            (eglot-shutdown proc)))))
+        (eglot-shutdown proc)))))
 
 (defun eglot--server-ready-p (_what _proc)
   "Tell if server of PROC ready for processing deferred WHAT."
diff --git a/jrpc.el b/jrpc.el
index 6773e12..3467b89 100644
--- a/jrpc.el
+++ b/jrpc.el
@@ -128,26 +128,23 @@ A function passed the process object for the server.")
 (defun jrpc--make-process (name contact)
   "Make a process from CONTACT.
 NAME is a name to give the inferior process or connection.
-CONTACT is as `jrpc-contact'.  Returns a process object."
+CONTACT is as explained in `jrpc-connect'.  Returns a process
+object."
   (let* ((readable-name (format "JSON-RPC server (%s)" name)                   
                                         )
-         (buffer (get-buffer-create
-                  (format "*%s inferior*" readable-name)))
-         singleton
+         (buffer (get-buffer-create (format "*%s inferior*" readable-name)))
          (proc
-          (if (and (setq singleton (and (null (cdr contact)) (car contact)))
-                   (string-match "^[\s\t]*\\(.*\\):\\([[:digit:]]+\\)[\s\t]*$"
-                                 singleton))
-              (open-network-stream readable-name
-                                   buffer
-                                   (match-string 1 singleton)
-                                   (string-to-number
-                                    (match-string 2 singleton)))
-            (make-process :name readable-name
-                          :buffer buffer
-                          :command contact
-                          :connection-type 'pipe
-                          :stderr (get-buffer-create (format "*%s stderr*"
-                                                             name))))))
+          (cond ((processp contact) contact)
+                ((integerp (cadr contact))
+                 (apply #'open-network-stream
+                        readable-name buffer contact))
+                (t
+                 (make-process :name readable-name
+                               :command contact
+                               :connection-type 'pipe
+                               :stderr (get-buffer-create (format "*%s stderr*"
+                                                                  name)))))))
+    (set-process-buffer proc buffer)
+    (set-marker (process-mark proc) (with-current-buffer buffer (point-min)))
     (set-process-filter proc #'jrpc--process-filter)
     (set-process-sentinel proc #'jrpc--process-sentinel)
     proc))
@@ -164,9 +161,13 @@ CONTACT is as `jrpc-contact'.  Returns a process object."
 
 NAME is a string naming the server.
 
-CONTACT is either a list of strings (a shell command and
-arguments), or a list of a single string of the form
-<host>:<port>.
+CONTACT is a list of strings (COMMAND ARGS...) specifying how to
+start a server subprocess to connect to.  If the second element
+in the list is an integer number instead of a string, the list is
+interpreted as (HOST PORT PARAMETERS...) to connect to an
+existing server via TCP, with the remaining PARAMETERS are given
+to `open-network-stream's optional arguments.  CONTACT can also
+be a live connected process object.
 
 ON-SHUTDOWN, when non-nil, is a function called on server exit
 and passed the moribund process object.
@@ -453,13 +454,13 @@ timeout keeps counting."
     (puthash id
              (list (or success-fn
                        (jrpc-lambda (&rest _ignored)
-                                    (jrpc-log-event
-                                     proc (jrpc-obj :message "success ignored" 
:id id))))
+                         (jrpc-log-event
+                          proc (jrpc-obj :message "success ignored" :id id))))
                    (or error-fn
                        (jrpc-lambda (&key code message &allow-other-keys)
-                                    (setf (jrpc-status proc) `(,message t))
-                                    proc (jrpc-obj :message "error ignored, 
status set"
-                                                   :id id :error code)))
+                         (setf (jrpc-status proc) `(,message t))
+                         proc (jrpc-obj :message "error ignored, status set"
+                                        :id id :error code)))
                    (funcall make-timeout))
              (jrpc--request-continuations proc))
     (jrpc--process-send proc (jrpc-obj :jsonrpc "2.0"



reply via email to

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