From 904556f662fa188c97f3b56d3555c58a3dc84afe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Mon, 28 Mar 2022 11:00:44 +0100 Subject: [PATCH] Easier initializationoptions in eglot-server-programs Per https://github.com/joaotavora/eglot/issues/845. * NEWS.md: Update. * eglot.el (eglot-server-programs): Document new syntax. (eglot-initialization-options): Can use initializationOptions from server's saved initargs. (eglot--connect): Allow a plist to be appended to a server contact. GitHub-reference: close https://github.com/joaotavora/eglot/issues/901 --- lisp/progmodes/eglot.el | 51 ++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index d71e5966a83..ade8a7c7118 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -218,17 +218,24 @@ CONTACT can be: PROGRAM is called with ARGS and is expected to serve LSP requests over the standard input/output channels. +* A list (PROGRAM [ARGS...] :initializationOptions OPTIONS), + whereupon PROGRAM is called with ARGS as in the first option, + and the LSP \"initializationOptions\" JSON object is + constructed from OPTIONS. If OPTIONS is a unary function, it + is called with the server instance and should return a JSON + object. + * A list (HOST PORT [TCP-ARGS...]) where HOST is a string and PORT is a positive integer for connecting to a server via TCP. Remaining ARGS are passed to `open-network-stream' for upgrading the connection with encryption or other capabilities. * A list (PROGRAM [ARGS...] :autoport [MOREARGS...]), whereupon a - combination of the two previous options is used. First, an - attempt is made to find an available server port, then PROGRAM - is launched with ARGS; the `:autoport' keyword substituted for - that number; and MOREARGS. Eglot then attempts to establish a - TCP connection to that port number on the localhost. + combination of previous options is used. First, an attempt is + made to find an available server port, then PROGRAM is launched + with ARGS; the `:autoport' keyword substituted for that number; + and MOREARGS. Eglot then attempts to establish a TCP + connection to that port number on the localhost. * A cons (CLASS-NAME . INITARGS) where CLASS-NAME is a symbol designating a subclass of `eglot-lsp-server', for representing @@ -627,7 +634,11 @@ treated as in `eglot-dbind'." (cl-defgeneric eglot-initialization-options (server) "JSON object to send under `initializationOptions'." - (:method (_s) eglot--{})) ; blank default + (:method (s) + (let ((probe (plist-get (eglot--saved-initargs s) :initializationOptions))) + (cond ((functionp probe) (funcall probe s)) + (probe) + (t eglot--{}))))) (cl-defgeneric eglot-register-capability (server method id &rest params) "Ask SERVER to register capability METHOD marked with ID." @@ -1116,18 +1127,22 @@ This docstring appeases checkdoc, that's all." (setq autostart-inferior-process inferior) connection)))) ((stringp (car contact)) - `(:process - ,(lambda () - (let ((default-directory default-directory)) - (make-process - :name readable-name - :command (setq server-info (eglot--cmd contact)) - :connection-type 'pipe - :coding 'utf-8-emacs-unix - :noquery t - :stderr (get-buffer-create - (format "*%s stderr*" readable-name)) - :file-handler t))))))) + (let* ((probe (cl-position-if #'keywordp contact)) + (more-initargs (and probe (cl-subseq contact probe))) + (contact (cl-subseq contact 0 probe))) + `(:process + ,(lambda () + (let ((default-directory default-directory)) + (make-process + :name readable-name + :command (setq server-info (eglot--cmd contact)) + :connection-type 'pipe + :coding 'utf-8-emacs-unix + :noquery t + :stderr (get-buffer-create + (format "*%s stderr*" readable-name)) + :file-handler t))) + ,@more-initargs))))) (spread (lambda (fn) (lambda (server method params) (let ((eglot--cached-server server)) (apply fn server method (append params nil)))))) -- 2.39.5