[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot 95187cf 058/139: Connect to LSP server via TCP
From: |
João Távora |
Subject: |
[elpa] externals/eglot 95187cf 058/139: Connect to LSP server via TCP |
Date: |
Mon, 14 May 2018 09:54:53 -0400 (EDT) |
branch: externals/eglot
commit 95187cfcecbfafb090c530808e2f6932cf9d860e
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Connect to LSP server via TCP
* eglot.el (eglot--make-process): Rename from
eglot-make-local-process.
(eglot): Fix docstring and rework.
(eglot--bootstrap-fn): Remove
(eglot--contact): New process-local var.
(eglot--connect): Take CONTACT arg.
(eglot--reconnect): Rework.
---
eglot.el | 137 ++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 73 insertions(+), 64 deletions(-)
diff --git a/eglot.el b/eglot.el
index ac52b9a..c5a0c0f 100644
--- a/eglot.el
+++ b/eglot.el
@@ -133,30 +133,40 @@ A list (ID WHAT DONE-P)." t)
"Status as declared by the server.
A list (WHAT SERIOUS-P)." t)
-(eglot--define-process-var eglot--bootstrap-fn nil
- "Function for returning processes/connetions to LSP servers.
-Must be a function of one arg, a name, returning a process
-object.")
+(eglot--define-process-var eglot--contact nil
+ "Method used to contact a server.
+Either a list of strings (a shell command and arguments), or a
+list of a single string of the form <host>:<port>")
(eglot--define-process-var eglot--buffer-open-count (make-hash-table)
"Keeps track of didOpen/didClose notifs for each buffer.")
-(defun eglot-make-local-process (name command)
- "Make a local LSP process from COMMAND.
+(defun eglot--make-process (name contact)
+ "Make a process from CONTACT.
NAME is a name to give the inferior process or connection.
-Returns a process object."
+CONTACT is as `eglot--contact'. Returns a process object."
(let* ((readable-name (format "EGLOT server (%s)" name))
+ (buffer (get-buffer-create
+ (format "*%s inferior*" readable-name)))
+ (singleton (and (null (cdr contact)) (car contact)))
(proc
- (make-process
- :name readable-name
- :buffer (get-buffer-create
- (format "*%s inferior*" readable-name))
- :command command
- :connection-type 'pipe
- :filter 'eglot--process-filter
- :sentinel 'eglot--process-sentinel
- :stderr (get-buffer-create (format "*%s stderr*"
- name)))))
+ (if (and
+ singleton
+ (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))))))
+ (set-process-filter proc #'eglot--process-filter)
+ (set-process-sentinel proc #'eglot--process-sentinel)
proc))
(defmacro eglot--obj (&rest what)
@@ -180,13 +190,12 @@ Returns a process object."
retval))
(defun eglot--connect (project managed-major-mode
- short-name bootstrap-fn &optional success-fn)
- "Make a connection for PROJECT, SHORT-NAME and MANAGED-MAJOR-MODE.
-Use BOOTSTRAP-FN to make the actual process object. Call
+ short-name contact &optional success-fn)
+ "Connect for PROJECT, MANAGED-MAJOR-MODE, SHORT-NAME and CONTACT.
SUCCESS-FN with no args if all goes well."
- (let* ((proc (funcall bootstrap-fn short-name))
+ (let* ((proc (eglot--make-process short-name contact))
(buffer (process-buffer proc)))
- (setf (eglot--bootstrap-fn proc) bootstrap-fn
+ (setf (eglot--contact proc) contact
(eglot--project proc) project
(eglot--major-mode proc) managed-major-mode)
(with-current-buffer buffer
@@ -226,15 +235,17 @@ SUCCESS-FN with no args if all goes well."
"History of COMMAND arguments to `eglot'.")
(defun eglot (managed-major-mode command &optional interactive)
- ;; FIXME: Later make this function also connect to TCP servers by
- ;; overloading semantics on COMMAND.
"Start a Language Server Protocol server.
Server is started with COMMAND and manages buffers of
MANAGED-MAJOR-MODE for the current project.
COMMAND is a list of strings, an executable program and
-optionally its arguments. MANAGED-MAJOR-MODE is an Emacs major
-mode.
+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\".
+
+MANAGED-MAJOR-MODE is an Emacs major mode.
With a prefix arg, prompt for MANAGED-MAJOR-MODE and COMMAND,
else guess them from current context and `eglot-executables'.
@@ -257,47 +268,45 @@ INTERACTIVE is t if called interactively."
(cdr (assoc managed-major-mode eglot-executables))))
(list
managed-major-mode
- (if current-prefix-arg
- (split-string-and-unquote
- (read-shell-command "[eglot] Run program: "
- (combine-and-quote-strings guessed-command)
- 'eglot-command-history))
- guessed-command)
+ (let ((prompt
+ (cond (current-prefix-arg
+ "[eglot] Execute program (or connect to <host>:<port>) ")
+ ((null guessed-command)
+ (format "[eglot] Sorry, couldn't guess for `%s'!\n\
+Execute program (or connect to <host>:<port>) "
+ managed-major-mode)))))
+ (if prompt
+ (split-string-and-unquote
+ (read-shell-command prompt
+ (combine-and-quote-strings guessed-command)
+ 'eglot-command-history))
+ guessed-command))
t)))
(let* ((project (project-current))
(short-name (eglot--project-short-name project)))
- (unless project (eglot--error
- "Cannot work without a current project!"))
- (let ((current-process (eglot--current-process))
- (command
- (or command
- (eglot--error "Don't know how to start EGLOT for %s buffers"
- major-mode))))
- (cond
- ((and current-process
- (process-live-p current-process))
- (when (and
- interactive
- (y-or-n-p "[eglot] Live process found, reconnect instead? "))
- (eglot-reconnect current-process interactive)))
- (t
- (eglot--connect
- project
- managed-major-mode
- short-name
- (lambda (name)
- (eglot-make-local-process
- name
- command))
- (lambda (proc)
- (eglot--message "Connected! Process `%s' now managing `%s'\
+ (unless project (eglot--error "Cannot work without a current project!"))
+ (unless command (eglot--error "Don't know how to start EGLOT for %s
buffers"
+ major-mode))
+ (let ((current-process (eglot--current-process)))
+ (cond ((and (process-live-p current-process)
+ interactive
+ (y-or-n-p "[eglot] Live process found, reconnect instead? "))
+ (eglot-reconnect current-process interactive))
+ (t
+ (eglot--connect
+ project
+ managed-major-mode
+ short-name
+ command
+ (lambda (proc)
+ (eglot--message "Connected! Process `%s' now managing `%s'\
buffers in project %s."
- proc
- managed-major-mode
- short-name)
- (dolist (buffer (buffer-list))
- (with-current-buffer buffer
- (eglot--maybe-activate-editing-mode proc))))))))))
+ proc
+ managed-major-mode
+ short-name)
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (eglot--maybe-activate-editing-mode proc))))))))))
(defun eglot-reconnect (process &optional interactive)
"Reconnect to PROCESS.
@@ -309,7 +318,7 @@ INTERACTIVE is t if called interactively."
(eglot--project process)
(eglot--major-mode process)
(eglot--short-name process)
- (eglot--bootstrap-fn process)
+ (eglot--contact process)
(lambda (proc)
(eglot--message "Reconnected!")
(dolist (buffer (buffer-list))
- [elpa] externals/eglot 75495dc 033/139: Slightly more user friendly start, (continued)
- [elpa] externals/eglot 75495dc 033/139: Slightly more user friendly start, João Távora, 2018/05/14
- [elpa] externals/eglot fdb4de1 039/139: Simplify flymake integration, João Távora, 2018/05/14
- [elpa] externals/eglot cc183a6 043/139: Fix assorted bugs, João Távora, 2018/05/14
- [elpa] externals/eglot df5d76d 065/139: Reply to client/registerCapability (don't handle it yet), João Távora, 2018/05/14
- [elpa] externals/eglot c2862f4 063/139: Don't auto-reconnect if last attempt lasted less than 3 seconds, João Távora, 2018/05/14
- [elpa] externals/eglot f1b6485 053/139: Trim some edges and add a bunch of boring RPC methods, João Távora, 2018/05/14
- [elpa] externals/eglot 0e95167 042/139: Watch for files opened under umbrella of existing process, João Távora, 2018/05/14
- [elpa] externals/eglot 4d4b85d 061/139: eglot-editing-mode becomes eglot--managed-mode, João Távora, 2018/05/14
- [elpa] externals/eglot e7ffc31 067/139: Make reported capabilities into its own function, João Távora, 2018/05/14
- [elpa] externals/eglot 79a2a1e 069/139: Be quite explicit about our lack of capabilities right now, João Távora, 2018/05/14
- [elpa] externals/eglot 95187cf 058/139: Connect to LSP server via TCP,
João Távora <=
- [elpa] externals/eglot f76f04e 057/139: More correctly keep track of didOpen/didClose per buffer, João Távora, 2018/05/14
- [elpa] externals/eglot 46bb1c0 049/139: Reorganize file, João Távora, 2018/05/14
- [elpa] externals/eglot ff5a03d 074/139: Very basic xref support, João Távora, 2018/05/14
- [elpa] externals/eglot e9b5e54 077/139: ETOOMANYLAMBDAS, João Távora, 2018/05/14
- [elpa] externals/eglot dda11dd 095/139: Try to fix some textDocument/completion bugs, João Távora, 2018/05/14
- [elpa] externals/eglot ea918ab 066/139: Include source info in diagnostics, João Távora, 2018/05/14
- [elpa] externals/eglot a199c8e 070/139: Honour textDocumentSync, João Távora, 2018/05/14
- [elpa] externals/eglot e86f9b4 073/139: New helper eglot--sync-request, João Távora, 2018/05/14
- [elpa] externals/eglot 1add335 078/139: Workaround two suspected Emacs bugs, João Távora, 2018/05/14
- [elpa] externals/eglot 889ef20 085/139: Tweak the async request engine., João Távora, 2018/05/14