1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00
Commit graph

1174 commits

Author SHA1 Message Date
João Távora
b55e6b77eb Eglot: adjust semtok delta request debouncing
When a response to a semtok request is received, it's important
to remember which regions to flush.  Font-lock logic will then
do its magic and coalesce those regions into one before invoking
eglot--semtok-font-lock, and eglot--semtok-font-lock-1 will have
up-to-date data to work with.

* lisp/progmodes/eglot.el (eglot--semtok-request): Rework.
(eglot--semtok-inflight): Adjust docstring.
2025-11-12 20:47:34 +00:00
João Távora
928df44707 Eglot: simplify eglot--semtok-font-lock-2
* lisp/progmodes/eglot.el (eglot--semtok-font-lock-2): Simplify.
2025-11-12 13:31:10 +00:00
João Távora
5ea26e0ea5 Eglot: don't use eglot--semtok-idle-timer
Don't have evidence for the usefulness of this optimization yet.

* lisp/progmodes/eglot.el (eglot--semtok-idle-timer): Delete.
(eglot--semtok-request): Simplify.
2025-11-12 13:30:47 +00:00
João Távora
b248acba1d Eglot: rework semtok user options and face calculation
* lisp/progmodes/eglot.el (eglot-semantic-tokens-faces)
(eglot-semantic-tokens-modifier-faces): Delete.
(eglot--semtok-types, eglot--semtok-modifiers): Rename from
eglot-semantic-tokens-faces and
eglot-semantic-tokens-modifier-faces.
(eglot-client-capabilities): Tweak.
(eglot--lsp-interface-alist): Add SemanticTokensLegend.
(eglot--connect): Don't initialize a server.
(eglot--semtok-define-things): New helper.
(eglot-lsp-server): Just one slot needed.
(eglot--semtok-token-faces): Rework.
2025-11-12 13:30:47 +00:00
João Távora
2589dfc300 Eglot: fix last debouncing commit
* lisp/progmodes/eglot.el
(eglot--semtok-request): tweak.
2025-11-12 00:41:57 +00:00
João Távora
849a2a9834 Eglot: debounce multiple useless full-buffer semtok delta rquests
Many back-to-back calls for 'eglot--semtok-request' and small
regions occur even on trivial fast edits.  Even though it's
cheap and harmless to send many delta rquests, it's nicer to
just send just one.  The debouncing from jsonrpc-async-request
almost suffices, but sometimes two requests creep in because
didChange is sent in between.  Use this simple flag to avoid.

* lisp/progmodes/eglot.el (eglot--semtok-inflight): New variable.
(eglot--semtok-request): Use it.
2025-11-12 00:10:49 +00:00
João Távora
950764fe72 Eglot: change semtok implementation yet again
Stefan's idea to use ONLY font-lock instead of jit-lock seems
more promising and less buggy.  I did have to add this slightly
odd eglot--semtok-font-lock-2 kludge, though, but other than
that, it seems fine.

* lisp/progmodes/eglot.el (eglot-semantic-tokens-mode): Now use
ONLY font-lock.
(eglot--semtok-request): Rework, don't call painting function
here.
(eglot--semtok-font-lock): Rename from eglot--semtok-jit-lock and
use a single arg.  Maybe call eglot--semtok-font-lock-2.  Return
nil or risk crashing Emacs.
(eglot--semtok-font-lock-1): Rework slightly.
(eglot--semtok-font-lock-2): New helper.
2025-11-11 22:44:41 +00:00
João Távora
cdd9cad77c Eglot: rework semtok code again
Simplify many things.  Instead of font-lock-add-keywords, use
jit-lock-register exclusively.  Works, but slightly problematic,
since when editing the buffer the existing enriched face
information is first removed, then readded.  Will try other
approaches.

* lisp/progmodes/eglot.el (eglot-connect-hook): Don't put
eglot--semtok-initialize here.
(eglot--connect): Ratther here.
(eglot--semtok-token-faces): New helper.
(eglot--semtok-font-lock): Delete.
(eglot--semtok-initialize): Rework.
(eglot-semantic-tokens-mode): Simplify.
(eglot--semtok-jit-lock): Simplify.
(eglot--semtok-jit-lock-1): Simplify.
2025-11-11 21:39:27 +00:00
João Távora
4e3535566b Eglot: rework semtok feature
Kept the general structure but clarified the code paths.

Less lines of code, remove some variables.  Probably fixed some
bugs and introduced others.

* lisp/progmodes/eglot.el (eglot-lsp-server): Tweak doc.
(eglot--semtok-request-full-on-idle): Delete.  Integrated into caller.
(eglot--semtok-jit-lock): Rename from eglot--semtok-propertize.  Rework.
(eglot--semtok-jit-lock-1): Extract from old eglot--semtok-propertize.
(eglot-semantic-tokens-mode): Use new eglot--semtok-jit-lock name.
(eglot--semtok-put-cache)
(eglot--semtok-ingest-range-response)
(eglot--semtok-ingest-delta-response)
(eglot--semtok-ingest-full-response): Delete helpers.
(eglot--semtok-apply-delta-edits): Rework with more cl-loopy idioms.
(eglot--semtok-flush-region): Delete.
(eglot--semtok-request): Now takes a region as argument.  Rework extensively.
2025-11-11 15:09:20 +00:00
João Távora
f622737a3e Eglot: fix bug when handling server-intiated semtok regresh
* lisp/progmodes/eglot.el
(eglot-handle-request): Don't bump eglot--versioned-identifier,
since that confuses semtok bootstrap in a new file with clangd.
2025-11-11 15:09:20 +00:00
João Távora
e6c31808c4 Eglot: rename semtok things
* lisp/progmodes/eglot.el (eglot--semtok-font-lock): Rename from
eglot--semtok-fontify-tokens.
(eglot-semantic-tokens-mode): Use eglot--semtok-font-lock.
(eglot--semtok-ingest-delta-response): Rename from
eglot--semtok-ingest-full/delta-response
(eglot--semtok-request): Use new function.
2025-11-11 15:09:11 +00:00
João Távora
9cffaf74e7 Eglot: reorganize semtok code
* lisp/progmodes/eglot.el (eglot-semantic-tokens-faces)
(eglot-semantic-tokens-modifier-faces): Move up to defcustom section.
(eglot--semtok-fontify-tokens)
(eglot--semtok-request-full-on-idle, eglot-handle-request)
(eglot--semtok-build-face-map, eglot--semtok-initialize)
(eglot-semantic-tokens-mode): Move into semantic tokens section.
2025-11-11 15:08:31 +00:00
Lua Viana Reis
ad76b8c721 Eglot: add semantic token support
* lisp/progmodes/eglot.el: many changes (TODO describe them)
2025-11-11 15:08:13 +00:00
Spencer Baugh
411e8068dc Eglot: consider invisibility in eldoc one-liners (bug#79779)
Since we keep the invisible characters of all the
server-supplied markdown, we risk that the first lines are
entirely invisible.  This defeats the :echo calculation in
eglot-hover-eldoc-function.

Fallout of bug#79552.

* lisp/progmodes/eglot.el (eglot-hover-eldoc-function): Fix.

Co-authored-by: João Távora <joaotavora@gmail.com>
2025-11-10 11:33:48 +00:00
João Távora
94a4bf8a39 Eglot: release version 1.19
* lisp/progmodes/eglot.el (Version): Bump to 1.19.
(Package-Requires): Require Flymake 1.4.2

* etc/EGLOT-NEWS: Announce new version.
2025-10-23 21:47:04 +01:00
João Távora
1e7981fd86 Eglot: don't send JSONRPC params in 'shutdown' request (bug#79653)
See also bug#66144.
Github-reference: https://github.com/joaotavora/eglot/discussions/1540

* lisp/progmodes/eglot.el (eglot-shutdown): Pass :jsonrpc-omit
(Package-Requires): Require jsonrpc 1.0.26.

* etc/EGLOT-NEWS: Announce bugfix.
2025-10-23 21:46:22 +01:00
Pooya Moradi
f362cef564 Eglot: Add LSP server for TOML.
* lisp/progmodes/eglot.el (eglot-server-programs): Add LSP server
for TOML.  (Bug#79605)

Copyright-paperwork-exempt: yes
2025-10-11 12:37:20 +03:00
Spencer Baugh
3ec87212a4 Eglot: make markup invisible instead of deleting it (bug#79552)
We use gfm-view-mode to render Markdown before we hand over the string
to ElDoc (which usually put it in a 'special' mode "*eldoc*" buffer).
'gfm-view-mode' adds keymap text properties to make links clickable.  It
also makes some of the markup invisible with a special 'invisible'
property value which is specific to 'gfm-view-mode'.  We used to delete
the latter, therefore breaking the link-clicking.  Simply resetting the
regions with non-nil 'invisible' to 't' instead of deleting them fixes
this.  See also https://github.com/joaotavora/eglot/discussions/1238

* lisp/progmodes/eglot.el: Make invisible markup invisible
instead of deleting it.

* etc/EGLOT-NEWS: Mention bugfix.

Co-authored-by: João Távora <joaotavora@gmail.com>
2025-10-03 09:44:56 +01:00
Brian Leung
e06684067d Eglot: Really fix neocmakelsp invocation
* lisp/progmodes/eglot.el (eglot-server-programs): Remove an
incorrect extra layer of parentheses.  (Bug#79394)
2025-09-06 16:42:33 +03:00
João Távora
5db70442e5 Eglot: really fix bug#79259
The previous change actually introduced a bug in a closely
related but distinct place.  We need to address the off-by-one
in the 'substring' call, not the 'add-face-text-property'.

* lisp/progmodes/eglot.el (eglot--sig-info): Fixup.
2025-09-03 08:16:15 +01:00
João Távora
53f5a07beb Eglot: fix likely off-by-1 in LabelOffsetSupport feature (bug#79259)
This feature was tweaked and last tested with a 2019 edition of
the 'ccls' LSP.  The spec does not clearly specify this number
to be 0-indexed, but it would make sense that it would be so.
So there's not need to 1+ - correct the numbers at all before
using them in substring.  This would fix the Haskell server use
of this feature (which is bug#79259)

* lisp/progmodes/eglot.el (eglot--sig-info): Fix likely off-by-1.
2025-08-30 11:44:56 +01:00
Steven Allen
4ab16d701e Eglot: escape literal % characters in URIs
Escape literal % characters in Eglot URIs

Otherwise, a literal % in a file-name will be interpreted (by the
language server) as if it were a part of a percent-encoded sequence.

See Bug#78984 for context on why `url-path-allowed-chars' cannot be
changed to escape literal % characters.

* lisp/progmodes/eglot.el (eglot--uri-path-allowed-chars): Escape %,
remove the redundant variable definition.
* test/lisp/progmodes/eglot-tests.el (eglot-test-path-to-uri-escape):
test it.
2025-08-30 11:19:19 +01:00
Eli Zaretskii
218fc1cc04 ; * lisp/progmodes/eglot.el (eglot--managed-mode): Pacify byte-compiler. 2025-08-19 19:18:28 +03:00
Gerd Möllmann
ab577467e4 ; Revert last change in eglot
* lisp/progmodes/eglot.el (eglot--managed-mode):
Use revert-buffer-in-progress-p again.
2025-08-19 14:43:58 +02:00
Gerd Möllmann
e92da50e05 ; Pacify byte-compiler
* lisp/progmodes/eglot.el (eglot--managed-mode): Use
revert-buffer-in-progress instead of
revert-buffer-in-progress-p.
* lisp/vc/vc-hooks.el (vc-dir-resynch-file): Declare some
functions.
2025-08-19 13:05:00 +02:00
Juri Linkov
80f2f07c48 Add alternative "ruby-lsp" to eglot-server-programs.
* lisp/progmodes/eglot.el (eglot-server-programs):
Add "ruby-lsp" to eglot-alternatives for ruby-mode and ruby-ts-mode.
https://shopify.github.io/ruby-lsp/editors.html#emacs-eglot
2025-06-25 20:07:17 +03:00
Eli Zaretskii
056ba8c569 Merge from origin/emacs-30
df9636f892 ; * doc/misc/use-package.texi (Hooks): Fix typo (bug#77609).
36afdd2f6f Fix documentation of use-package's ':hook' keyword
d0c90bc9bf * test/infra/gitlab-ci.yml (.job-template): Make it more ...
b8f24cbdbb ; * lisp/emacs-lisp/find-func.el (find-function): Doc fix.
e0c6f3e765 Fix todo-mode item insertion bug (bug#78506)
328b316764 Add support for Pyrefly LSP for Python
2025-05-24 06:55:24 -04:00
Yuan Fu
0b2ba13c97
Eglot: always call ElDoc callbacks in correct buffer (bug#78530)
Some minor modes adds their own eldoc display function to
'eldoc-display-functions' hook buffer-locally.  So when eldoc
uses 'eldoc-display-functions' to display docs, it should use
the buffer-local value of the hook.

But that's not always the case. In 'eldoc--invoke-strategy', the
code that runs 'eldoc-display-functions' hook is wrapped in a
callback function that eventually gets passed to each
documentation function in 'eldoc-documentation-functions'. So
now it's the documentation functions' responsibility to call the
eldoc callback in the original buffer.

All the eglot documentation functions indeed do that, using
'eglot--when-buffer-window' to switch to the original buffer
when calling the eldoc callback. But
'eglot-code-action-suggestion' is the exception, the callback is
called outside of the 'eglot--when-buffer-window' form.

This patch fixes that.

This bug was originally reported on eldoc-box [1]. The user
found that eldoc-box's display function are rarely called, even
though the minor mode is turned on. This patch fixes the issue.

[1] https://github.com/casouri/eldoc-box/issues/126#issuecomment-2896611278

* lisp/progmodes/eglot.el (eglot-code-action-suggestion): Move
the funcall form into the eglot--when-buffer-window form.
2025-05-21 22:42:35 -07:00
Jostein Kjønigsen
328b316764 Add support for Pyrefly LSP for Python
* lisp/progmodes/eglot.el (eglot-server-programs): Add config
for Pyrefly.  (Bug#78492)
2025-05-19 14:50:20 +03:00
Eli Zaretskii
b3e280faba Eglot: Fix parsing file:// URIs on MS-Windows
* lisp/progmodes/eglot.el (eglot-uri-to-path): Remove the leading
slash in MS-Windows file names only if they begin with a slash.
This adjusts the function to the recent fix for bug#76982 in
'url-generic-parse-url', which previously would produce file names
that begin with an extra slash.  (Bug#78392)
2025-05-13 14:45:04 +03:00
João Távora
c69c18b732 Eglot: fix call hierarchy navigation again (bug#78367, bug#78250)
* lisp/progmodes/eglot.el (eglot--hierarchy-label): Fix again.
2025-05-11 11:14:18 +01:00
João Távora
7617c7a6e4 Eglot: fix navigation in eglot-hierarchy-mode (bug#78250)
* lisp/progmodes/eglot.el (eglot--hierarchy-label):  Take PARENT-URI. Rework.
(eglot--hierarchy-2): Rework.
2025-05-08 23:13:28 +01:00
Elijah Gabe Pérez
852d50ecfc Eglot: bind mouse-1 to margin and mode-line code actions
* lisp/progmodes/eglot.el (eglot-mode-line-action-suggestion):
advertise mouse-1.
(eglot-diagnostics-map): Bind left-margin mouse-1
(eglot-code-action-suggestion): Advertise mouse 1.  Simplify.

Co-authored-by: João Távora <joaotavora@gmail.com>
2025-05-06 10:58:52 +01:00
João Távora
660ebdddf6 Eglot: allow other keys in window/logMessage (bug#77948)
* lisp/progmodes/eglot.el (eglot-handle-notification window/logMessage): Fix.
2025-05-04 08:27:43 +01:00
João Távora
dd5ae0f3ba Eglot: tweak previous change (clear Flymake 'Wait' state)
When we don't have anything to give to Flymake, we still want to
signal we're alive so the mode-line doesn't show a confusing
'Wait'.

* lisp/progmodes/eglot.el (eglot--report-to-flymake): Clear 'Wait'
state.
2025-04-30 22:45:44 +01:00
João Távora
7ae275f04c Eglot: improve diagnostic-reporting performance
After a change in the buffer has occured, it is often the case
that Flymake is quicker to ask for diagnostics than the server
is to supply them to us.  If we're still stuck with old outdated
diagnostics, don't forward them to Flymake, even if it eagerly
asks us for them.

* etc/EGLOT-NEWS (Changes in upcoming Eglot): Announce changes.

* lisp/progmodes/eglot.el
(eglot--diagnostics): Rework.
(eglot--report-to-flymake): Also take version.
(eglot-handle-notification textDocument/publishDiagnostics)
(eglot--managed-mode)
(eglot-flymake-backend): Tweak call to eglot--report-to-flymake.
2025-04-29 12:23:06 +01:00
João Távora
01f97fabfe Eglot: require bug-fixed Flymake 1.4.1 (bug#77856)
* lisp/progmodes/eglot.el (Package-Requires) Require Flymake 1.4.1.
2025-04-23 08:35:30 +01:00
João Távora
7ac6b33560 Eglot: use richer diagnostic-making capability of Flymake 1.4.0
* lisp/progmodes/eglot.el (Package-Requires): Require Flymake
1.4.0.
(eglot-handle-notification): Tweak.
2025-04-20 23:20:33 +01:00
João Távora
c5b97b7b32 Eglot: be aware of LSP version of contextual diagnostics
In certain situations, Eglot has to report to the server parts
of the diagnostics that it itself sent us.  The server may use
this as context to compute code actions, for example.  Eglot
selects diagnostics by asking Flymake, looking for the ones that
contain Eglot-specific cookies.

But when doing so, it is important to also be aware of the LSP
document version these each of these diagnostics pertain to,
since if a diagonstic in the buffer pertains to an older version
of the LSP document (because Flymake fired or the server hasn't
pushed a new set), that diagnostics 'eglot-lsp-data' cookie is
invalid and possibly harmful.

An example is when a diagnostic extends all the way to the end
of the buffer.  If we attempt to fix by shortening the buffer,
an Eldoc-started code actions request may be sent to the server
considering the soon-to-be-deleted Flymake diagnostic as
context.  But that diagnostic's 'eglot-lsp-data' cookie is no
longer valid and when processing that context we try to go past
point-max and burp an annoying error.

Best to check the version of the diagnostic (if we have it) and
ignore the ones that don't match the document version.

* lisp/progmodes/eglot.el (eglot--versioned-identifier): Move up.
(eglot--flymake-diagnostics, eglot--diag-to-lsp-diag): New helpers.
(eglot-handle-notification): Record LSP doc version in diagnostics.
(eglot--code-action-bounds)
(eglot--code-action-params): Use eglot--flymake-diagnostics.
2025-04-17 00:31:38 +01:00
João Távora
3e22c73fb6 Eglot: announce support for diagnostic version checks (bug#77588)
* lisp/progmodes/eglot.el (eglot-client-capabilities): Mention versionSupport.
2025-04-08 22:16:27 +01:00
João Távora
13f439ce98 Eglot: check textDocument/publishDiagnostics version (bug#77588)
* lisp/progmodes/eglot.el (eglot--versioned-identifier): Move up.
(eglot-handle-notification textDocument/publishDiagnostics): Check
eglot--versioned-identifier
2025-04-08 08:46:17 +01:00
Stefan Monnier
468c2aebae Replace uses of replace-buffer-contents
* lisp/vc/vc.el (vc-diff-restore-buffer):
* lisp/progmodes/python.el (python--do-isort):
* lisp/progmodes/eglot.el (eglot--apply-text-edits):
* lisp/files.el (revert-buffer-insert-file-contents-delicately):
* lisp/json.el (json-pretty-print): Use `replace-region-contents`.
2025-03-29 17:49:49 -04:00
Gerd Möllmann
638ec3cd66 Remove a use of a PUA Unicode character (bug#77328)
* lisp/progmodes/eglot.el (eglot-code-action-indicator): Use
U+1F4A1 ELECTRIC LIGHT BULB instead of a PUA character.
2025-03-28 14:48:33 +01:00
João Távora
d81cdf9fd2 Eglot: unbreak from Emacs 26.3 (two-arg setq-local)
* lisp/progmodes/eglot.el (eglot--hierarchy-1): Use two-arg setq-local
2025-03-08 05:15:57 +00:00
João Távora
07bbfea901 Eglot: fix invocation of neocmakelsp
* lisp/progmodes/eglot.el (eglot-server-programs): Fix invocation
of neocmakelsp
2025-03-02 22:22:15 +00:00
Felician Nemeth
18c81b76bc Eglot: implement additionalPropertiesSupport for showMessage
This feature was introduced in LSP v3.16.

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#window_showMessageRequest

* lisp/progmodes/eglot.el (eglot-client-capabilities): Set
window/showMessage/messageActionItem/additionalPropertiesSupport to t.
(eglot-handle-request window/showMessageRequest): Return the whole
selected MessageActionItem, not just its title.

Co-authored-by: João Távora <joaotavora@gmail.com>
2025-03-02 22:22:09 +00:00
Stefan Kangas
60b071e224 Make cl-gensym obsolete in favor of built-in gensym
* lisp/emacs-lisp/cl-macs.el (cl-gensym): Declare function
obsolete in favor of gensym, added in Emacs 26.1.  The only reason
for its existence is that it allows an integer argument, but
that's not really useful, so it's better to remove this complexity.
Ref: https://lists.gnu.org/r/emacs-devel/2017-09/msg00313.html
* doc/misc/cl.texi (Symbols, Creating Symbols, Efficiency Concerns)
(Obsolete Setf Customization): Don't document above obsolete function.
* lisp/emacs-lisp/cl-macs.el (cl--parse-loop-clause):
* lisp/emacs-lisp/edebug.el (edebug-make-form-wrapper):
* lisp/obsolete/cl.el (cl--function-convert, lexical-let):
* lisp/obsolete/thumbs.el (thumbs-temp-file):
* lisp/progmodes/eglot.el (eglot--lambda)
(eglot--when-live-buffer, eglot--when-buffer-window)
(eglot--collecting-xrefs, eglot--glob-parse):
* lisp/progmodes/flymake.el (flymake--run-backend):
* test/lisp/emacs-lisp/package-tests.el (with-package-test):
* test/lisp/progmodes/eglot-tests.el (eglot--guessing-contact):
* test/lisp/progmodes/elisp-mode-tests.el
(elisp-shorthand-read-buffer, elisp-shorthand-read-from-string): Prefer
plain gensym to cl-gensym in files that can depend on Emacs 26.1.
* lisp/jsonrpc.el (jsonrpc-lambda, jsonrpc-request): Prefer gensym to
cl-gensym only when defined, as this file supports Emacs 25.1
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-lib-test-gensym): Simplify
test as 'should' no longer uses cl-gensym.
2025-02-25 01:25:15 +01:00
João Távora
7bb53815d2 Eglot: add out-of-box support for neocmakelsp
* lisp/progmodes/eglot.el (eglot-server-programs): Add
neocmakelsp.
2025-02-24 23:38:15 +00:00
João Távora
e4c911adea Eglot: use eglot-advertise-cancellation in more situations
The async requests frequently issued by ElDoc are a significant
source of request pile-up on the server side (for some servers).

With this change, Eglot will issue additional LSP
$/cancelRequest notifications for in-flight requests of certain
kinds in the pre-command hook.

This required a small change to the 'jsonrpc-async-request'
entrypoint.

This feature is experimental.

* lisp/jsonrpc.el (jsonrpc-async-request): No longer returns nil.

* lisp/progmodes/eglot.el (eglot--inflight-async-requests): New variable.
(eglot--cancel-inflight-async-requests): New function.
(eglot--async-request): New function.
(eglot--pre-command-hook): Call eglot--cancel-inflight-async-requests.
(eglot-signature-eldoc-function, eglot-hover-eldoc-function)
(eglot-highlight-eldoc-function, eglot-code-action-suggestion):
Use eglot--async-request.
2025-02-24 23:38:15 +00:00
Stefan Kangas
702cb123fa ; Fix typos 2025-02-22 14:48:29 +01:00