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
João Távora [Wed, 3 Feb 2021 10:41:40 +0000 (10:41 +0000)]
Simplify dir-watching strategy of w/didchangewatchedfiles
Instead of massaging the globPattern to match directories instead of
files, which is fragile, gather the list of directoris to watch by
matching the globPattern against every file recursively (except hidden
files and dirs).
This is still not 100% correct, but should do the right thing is most
cases. Notably, if the correct dirs are being watched, the glob
pattern is matched against all existing and new files in those
directories, which does include hidden files.
* eglot.el (eglot-register-capability): match file globs against
files only.
(eglot--files-recursively): Rename from eglot--directories-recursively.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/602
João Távora [Mon, 1 Feb 2021 17:23:07 +0000 (17:23 +0000)]
Speed up glob matching 2x
with-temp-buffer was taking a lot of time, presumably because it kills
the buffer. Since emacs is single-threaded, we can safely reuse a
single buffer.
João Távora [Mon, 1 Feb 2021 14:03:23 +0000 (14:03 +0000)]
Also override global flymake-diagnostic-functions
The global value of the flymake-diagnostic-functions is likely to be
of little use in Eglot-managed buffers, so don't run it. Likely the
value flymake-proc-legacy-flymake is there which is not only likely of
little uses but also causes trouble in some situations.
The user can easily avert this by leveraging the variable
eglot-stay-out-of.
* eglot.el (eglot--managed-mode): Don't run global
flymake-diagnostic-functions.
Brian Leung [Mon, 1 Feb 2021 01:28:49 +0000 (17:28 -0800)]
Support activeparameter property for signatureinformation
SignatureInformation.activeParameter is new in version 3.16.0 of the
protocol. When non-nil, it is used in place of
SignatureHelp.activeParameter. The latter was deemed insufficient in
languages where multiple signatures for the same function may exist
with arbitrary order of parameters, like Python.
Co-authored-by: João Távora <joaotavora@gmail.com>
* eglot.el (eglot--lsp-interface-alist): Add
SignatureInformation.activeParameter.
* eglot.el (eglot--sig-info): Prioritize
SignatureInformation.activeParameter over
SignatureHelp.activeParameter.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/605
Offer shortcut commands to commonly invoked code actions
See also https://github.com/joaotavora/eglot/issues/598.
Make eglot-code-actions accept a new action-kind argument. If there
is only one action of that kind, apply it. This allows us to create
actions shortcuts like eglot-code-action-organize-imports, etc.
* eglot.el (eglot-code-actions): Accept new argument action-kind.
(eglot--code-action): New function-defining helper macro.
(eglot-code-action-organize-imports)
(eglot-code-action-extract)
(eglot-code-action-inline)
(eglot-code-action-rewrite)
(eglot-code-action-quickfix): New commands.
* README.md: Mention new feature.
* NEWS.md: Mention new feature.
Co-authored-by: João Távora <joaotavora@gmail.com>
GitHub-reference: close https://github.com/joaotavora/eglot/issues/411
Felicián Németh [Sat, 11 Jan 2020 19:12:26 +0000 (20:12 +0100)]
Fix eglot-completion-at-point for multiple matches
The test-completion case shouldn't return t when there are multiple
matches. Similarly, the try-completion should return t only if the
match is exact. See (info "(elisp)Programmed Completion").
* eglot.el (eglot-completion-at-point): Instead of testing
memberships, use test-completion and try-completion suggested
by (info "(elisp)Programmed Completion").
* eglot-tests.el (non-unique-completions): Add new test.
Co-authored-by: João Távora <joaotavora@gmail.com>
GitHub-reference: fix https://github.com/joaotavora/eglot/issues/365
João Távora [Wed, 13 Jan 2021 15:13:32 +0000 (15:13 +0000)]
Unbreak interactivee eglot--connect for complex contact specs
The previous commit for https://github.com/joaotavora/eglot/issues/526 was completely botched. One has to check
current-prefix-arg for the presence of C-u, not eglot--guess-contact
INTERACTIVE arg.
* eglot.el (eglot--guess-contact): Be more careful when
processing guess.
João Távora [Tue, 22 Dec 2020 17:35:08 +0000 (17:35 +0000)]
Don't block in eglot-imenu if performing non-essential task
eglot-imenu is used by imenu which in turn is used by which-func-mode
called from an idle timer. We don't want it to block in that
situation. Latest which-func mode now sets "non-essential" when
performing its duties, so we leverage that in eglot-imenu.
* eglot.el (eglot-imenu): Use non-essential.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/212
João Távora [Tue, 15 Dec 2020 12:24:13 +0000 (12:24 +0000)]
Robustify previous fix of onchange breakage
From the in-code comments:
;; githubhttps://github.com/joaotavora/eglot/issues/259 and githubhttps://github.com/joaotavora/eglot/issues/367: With `capitalize-word' or somesuch,
;; `before-change-functions' always records the whole word's `b-beg'
;; and `b-end'. Similarly, when coalescing two lines into one,
;; `fill-paragraph' they mark the end of the first line up to the end
;; of the second line. In both situations, args received here
;; contradict that information: `beg' and `end' will differ by 1 and
;; will likely only encompass the letter that was capitalized or, in
;; the sentence-joining situation, the replacement of the newline with
;; a space. That's we keep markers _and_ positions so we're able to
;; detect and correct this. We ignore `beg', `len' and
;; `pre-change-len' and send "fuller" information about the region
;; from the markers. I've also experimented with doing this
;; unconditionally but it seems to break when newlines are added.
João Távora [Mon, 14 Dec 2020 17:08:26 +0000 (17:08 +0000)]
Don't let m-x fill-paragraph break didchange
M-x fill-paragraph represents some paragraph-fillling changes very
summarily. Filling
1 // foo
2 bar
Into
1 // foo bar
Only makes two changes: a deletion of the "// " and a replacement of a
newline with a space character. The second change fooled Eglot's fix
for https://github.com/joaotavora/eglot/issues/259, by making a change similar to the one it is made to detect
and correct. That fix should taget things that happen on the same
line, this not being one of those things.
* eglot.el (eglot--after-change): Only apply fix to https://github.com/joaotavora/eglot/issues/259 if
case-fiddling happens on same line.
João Távora [Tue, 3 Nov 2020 10:26:03 +0000 (10:26 +0000)]
Don't force eglot-strict-mode completely in eglot--dcase
Doing so was by design, since there's much ambiguity between the
CodeAction and Command objects. But 'disallow-non-standard-keys is
not necessary to disambiguate, and proved harmful in this bug.
To design a completion-in-region-function replacement that leverages
the elements in completion-at-point-functions, we must ensure that
their :exit-function parts execute in the correct buffer. That is the
buffer where the text to be completed lives, not necessarily the
buffer being used for user interaction.
Later on, this guarantee should be provided by Emacs itself, perhaps
by putting the correct with-current-buffer call in completion--done.
Copyright-paperwork-exempt: yes Co-authored-by: João Távora <joaotavora@gmail.com>
* eglot.el (eglot-completion-at-point): Ensure :exit-function's
buffer is where the source is.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/505