João Távora [Sat, 5 Jan 2019 13:32:13 +0000 (13:32 +0000)]
Handle (un)registercapability requests via generic functions
* eglot.el (Version): Bump to 1.4
(eglot-register-capability, eglot-unregister-capability): New
generic functions.
(eglot--register-unregister): Call eglot-register-capability,
eglot-unregister-capability.
(eglot-register-capability s (eql
workspace/didChangeWatchedFiles)): Rename from
eglot--register-workspace/didChangeWatchedFiles.
(eglot-unregister-capability s (eql
workspace/didChangeWatchedFiles)): Rename from
eglot--unregister-workspace/didChangeWatchedFiles.
João Távora [Wed, 2 Jan 2019 17:12:36 +0000 (17:12 +0000)]
Run connection hooks with proper dir-locals
eglot-connect-hook and eglot-server-initialized-hook must run in a
buffer with properly setup directory-local variables for the project.
This is crucial for things like eglot-signal-didChangeConfiguration,
which needs a properly setup value of eglot-workspace-configuration to
succeed.
I could have chosen any of the buffers where Eglot is activating
itself, but the approach using
hack-dir-local-variables-non-file-buffer seems more correct, despite
the name.
* eglot.el (eglot--connect): Run connection hooks with proper
dir-locals.
João Távora [Sun, 16 Dec 2018 19:03:06 +0000 (19:03 +0000)]
Take over flymake and eldoc completely while managing buffers
Take a pragmatic approach and override all other Flymake and Eglot
backends while Eglot is enabled. Restore previous values after
eglot-shutdown.
Certainly cases might arise where using more than one datasource
besides LSP while Eglot is managing the buffer is useful. But
currently contrary, it confuses users enabling Eglot in buffers that
already have flymake/eldoc backends configured.
The reasons are slightly different for Eldoc and Flymake:
- For Eldoc the :before-until strategy only makes sense for
synchronous backends, which Eglot isn't. This conflicts with
python.el default python-eldoc-function, which is also asynchronous.
- For Flymake, the default backends in Emacs (python-mode, c-mode, and
a few others) are mainly repetitions of what LSP does. The global
value is still run though (in case you want to put, say, a
spell-checking backend there).
* eglot.el (eglot--saved-bindings, eglot--setq-saving): New
helpers.
(eglot--managed-mode): Use them.
João Távora [Thu, 6 Dec 2018 18:26:17 +0000 (18:26 +0000)]
Warn about suspicious interface usage at compile-time
For fun, set eglot-strict-mode to '(disallow-non-standard-keys
enforce-required-keys enforce-optional-keys) when compiling, or just
use flymake-mode in eglot.el.
* eglot.el (eglot--lsp-interface-alist): Use in compile-time.
Order alphabetically. Fix a few bugs.
(eglot-strict-mode): Disallow non-standard-keys when compiling.
Update docstring.
(eglot--keywordize-vars, eglot--check-interface): New
compile-time-helpers.
(eglot--dbind, eglot--dcase): Use new helpers.
João Távora [Mon, 3 Dec 2018 12:24:26 +0000 (12:24 +0000)]
Robustify previous fix against non-standard insertion bindings
* eglot.el (eglot--managed-mode): Manage post-self-insert-hook.
(eglot--last-inserted-char): New variable.
(eglot--post-self-insert-hook): Set it.
(eglot--before-change): Reset it.
(eglot--CompletionParams): Use it.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/173
João Távora [Sun, 2 Dec 2018 10:54:09 +0000 (10:54 +0000)]
Support completioncontext to help servers like ccls
* eglot.el (eglot-client-capabilities): Annouce
textDocument/completion/contextSupport.
(eglot--CompletionParams): New helper.
(eglot-completion-at-point): Use it.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/173
João Távora [Sat, 1 Dec 2018 22:47:56 +0000 (22:47 +0000)]
Don't break in indirect buffers
Indirect buffers, such as the ones created by ediff-regions-wordwise,
have eglot enabled but not buffer-file-name. Resort to the finding
the file-name of the original buffer for these.
* eglot.el (eglot--TextDocumentIdentifier): Work in indirect
buffers.
* eglot.el (eglot--lsp-interface-alist): Add CodeAction,
FileSystemWatcher, Registration, TextDocumentEdit, WorkspaceEdit.
(eglot-handle-notification): Use eglot--dbind.
(eglot--apply-workspace-edit): Use eglot--dbind and eglot--lambda.
(eglot-code-actions): Use eglot--lambda.
(eglot--register-workspace/didChangeWatchedFiles): Use eglot--lambda.
João Távora [Wed, 28 Nov 2018 20:26:37 +0000 (20:26 +0000)]
Simplify interface of eglot--dbind macro
* eglot.el (eglot--dbind): Use new interface.
(eglot--lambda): Use new eglot--dbind interface.
(eglot--lsp-interface-alist): Fix docstring.
(eglot--call-with-interface): Simplify.
(eglot--plist-keys): New helper.
* eglot-tests.el (eglot-strict-interfaces):
Add a new test clause.
* eglot.el (eglot-current-column): Rename from eglot--current-column.
(eglot-current-column-function): Use it as value and mention in docstring.
(eglot--xref-make): Use eglot-current-column.
(eglot-current-column-function): Set to eglot--current-column.
(eglot--pos-to-lsp-position): Don't bind tab-width anymore.
(eglot--xref-make): Use eglot--current-column.
João Távora [Tue, 27 Nov 2018 13:49:30 +0000 (13:49 +0000)]
Improve performance of xref summary line collection
* eglot.el (eglot--temp-location-buffers): New variable.
(eglot--handling-xrefs): New macro.
(eglot--xref-make): Use eglot--temp-location-buffers.
(xref-backend-definitions, xref-backend-references)
(xref-backend-apropos): Use eglot--handling-xrefs.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/52
GitHub-reference: per https://github.com/joaotavora/eglot/issues/127
João Távora [Fri, 23 Nov 2018 12:31:15 +0000 (12:31 +0000)]
Control strictness towards incoming lsp messages
A new variable, eglot-strict-mode controls whether Eglot is strict or
lax with regard to incoming LSP messages.
1. Bug reports should be tested with eglot-strict-mode set to
'(disallow-non-standard-keys enforce-required-keys)
2. Users struggling to get non-standard servers working set this
variable to '(), nil. For now, by popular demand, this is the
default value.
Note that this commit in particular introduces a new infrastructure,
but does not yet alter any code in Eglot to use it. Neither is the
variable eglot--lsp-interface-alist populated.
* eglot-tests.el (eglot-strict-interfaces): New test.
* eglot.el (eglot--lsp-interface-alist): New variable.
(eglot-strict-mode): New variable.
(eglot--call-with-interface): New helper.
(eglot--dbind): New macro.
(eglot--lambda): New macro.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/144
GitHub-reference: per https://github.com/joaotavora/eglot/issues/156
João Távora [Mon, 19 Nov 2018 23:16:33 +0000 (23:16 +0000)]
Fix potential security issue fontifying lsp doc
Previously, a server could mistankely or maliciously call *-mode
functions by in the response to a completion or hover request,
specifically in the :documentation field of the response.
Although there are plenty of similar avenues of attack in Emacs, it's
probably a good idea not to let LSP servers decide which functions to
call in an Emacs session running Eglot.
* eglot.el (eglot--format-markup): Call major-mode to fontify
buffer, not some dynamically constructed function name.
(eglot-completion-at-point): Ensure eglot--format-markup runs in
source buffer.
* eglot.el (eglot--pos-to-lsp-position): Call
eglot-current-column-function with tab-width bound to 1.
(eglot--lsp-position-to-point): Call eglot-move-to-column-function
with tab-width bound to 1.
João Távora [Tue, 13 Nov 2018 22:08:16 +0000 (22:08 +0000)]
Add ability to report lsp-compliant columns
* eglot.el (eglot-current-column-function): New variable.
(eglot-lsp-abiding-column): New helper.
(eglot--pos-to-lsp-position): Use eglot-current-column-function.
(eglot-move-to-column-function): Tweak docstring.
João Távora [Mon, 12 Nov 2018 22:29:38 +0000 (22:29 +0000)]
Add ability to move to lsp-precise columns
Also close https://github.com/joaotavora/eglot/issues/125.
Idea and much of design contributed by Michał Krzywkowski
<k.michal@zoho.com>
This introduces the variable eglot-move-to-column-function.
According to the standard, LSP column/character offsets are based
on a count of UTF-16 code units, not actual visual columns. So
when LSP says position 3 of a line containing just \"aXbc\",
where X is a multi-byte character, it actually means `b', not
`c'. This is what the function
`eglot-move-to-lsp-abiding-column' does.
However, many servers don't follow the spec this closely, and
thus this variable should be set to `move-to-column' in buffers
managed by those servers.
* eglot.el (eglot-move-to-column-function): New variable.
(eglot-move-to-lsp-abiding-column): New function.
(eglot--lsp-position-to-point): Use eglot-move-to-column-function.
* eglot.el (eglot-server-programs): Mention that the function must
accept one argument.
(eglot--guess-contact): Pass to functional contacts the interactive
value.
GitHub-reference: per https://github.com/joaotavora/eglot/issues/63
* eglot.el (eglot--sig-info): Don't lose existing information.
Attempt to highlight the active parameter by searching for it's
:label in signature's :label. Append to the result first sentence
of signature's :documentation, if present.
João Távora [Fri, 10 Aug 2018 01:29:26 +0000 (02:29 +0100)]
Support snippet completions
* eglot.el (eglot-client-capabilities): Declare support for
snippet-based completions.
(eglot-completion-at-point): Expand snippet completions with
YASnippet if that is found.
(eglot-note, eglot-warning, eglot-error): Diagnostic
overlay priorities have to be slightly lower than yasnippet's,
which must be reasonably high.
GitHub-reference: close https://github.com/joaotavora/eglot/issues/50