New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow :initializationOptions with all forms of contact in eglot-server-programs #1038
Conversation
* eglot.el (eglot-server-programs): Update docstring. (eglot--connect): Extract a :initializationOptions entry in all cases, not only in the `(stringp (car contact))' case; revert the latter to its previous value. Include the :initializationOption entry in the saved-initiargs slot, so that `eglot-initialization-options' picks it up.
I'd be more comfortable with a more surgical change such as: diff --git a/eglot.el b/eglot.el
index ff94d5ca5f..3b1b1a9536 100644
--- a/eglot.el
+++ b/eglot.el
@@ -796,6 +796,8 @@ treated as in `eglot-dbind'."
:documentation
"Represents a server. Wraps a process for LSP communication.")
+(cl-defmethod initialize-instance :before ((_server eglot-lsp-server) &optional args)
+ (cl-remf args :initializationOptions))
;;; Process management
(defvar eglot--servers-by-project (make-hash-table :test #'equal) This seems to do the right thing in my simple tests. |
With this patch and setting
I get the following error
This happens because, as you know
So these horrible manipulations in the PR
seem necessary. |
Oops, the above reason for the error is wrong. It's rather something in |
By the way, my PR is longer than your suggestion because it makes |
Also see #1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions.
Yes, I see the error now, thanks for reporting it. See my new commit, which simplifies |
I hope this means my version, since it prunes down the possible forms of CONTACT in |
No, I'm sorry. It's too much code for and complicates the structure of the
It just moves a section down to the end. I actually think that complicates the docstring. Also I don't think |
Also see #1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions.
Also see #1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions.
Also see #1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions. * eglot-tests.el (eglot-server-programs-simple-missing-executable): Update test.
Also see #1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions. * eglot-tests.el (eglot-server-programs-simple-missing-executable): Update test.
Well, it's true that this is not the minimal hack necessary to make This change is slightly longer because it makes Anyway, I'll rename the PR to reflect what it does, even though I don't expect it will be merged. |
(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))))) | ||
`(: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))))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this hunk, which is the biggest code change here, is just reverting things to their state before :initializationOptions
was initially introduced.
In my opinion, it is not simpler. I went to some lengths to make that list a flat list of 6 forms and I hope never to have to extend it again. And it's not a questions of making the code "a couple of lines longer": it's about unmotivated changes. If I don't witness an actual need for making something,I won't. Here my need is to make Eglot is about 4 years old. Well-meaning ambitious contributors have come and gone. I myself drift away often: I need the codebase to be as minimal and as stable as possible. See for example all the TRAMP related bugs: I didn't implement TRAMP support and I don't use it regularly. There were some proposals for adding this to Eglot and I took some time to choose the simplest one. Even that seems to cause intermittent problems I just don't have time to debug. |
The T in Tramp is for "transparent", so Eglot shouldn't do anything at all — except for translating some magic file names to the local name in the remote machine, of course. I completely agree with your approach there. I guess I should close this after all, so thanks for your patience :-). |
…r-programs Also see joaotavora/eglot#1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions. * eglot-tests.el (eglot-server-programs-simple-missing-executable): Update test.
…r-programs Also see joaotavora/eglot#1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions. * eglot-tests.el (eglot-server-programs-simple-missing-executable): Update test.
Also see #1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions. * eglot-tests.el (eglot-server-programs-simple-missing-executable): Update test. #940: joaotavora/eglot#940 #1038: joaotavora/eglot#1038
Also see joaotavora/eglot#1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions. * eglot-tests.el (eglot-server-programs-simple-missing-executable): Update test. GitHub-reference: fix joaotavora/eglot#940
Also see joaotavora/eglot#1038. This feature was poorly tested, and simply wouldn't work when trying to initialize the server object. The simple solution is to ignore :initializationOptions initarg in this context. It is still stored separately as and accessed as the 'eglot--saved-initargs' slot. Another complication arises in eglot--guess-contact, which tried too hard to be able to compose an interactive prompt (when the server program can't be found). The solution is just to give up when :autoport or :initializationOptions is found. It's not easy or practical to have the user provide non-string arguments via a string interface like the minibuffer. * eglot.el (initialize-instance :before eglot-lsp-server): Don't pass :initializationOptions initarg onward. (eglot--guess-contact): Simplify. Don't try heroics with :autoport and :initializationOptions. * eglot-tests.el (eglot-server-programs-simple-missing-executable): Update test. GitHub-reference: fix joaotavora/eglot#940
Currently, passing
:initialiationOptions
to a server ineglot-server-programs
is not supported when the connection is over TCP or the contact is a class.This PR lifts this restriction this by making the
:initializationOptions
feature orthogonal to the details of how to launch a server program.(The initial submission of this PR phrased it differently, so note that the ensuing discussion doesn't address the description above directly.)
See als Emacs bug#57725.
Closes #940