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
João Távora [Mon, 13 Jul 2020 22:43:35 +0000 (23:43 +0100)]
Reload eldoc if needed on emacs < 28
ElDoc is preloaded in Emacs, so `require`-ing won't guarantee we are
using the latest version from GNU Elpa when we load eglot.el. Use an
heuristic to see if we need to `load` it in Emacs < 28.
* eglot.el (Package-Requires): Require eldoc 1.5.0
(top): Sometimes load eldoc
João Távora [Wed, 3 Jun 2020 17:40:58 +0000 (18:40 +0100)]
Delegate "hover" and "signature" doc synchronization efforts to eldoc
Uses Eldoc's eldoc-documentation-functions variable. In Eldoc v1.0.0
that variable was already available as a way of handling/composing
multiple docstrings from different sources, but it didn't work
practically with mutiple concurrent async sources. This was fixed in
1.1.0, which Eglot now requires.
This fixes the synchronization problems reported in https://github.com/joaotavora/eglot/issues/494 and also
issue https://github.com/joaotavora/eglot/issues/439. It is likely that some of the exact doc-composing
functionality in Eglot, (developed during those issues) was lost, and
has to be remade, quite likely in Eldoc itself.
Flymake is now also an Eldoc producer, and therefore the problems of
github issues https://github.com/joaotavora/eglot/issues/481 and https://github.com/joaotavora/eglot/issues/454 will also soon be fixed as soon as Eglot
starts using the upcoming Flymake 1.0.9.
* NEWS.md: New entry.
* README.md (eglot-put-doc-in-help-buffer)
(eglot-auto-display-help-buffer): Remove mention to these options.
* eglot.el
(Package-Requires:) Require eldoc.el 1.1.0.
(eglot--when-live-buffer): Rename from eglot--with-live-buffer.
(eglot--when-buffer-window): New macro.
(eglot--after-change, eglot--on-shutdown, eglot-ensure): Use eglot--when-live-buffer.
(eglot--managed-mode): Use eglot-documentation-functions and eldoc-documentation-strategy.
(eglot--highlights): Move down.
(eglot-signature-eldoc-function, eglot-hover-eldoc-function)
(eglot--highlight-piggyback): New eldoc functions.
(eglot--help-buffer, eglot--update-doc)
(eglot-auto-display-help-buffer, eglot-put-doc-in-help-buffer)
(eglot--truncate-string, eglot-doc-too-large-for-echo-area)
(eglot-help-at-point): Remove all of this.
(eglot--apply-workspace-edit): Call eldoc manually after an edit.
(eglot-mode-map): Remap display-local-help to eldoc-doc-buffer
João Távora [Sun, 31 May 2020 10:49:51 +0000 (11:49 +0100)]
Fix small problems around eglot's help buffer
Specifically:
- correctly format the message shown to the user about doc being truncated
- don't show message if the buffer is showing in some frame's window
- correctly name the help buffer switched to with `C-h .'.
This is still not ideal:
- When the `C-h .' suggestion is shown to the user, typing that keybinding
shouldn't result in a new LSP request to fetch probably the same info;
- All this functionality belongs in eldoc.el.
* eglot.el (eglot-help-at-point): Fix buffer name.
(eglot--update-doc): Provide more help.
This way modes used to represent hover info text, such as
gfm-view-mode can e.g. filter out invisible text by providing own
`filter-buffer-substring-function'.
* eglot.el (eglot--format-markup): Use `filter-buffer-substring'.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/482
Rework computation of string given to eldoc (again)
Co-authored-by: Andreii Kolomoiets <andreyk.mad@gmail.com>
Also do some refactoring to join similar logic in
eglot-doc-too-large-for-echo-area and eglot--truncate-string.
* eglot.el (eglot-doc-too-large-for-echo-area): Now returns the
number of lines available.
(eglot--truncate-string): New helper.
(eglot--first-line-of-doc, eglot--top-lines-of-doc): Remove.
(eglot--update-doc): Use new helpers.
* eglot-tests.el (hover-multiline-doc-locus): New test
GitHub-reference: close https://github.com/joaotavora/eglot/issues/459
João Távora [Sat, 2 May 2020 23:43:00 +0000 (00:43 +0100)]
Kind of honour eldoc-echo-area-use-multiline-p
A reworking of an idea and original implementation by Andrii
Kolomoiets <andreyk.mad@gmail.com>. It doesn't honor it completely
because the semantics for a non-t, non-nil value are tricky. And we
don't always exactly know what the symbol prefix reliably.
* eglot.el (eglot--update-doc): Kind of honour
eldoc-echo-area-use-multiline-p.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/443
João Távora [Sat, 2 May 2020 09:30:28 +0000 (10:30 +0100)]
Also check types when destructuring lsp objects
The problem in this issue is that the disambiguation between Command
and CodeAction objects can only be performed by checking the types of
the keys involved. So we added that to the spec and check it at
runtime.
* eglot.el (eglot--lsp-interface-alist): Add types to
Command. Tweak docstring.
(eglot--check-object): Renamed from eglot--call-with-interface.
(eglot--ensure-type): New helper.
(eglot--interface): New helper.
(eglot--check-dspec): Renamed from eglot--check-interface.
(eglot--dbind): Simplify.
(eglot-code-actions): Adjust indentation.
* eglot-tests.el (eglot-dcase-issue-452): New test.
Co-authored-by: João Távora <joaotavora@gmail.com>
* eglot.el (eglot-eldoc-function): Pass nil to eglot--update-doc
on empty hover info.
(eglot--update-doc): Skip update eglot help buffer if string
is nil.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/439
Tests: print contents of *eglot ...* buffers in batch mode.
Useful for the CI on github. To be able to see more of the context of
a failure.
* eglot.el (eglot-server-initialized-hook): Changed semantics. Now
called when an instance of `eglot-lsp-server' is created as part of
the "connect to server" flow. Previously, there was no difference
between this hook and `eglot-connect-hook' which continues to be run
once a connection was successfully established. The
`eglot-server-initialized-hook' will now capture ALL server instances
including those that failed to be started. This change was necessary
to make the test suite be able to dump the output of processes that
fail to start when running the test suite in batch mode ("make check"
and the CI.) In PR https://github.com/joaotavora/eglot/issues/448 it was decided that it is ok to change the
semantics of this hook rather than introducing a new hook.
(eglot--connect): Change place of where the hook is run.
(eglot-connect-hook): Initialized now with
`eglot-signal-didChangeConfiguration' which was kept in
`eglot-server-initialized-hook' before.
* eglot-tests.el (eglot--call-with-fixture): Use
`eglot-server-initialized-hook' rather than `eglot-connect-hook'. And
dump the contents of the *EGLOT ...* buffers when run in
`noninteractive' (i.e. batch) mode.
(eglot--cleanup-after-test): New auxiliary function. Extracted
verbatim out of `eglot--call-with-fixture` in order to lower the
latter's LOC.
Co-authored-by: João Távora <joaotavora@gmail.com>
* eglot.el (eglot-move-to-lsp-abiding-column): use
already existing function to refer to lsp-abiding-column
GitHub-reference: close https://github.com/joaotavora/eglot/issues/397
João Távora [Sun, 19 Jan 2020 10:02:55 +0000 (11:02 +0100)]
Fix eglot-move-to-lsp-abiding-column ()
Ensure conformance with the this part of the specification: "if the
character value is greater than the line length it defaults back to
the line length."
Fix regression introduced in 70e6157b (https://github.com/joaotavora/eglot/issues/315). According to the
LSP specification the exit notification and the shutdown request
shouldn't have arguments ("params: void"). Note that jsonrpc.el
send nil as null on the wire.
* eglot.el (eglot-shutdown): Change back the arguments of
:shutdown and :exit to nil.
Felicián Németh [Fri, 22 Nov 2019 17:35:01 +0000 (18:35 +0100)]
Make a public reader for project-nickname
Close https://github.com/joaotavora/eglot/issues/399.
* eglot.el (eglot-lsp-server): Add a public reader for
project-nickname as eglot-project-nickname.
(eglot--connect, eglot--read-server, eglot--mode-line-format): Use
the public variant.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/354
Felicián Németh [Fri, 22 Nov 2019 15:55:04 +0000 (16:55 +0100)]
Add public hook eglot-managed-mode-hook
Per https://github.com/joaotavora/eglot/issues/354.
* eglot.el (eglot-managed-p): New function.
(eglot--managed-mode-hook): Obsolete it.
(eglot-managed-mode-hook): New hook variable.
(eglot--managed-mode): Run the new hook.
* README.md (Customization): Mention the new hook.
João Távora [Wed, 1 Jan 2020 22:05:29 +0000 (22:05 +0000)]
Avoid double shutdowns and simplify shutdown logic
* eglot.el (eglot-shutdown): Don't turn off eglot--managed-mode here.
(eglot--on-shutdown): Rather here, but without autoshutdown.
(eglot--managed-mode): Don't check eglot--shutdown-requested.