Felicián Németh [Sun, 20 Mar 2022 08:50:15 +0000 (09:50 +0100)]
Add simple support for workspacefolders
Close https://github.com/joaotavora/eglot/issues/893.
Clients can support workspaceFolders since LSP 3.6. rootUri and
rootPath are deprecated. Dynamic changes in folders are not
supported, i.e., this patch does not implement
workspace/didChangeWorkspaceFolders.
* eglot.el (eglot-client-capabilities): Add capability
`workspaceFolders'.
(eglot-workspace-folders): New cl-defgeneric.
(eglot--connect): Add workspaceFolders to initializeParams.
(eglot-handle-request workspace/workspaceFolders): New cl-defmethod.
1 // args_out_of_range.c
2 struct Book {
3 int id;
4 char title[50]
5 } book = { 1024, "C" };
6
7 int main(int argc, char *argv[])
8 {
9
10 // Error when typing the dot to make "book."
11 book
12 return 0;
13 }
When one types the dot after the "book" on line 11, company-mode
displays a two-line overlay that visually encompasses line 12 after
"book", which has the "return 0;" statement. That line happens to
also hold a warning about incorrect syntax, one that starts at column
2.
Eglot uses 'move-to-column' to go that precise place.
In Emacs 27.2, move-to-column is unaffected by previous company-mode
overlays, even if the current line is being co-used visually by the
overlay. It moves to the right buffer position.
In Emacs master, this isn't true. It seems to be confounded by the
company-mode overlay and moves to eob, which eventually breaks Eglot
with a backtrace such as this one:
Augusto Stoffel [Thu, 10 Mar 2022 11:32:20 +0000 (12:32 +0100)]
Don't strip invisible text when formatting hover string
This was introduced in https://github.com/joaotavora/eglot/issues/482 due to a bad interaction with a specific
server. But this solution makes hyperlinks in Eldoc buffers
unclickable, because the markdown-mode function that visits a link
relies on the invisible text.
Per https://github.com/joaotavora/eglot/issues/866
* eglot.el (eglot--format-markup): Use buffer-string instead of
filter-buffer-substring
Brian Leung [Tue, 1 Mar 2022 15:59:05 +0000 (07:59 -0800)]
Prevent empty diagnostic tags vector hiding main fontification
* eglot.el (eglot-handle-notification): Require that the resulting
list of faces is non-empty and that each face corresponds only to a
known tag.
For unknown tags, we don't pass any additional face information to
Flymake, and instead expect it to make the appropriate overlay with
the "severity" property of the Diagnostic.
Co-authored-by: João Távora <joaotavora@gmail.com>
GitHub-reference: fix https://github.com/joaotavora/eglot/issues/851
Brian Leung [Sun, 23 Jan 2022 03:59:06 +0000 (19:59 -0800)]
Properly check the completionitem.deprecated property
* eglot.el (eglot-completion-at-point): Check the :deprecated property
is `t'. We do this so that a :deprecated property of :json-false does
not cause a completion candidate to be incorrectly marked as deprecated.
Brian Leung [Thu, 13 Jan 2022 03:06:18 +0000 (19:06 -0800)]
Add support for optional completionitem.tags
* eglot.el (eglot--lsp-interface-alist): Add optional CompletionItem.tags.
(eglot-completion-at-point): Add :company-deprecated key and value,
checking for either the appropriate tag (1) in the :tags property, or
a truthy value for the :deprecated property.
(eglot-client-capabilities): Advertise tagSupport (for tag == 1) and
deprecatedSupport.
Also load an updated version of seq.el in Emacsen < 27.
Stefan Kangas [Sat, 22 Jan 2022 03:13:11 +0000 (04:13 +0100)]
Don't use :exclusive no
See https://github.com/joaotavora/eglot/issues/812 for background, in particular:
https://github.com/joaotavora/eglot/issues/812#issuecomment-1014821345
* eglot.el (eglot-completion-at-point): Don't use :exclusive no, as it
leads to breakage in many cases.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/812
* eglot.el (eglot-handle-notification): Pass on diagnostics from
unvisited files to flymake. Enables project-wide-diagnostics, so that
we can view all diagnostics in a given workspace. Uses new
functionality from flymake 1.2.1, hence the version bump.
* eglot-tests.el (project-wide-diagnostics-typescript): New tests
showcasing the possibility to see all related diagnostics in a
workspace.
* eglot-tests.el (project-wide-diagnostics-rust-analyzer): New tests
showcasing the possibility to see all related diagnostics in a
workspace.
* NEWS.md: Mention the new functionality
* README.md: Mention the new functionality
Stefan Kangas [Fri, 14 Jan 2022 12:03:44 +0000 (13:03 +0100)]
Change rust language server to rust-analyzer
rust-analyzer is the officially blessed Language Server for Rust:
https://github.com/rust-lang/rfcs/pull/2912
Also drop the special support code for RLS.
* eglot.el (eglot-server-programs): Add rust-mode language server
"rust-analyzer" and prefer it to the older "rls".
(eglot-rls, jsonrpc-connection-ready-p)
(eglot-handle-notification): Delete special support for "rls".
* eglot-tests.el (rls-analyzer-watches-files)
(rls-analyzer-hover-after-edit): Rename to ...
(rust-analyzer-watches-files)
(rust-analyzer-hover-after-edit): ... this. Update tests to work
with rust-analyzer.
* README.md: Update references for RLS to point to rust-analyzer.
* NEWS.md: Announce above change.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/803
* eglot.el (eglot-rename): Change from symbol-at-point to
thing-at-point to avoid interning a symbol. Add "unknown symbol" to
prompt when no symbol is found.
Co-authored-by: João Távora <joaotavora@gmail.com>
GitHub-reference: close https://github.com/joaotavora/eglot/issues/385
A DiagnosticTag can be either 1 (DiagnosticTag.Unnecessary) or
2 (DiagnosticTag.Deprecated). Following the rendering suggestions in
the protocol, we fade out Unnecessary code and strike-through
Deprecated code.
* eglot.el (eglot-diagnostic-tag-unnecessary-face)
(eglot-diagnostic-tag-deprecated-face): New faces.
(eglot--tag-faces): New defconst.
(eglot--lsp-interface-alist): Add Diagnostic.tags.
(eglot-client-capabilities): Advertise supported tags.
(eglot-handle-notification): Assign the appropriate properties.
* eglot-tests.el (diagnostic-tags-unnecessary-code): New test.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/794
Brian Leung [Tue, 11 Jan 2022 03:32:19 +0000 (19:32 -0800)]
Don't error out on unsupported diagnostic.codedescription
A codeDescription property is, at the time of writing, an object with
an href property (of type URI, or a string), denoting a "URI to open
with more information about the diagnostic error".
It's not obvious how best to put this into a Flymake diagostic
aside from simply appending it to the diagnostic message, so we'll
worry about it some other time.
* eglot.el (eglot--lsp-interface-alist)
(eglot-client-capabilities): Don't error out on unsupported
Diagnostic.codeDescription.
Brian Leung [Sun, 9 Jan 2022 02:08:23 +0000 (18:08 -0800)]
Properly print error message of eglot-alternatives
* eglot.el (eglot-alternatives): Work with the listified form. This
allows presumed executables provided as (EXECUTABLE &rest ARGS...)
to be displayed in the error.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/786
The {html,css,json}-languageserver executables that are distributed
outside VS Code are not regularly updated by Microsoft; any relevant
updates to the VS Code source tree reach VS Code users without the
need for VS Code developers to go out of their way to publish new
versions of the executables. Consequently, users of other editors who
have been using the server executables from the most obvious NPM
packages are likely using stale versions.
@hrsh7th, a Vim user, created an NPM package with updated versions of these
executables taken straight from VS Code's source tree. We therefore
prefer to direct users to the corresponding repo, which contains
appropriate installation instructions, in the README.
Garret Buell [Wed, 15 Dec 2021 21:17:26 +0000 (13:17 -0800)]
Mark eglot-completion-at-point capf "non-exclusive"
Add :exclusive 'no to eglot-completion-at-point results marking it as
non-exclusive. This will allow completion to fall back to other less precise
completion backends (e.g. dabbrev) if Eglot's returns no results.
* eglot.el (eglot-completion-at-point): Set :exclusive to 'no
Copyright-paperwork-exempt: Yes
GitHub-reference: close https://github.com/joaotavora/eglot/issues/770
Stephen Leake [Tue, 16 Nov 2021 08:23:39 +0000 (00:23 -0800)]
Merge pull request from stephe-ada-guru/master
Fix issues https://github.com/joaotavora/eglot/issues/755, https://github.com/joaotavora/eglot/issues/401; severity not set in textDocument/publishDiagnostics
Ingo Lohmar [Sat, 9 Oct 2021 19:19:37 +0000 (21:19 +0200)]
Fix workspace/configuration handling when given scopeuri directory
The path returned by eglot--uri-to-path is mostly used for file paths,
and therefore does not end with a slash. Such a no-trailing-slash path
violates what default-directory demands (per its docstring), which
causes hack-dir-local-variables-non-file-buffer to not find the
appropriate dir-local vars.
João Távora [Sun, 5 Sep 2021 19:05:45 +0000 (20:05 +0100)]
Fixup last commit
Per https://github.com/joaotavora/eglot/issues/726.
I'm still not entirely convinced using all-completion here is a good
idea. As usual the completion list we get from the server is
pre-filtered to whatever the server wishes. Letting the completion
style do its own filtering (most completion styles use
completion-regexp-list and all-completions themselves) is completely
useless here.
João Távora [Sun, 13 Jun 2021 22:07:42 +0000 (23:07 +0100)]
Transpose order of "pylsp" and "pyls" alternatives
When operating remotely, searching for an executable that don't exist
takes longer than usual. Better to put the most likely server first
in the list to minimize the slowdown.
João Távora [Wed, 26 May 2021 17:51:30 +0000 (18:51 +0100)]
Use project-files to know which directory watchers to skip
The directory-finding logic is probably a bit slower than using
eglot--directories-recursively, but since it honours `.gitignores` and
ignores more directories it's much faster overall. And guaranteed to
create less watchers.
Thanks to Dmitry Gutov <dgutov@yandex.ru> for the idea.
João Távora [Wed, 26 May 2021 14:21:06 +0000 (15:21 +0100)]
Again speed up directory watching
Previously, given a number of globs, Eglot would try to place system
watchers only in those subdirectories that could potentially be
matched by a glob. This meant traversing the whole tree, which could
be impractical. Just place watchers in every subdirectory of the
project (you may run out of watchers).
Michael Livshin [Sat, 15 Dec 2018 01:17:32 +0000 (01:17 +0000)]
Manage cross-referenced files outside project in same server
Close https://github.com/joaotavora/eglot/issues/686, Close https://github.com/joaotavora/eglot/issues/695.
Co-authored-by: João Távora <joaotavora@gmail.com>
* eglot.el (eglot-extend-to-xref): new defcustom, default to
nil.
(eglot--servers-by-xrefed-file): new hash table, mapping file names
to servers.
(eglot--managed-mode): use eglot-current-server, instead of
eglot--cached-server directly.
(eglot--current-server-or-lose): ditto.
(eglot--maybe-activate-editing-mode): ditto.
(eglot-current-server): move all cached-server update logic here -- if
eglot--cached-server is nil, try to find it using current project or
(optionally) xref location.
(eglot--xref-make-match): record the xref location.
* README.md (Customization): Mention new defcustom.
Jim Porter [Thu, 13 May 2021 15:55:31 +0000 (08:55 -0700)]
Correct path/uri when using tramp from ms windows
Co-authored-by: João Távora <joaotavora@gmail.com>
* eglot.el (eglot--connect): Ensure drive letter doesn't sneak into
rootPath. (eglot--path-to-uri): Only add a leading "/" for local MS
Windows paths. (eglot--uri-to-path): Only remove leading "/" from
local MS Windows paths.
João Távora [Thu, 13 May 2021 09:09:20 +0000 (10:09 +0100)]
Provide context for finer project-find-functions
* eglot.el (eglot--guess-contact): Use eglot--current-project.
(eglot): Adjust docstring.
(eglot-lsp-context): New variable.
(eglot--current-project): New helper.
(eglot--maybe-activate-editing-mode, eglot--eclipse-jdt-contact):
Use eglot--current-project.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/687
* eglot.el: Add a completion-category-defaults entry, if applicable.
(eglot--managed-mode): Don't set `completion-styles'
(eglot-completion-at-point): Add style metadata to
completion table.
João Távora [Tue, 13 Apr 2021 00:16:31 +0000 (01:16 +0100)]
Add a passing test demonstrating clangd + tramp works
... It works at least within the minimal, well-controlled reproducible
settings of this test. Maybe if we knew something more about the
setup of the user who submitted this report we would be able to
concoct a failing test, but we don't.
* eglot-tests.el (subr-x): Require it
(eglot--make-file-or-dir): Return expanded file name.
(eglot-tests--lsp-abiding-column-1): New helper.
(eglot-lsp-abiding-column): Use it.
(eglot--tramp-test): Fix `skip-unless` condition.
(eglot--tramp-test-2): New test.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/667
Mohsin Kaleem [Mon, 29 Mar 2021 21:32:33 +0000 (22:32 +0100)]
Add :company-kind to eglot-completion-at-point
* eglot.el (eglot-completion-at-point): Add a :company-kind field to the
completion-at-point function so that company can associate completion
candidates with lsp types.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/652
João Távora [Sat, 10 Apr 2021 13:31:14 +0000 (14:31 +0100)]
Attempt to speed up initial directory/glob correspondence
In https://github.com/joaotavora/eglot/issues/602, not only a new glob processing system was implemented, but
also a new, more correct, way to look for directories that might hold
files matched by one of these globs.
Answering this question is important because the file watchers for
'workspace/didChangeWatchedFiles' are placed on a per-directory basis.
Previously, a glob such as /foo/**/bar/*.el would fail to produce
practical file-watching effects because /foo/**/bar/ isn't really a
directory.
However, answering this question is also expensive, as the globs sent
by the LSP server are meant to match files, not directories. The only
way is to list all files under the project's root directory and test
each glob on each one. If it matches at least one file, that file's
directory is meant to be watched.
We suspect that in https://github.com/joaotavora/eglot/issues/645 and https://github.com/joaotavora/eglot/issues/633 we are falling victim to LSP server
who serve a tremendous unoptimized number of globs, one for each file.
So instead of sending just '/foo/**/bar/*.el' they send
'/foo/**/bar/quux.el', '/foo/**/bar/quuz.el', etc... which would
tremendeously slow down the process. But this is only a suspicion.
This commit tries some simple optimizations: if a directory is known
to be watch-worthy becasue one of its files matched a single glob, no
more files under that directory are tried. This should help somewhat.
Also fixed a bug in 'eglot--files-recursively', though I suspect that
doesn't make that much of a difference.
* eglot.el (eglot--directories-matched-by-globs): New helper.
(eglot--files-recursively): Fix bug.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/645
João Távora [Thu, 1 Apr 2021 23:21:27 +0000 (00:21 +0100)]
Generalize eglot-flymake-backend
Loosen coupling between eglot-flymake-backend and flymake-mode. The
flymake-mode check in 'eglot-handle-notification publishDiagnostics'
was a hack (and it wasn't even functioning correctly on M-x
eglot-shutdown/eglot-reconnect).
This should also allow eglot-flymake-backend to be driven by
diagnostic-annotating frontends other than Flymake, such as the
popular Flycheck package.
* eglot.el (eglot--managed-mode): Use eglot--report-to-flymake.
(eglot-handle-notification textDocument/publishDiagnostics): Use
eglot--report-to-flymake.
This is useful for those who edit files in a certain source tree where
this directory-local variable is set, but without having yet loaded
eglot.el. Those users would be bothered by the usual
risky-local-variable prompt.
Brian Cully [Tue, 2 Mar 2021 21:13:07 +0000 (16:13 -0500)]
Add tramp support
Also close https://github.com/joaotavora/eglot/issues/463, close https://github.com/joaotavora/eglot/issues/84.
Thanks to Brian Cully for the original simple idea. The basic
technique is to pass :file-handler t to make-process, then tweak
eglot--uri-to-path and eglot--path-to-uri, along with some other
functions, to be aware of "trampy" paths".
Crucially, a "stty hack" was needed. It has been encapsulated in a
new a new eglot--cmd helper, which contains a comment explaining the
hack.
Co-authored-by: João Távora <joaotavora@gmail.com>
* eglot.el (eglot--executable-find): Shim two-arg executable-find
function only available on Emacs 27.
(eglot--guess-contact): Use eglot--executable-find.
(eglot--cmd): New helper.
(eglot--connect): Use eglot--cmd. Use :file-handler arg to
make-process.
(eglot--connect, eglot--path-to-uri): Be aware of trampy file
names.
* eglot-tests.el (eglot-tests--auto-detect-running-server-1): New helper.
(eglot--guessing-contact): Better mock for executable-find.
(eglot--tramp-test): New test.
* NEWS.md: mention TRAMP support.
* README.md: mention TRAMP support.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/637