[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot 1ac06d0 10/10: Fix #76: manage cross-referenced f
From: |
Stefan Monnier |
Subject: |
[elpa] externals/eglot 1ac06d0 10/10: Fix #76: manage cross-referenced files outside project in same server |
Date: |
Wed, 19 May 2021 21:52:14 -0400 (EDT) |
branch: externals/eglot
commit 1ac06d0bcc247fb19df6eceb57e2ea3d534806ec
Author: Michael Livshin <repo@cmm.kakpryg.net>
Commit: João Távora <joaotavora@gmail.com>
Fix #76: manage cross-referenced files outside project in same server
Close #686, Close #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.
* NEWS.md: Mention new feature
---
NEWS.md | 10 ++++++++++
README.md | 6 ++++++
eglot.el | 32 +++++++++++++++++++++-----------
3 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/NEWS.md b/NEWS.md
index d060ad4..03a22bc 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -7,6 +7,13 @@ Thanks to Brian Cully for the minimalist approach.
(also thanks to Felipe Lema who conducted many early experiments in
[#463][github#463])
+##### Manage cross-referenced files outside project ([#76][github#76],
([#686][github#686], ([#695][github#695])
+
+This is activated by a new customization option
+`eglot-extend-to-xref`, which defaults to nil.
+
+Thanks to Michael Livshin for the investigation an elegant solution.
+
##### Code action shortcuts ([#411][github#411])
`M-x eglot-code-actions` accepts an optional `action-kind` argument,
@@ -214,6 +221,7 @@ and now said bunch of references-->
[github#68]: https://github.com/joaotavora/eglot/issues/68
[github#73]: https://github.com/joaotavora/eglot/issues/73
[github#74]: https://github.com/joaotavora/eglot/issues/74
+[github#76]: https://github.com/joaotavora/eglot/issues/76
[github#80]: https://github.com/joaotavora/eglot/issues/80
[github#81]: https://github.com/joaotavora/eglot/issues/81
[github#82]: https://github.com/joaotavora/eglot/issues/82
@@ -263,3 +271,5 @@ and now said bunch of references-->
[github#494]: https://github.com/joaotavora/eglot/issues/494
[github#637]: https://github.com/joaotavora/eglot/issues/637
[github#643]: https://github.com/joaotavora/eglot/issues/643
+[github#686]: https://github.com/joaotavora/eglot/issues/686
+[github#695]: https://github.com/joaotavora/eglot/issues/695
diff --git a/README.md b/README.md
index 0ad6d46..302c7f6 100644
--- a/README.md
+++ b/README.md
@@ -319,6 +319,12 @@ lisp:
- `eglot-stay-out-of`: List of Emacs features that Eglot shouldn't
automatically try to manage on users' behalf. Useful when you need
non-LSP Flymake or Company backends. See docstring for examples.
+
+- `eglot-extend-to-xref`: If non-nil and `xref-find-definitions` lands
+ you in a file outside your project -- like a system-installed
+ library or header file -- transiently consider it managed by the
+ same LSP server. That file is still outside your project
+ (i.e. `project-find-file` won't find it).
# How does Eglot work?
diff --git a/eglot.el b/eglot.el
index f17e795..db468d8 100644
--- a/eglot.el
+++ b/eglot.el
@@ -237,6 +237,10 @@ let the buffer grow forever."
:type '(choice (const :tag "Don't show confirmation prompt" nil)
(symbol :tag "Show confirmation prompt" 'confirm)))
+(defcustom eglot-extend-to-xref nil
+ "If non-nil, activate Eglot in cross-referenced non-project files."
+ :type 'boolean)
+
;; Customizable via `completion-category-overrides'.
(when (assoc 'flex completion-styles-alist)
(add-to-list 'completion-category-defaults '(eglot (styles flex basic))))
@@ -832,6 +836,9 @@ be guessed."
(put 'eglot-lsp-context 'variable-documentation
"Dynamically non-nil when searching for projects in LSP context.")
+(defvar eglot--servers-by-xrefed-file
+ (make-hash-table :test 'equal :weakness 'value))
+
(defun eglot--current-project ()
"Return a project object for Eglot's LSP purposes.
This relies on `project-current' and thus on
@@ -1495,7 +1502,7 @@ Use `eglot-managed-p' to determine if current buffer is
managed.")
#'eglot-imenu))
(flymake-mode 1)
(eldoc-mode 1)
- (cl-pushnew (current-buffer) (eglot--managed-buffers
eglot--cached-server)))
+ (cl-pushnew (current-buffer) (eglot--managed-buffers
(eglot-current-server))))
(t
(remove-hook 'after-change-functions 'eglot--after-change t)
(remove-hook 'before-change-functions 'eglot--before-change t)
@@ -1533,11 +1540,19 @@ Use `eglot-managed-p' to determine if current buffer is
managed.")
(defun eglot-current-server ()
"Return logical EGLOT server for current buffer, nil if none."
- eglot--cached-server)
+ (setq eglot--cached-server
+ (or eglot--cached-server
+ (cl-find major-mode
+ (gethash (eglot--current-project)
eglot--servers-by-project)
+ :key #'eglot--major-mode)
+ (and eglot-extend-to-xref
+ buffer-file-name
+ (gethash (expand-file-name buffer-file-name)
+ eglot--servers-by-xrefed-file)))))
(defun eglot--current-server-or-lose ()
"Return current logical EGLOT server connection or error."
- (or eglot--cached-server
+ (or (eglot-current-server)
(jsonrpc-error "No current JSON-RPC connection")))
(defvar-local eglot--unreported-diagnostics nil
@@ -1555,14 +1570,7 @@ If it is activated, also signal textDocument/didOpen."
(unless eglot--managed-mode
;; Called when `revert-buffer-in-progress-p' is t but
;; `revert-buffer-preserve-modes' is nil.
- (when (and buffer-file-name
- (or
- eglot--cached-server
- (setq eglot--cached-server
- (cl-find major-mode
- (gethash (eglot--current-project)
- eglot--servers-by-project)
- :key #'eglot--major-mode))))
+ (when (and buffer-file-name (eglot-current-server))
(setq eglot--unreported-diagnostics `(:just-opened . nil))
(eglot--managed-mode)
(eglot--signal-textDocument/didOpen))))
@@ -2101,6 +2109,8 @@ Try to visit the target file for a richer summary line."
(start-pos (cl-getf start :character))
(end-pos (cl-getf (cl-getf range :end) :character)))
(list name line start-pos (- end-pos start-pos)))))))
+ (setf (gethash (expand-file-name file) eglot--servers-by-xrefed-file)
+ (eglot--current-server-or-lose))
(xref-make-match summary (xref-make-file-location file line column)
length)))
(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql eglot)))
- [elpa] externals/eglot updated (fc221c8 -> 1ac06d0), Stefan Monnier, 2021/05/19
- [elpa] externals/eglot efac602 02/10: Fix #673: declare eglot--cached-server before use, Stefan Monnier, 2021/05/19
- [elpa] externals/eglot a0a6218 01/10: Fix #670: make eglot-current-server work in notification handlers, Stefan Monnier, 2021/05/19
- [elpa] externals/eglot 9330397 03/10: Close #677: switch default langserver for OCaml to ocamllsp, Stefan Monnier, 2021/05/19
- [elpa] externals/eglot c6e05e0 04/10: Per #677: mention ocaml-lsp in the README, Stefan Monnier, 2021/05/19
- [elpa] externals/eglot 6f27bc1 06/10: Allow LSP languageId to be overridden via eglot-server-programs, Stefan Monnier, 2021/05/19
- [elpa] externals/eglot 3f1ad3b 07/10: Close #685: Fix Emacs 28 warning by avoiding positional args in define-minor-mode, Stefan Monnier, 2021/05/19
- [elpa] externals/eglot 40bba97 08/10: Per #687: provide context for finer project-find-functions, Stefan Monnier, 2021/05/19
- [elpa] externals/eglot b06589b 09/10: Fix #679: correct path/URI when using TRAMP from MS Windows, Stefan Monnier, 2021/05/19
- [elpa] externals/eglot 1ac06d0 10/10: Fix #76: manage cross-referenced files outside project in same server,
Stefan Monnier <=
- [elpa] externals/eglot 98943f1 05/10: Add a completion-category-defaults entry, Stefan Monnier, 2021/05/19