[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"
- [elpa] externals/eglot e5120aa 08/69: Add jrpc.el to Makefile, (continued)
- [elpa] externals/eglot e5120aa 08/69: Add jrpc.el to Makefile, João Távora, 2018/06/22
- [elpa] externals/eglot 07359a2 15/69: Allow null timeouts and set default to 3 seconds, João Távora, 2018/06/22
- [elpa] externals/eglot 67d8335 17/69: jrpc.el should know nothing of mode-line updates, João Távora, 2018/06/22
- [elpa] externals/eglot 0e1a5f0 05/69: jrpc-connect is now passed a generic dispatching function, João Távora, 2018/06/22
- [elpa] externals/eglot 078a1a6 13/69: Add full "Commentary" section to jrpc.el, João Távora, 2018/06/22
- [elpa] externals/eglot 2f1d76d 03/69: Proper server shutdown when jrpc.el is used, João Távora, 2018/06/22
- [elpa] externals/eglot a2aa1ed 19/69: Robustify timer handling for jrpc-async-request, João Távora, 2018/06/22
- [elpa] externals/eglot 7769c07 16/69: Send message, then establish continuations, João Távora, 2018/06/22
- [elpa] externals/eglot 7f2e894 11/69: Merge branch 'master' into jsonrpc-refactor (using good ol' git merge), João Távora, 2018/06/22
- [elpa] externals/eglot e5ba4f6 18/69: Automatically reply with error if dispatcher doesn't, João Távora, 2018/06/22
- [elpa] externals/eglot 33ae871 09/69: More flexible jrpc.el and improve eglot.el's doc,
João Távora <=
- [elpa] externals/eglot 3265c1d 10/69: Simpler callback protocol for JSONRPC parameters and results, João Távora, 2018/06/22
- [elpa] externals/eglot e906d25 14/69: Overhaul JSON and JSRONRPC error handling, João Távora, 2018/06/22
- [elpa] externals/eglot 7cd94b9 12/69: Improve jrpc.el's doc (and change jrpc-request's protocol a tiny bit), João Távora, 2018/06/22
- [elpa] externals/eglot 489182d 24/69: New jsonrpc-error error type, João Távora, 2018/06/22
- [elpa] externals/eglot 5cea412 20/69: Fix typos and phrasing in commentary and docstrings, João Távora, 2018/06/22
- [elpa] externals/eglot c30f0f3 23/69: Get rid of jsonrpc.el customization group and timeout, João Távora, 2018/06/22
- [elpa] externals/eglot 5e8fe4c 26/69: Add jsonrpc-tests.el, João Távora, 2018/06/22
- [elpa] externals/eglot 05ff697 29/69: Document current API breaches a bit, João Távora, 2018/06/22
- [elpa] externals/eglot 258e3b0 07/69: Merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22
- [elpa] externals/eglot 4bbf810 25/69: Don't return implementation details in jsonrpc-async-request, João Távora, 2018/06/22