Replies: 2 comments 2 replies
-
Why this matters: subjectively, "semantic selection" is one of the biggest "bang-for-buck" semantic features in terms of usefulness, so my personal valuation for this is not "nice to have", but rather "essential feature". |
Beta Was this translation helpful? Give feedback.
0 replies
-
This snippet of code worked for me using gopls, the Go LSP server. I stole the (defun eglot-expand-selection ()
"Expand the current selection to the enclosing unit of syntax,
as furnished by an LSP textDocument/selectionRange request."
;; TODO(adonovan): add corresponding unexpand.
(interactive)
(let* ((resp (eglot--request (eglot--current-server-or-lose)
:textDocument/selectionRange
`(:textDocument ,(eglot--TextDocumentIdentifier) :positions [,(eglot--pos-to-lsp-position)])))
(selection-range (elt resp 0)) ; LSP SelectionRange
(current-range (cons (point) (if (use-region-p) (mark) (point))))
(new-range (eglot-range-region (plist-get selection-range :range))))
;; Walk down the linked list until we find an enclosing element.
;; We define enclosing as a proper superinterval.
(while (let ((new-start (car new-range))
(new-end (cdr new-range))
(cur-start (car current-range))
(cur-end (cdr current-range)))
(not (and (<= new-start cur-start)
(>= new-end cur-end)
(> (- new-end new-start) (- cur-end cur-start)))))
(setq selection-range (plist-get selection-range :parent))
(setq new-range (eglot-range-region (plist-get selection-range :range))))
;; Finally set the selection.
(goto-char (car new-range))
(set-mark (cdr new-range))
(activate-mark))) Perhaps this could be added to eglot. |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
LSP has this method:
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_selectionRange
Roughly, it returns a stack of nested AST nodes that contain point. The primary intended use-case for this API is syntax-aware selection: the user presses shortcut, and the selection is extended to the next bigger node. This allows the user to quickly select any desired syntactical construct.
In Emacs, a similar functionality is provided by expand-region package, https://github.com/magnars/expand-region.el, but that is based on approximating the syntax tree, and doesn't return correct results in all cases.
Somewhat related, Emacs recently gained support for tree sitter, which provides an alternative for
textDocument/selectionRange
, and there's even a PR to support that from expandRegion magnars/expand-region.el#279. treesit-based implementation is probably usually the better default way to implement this feature, but lsp-based impl would be nice for completeness.With two different provides for this logical functionality, eglot and treesit, perhaps it makes sense to add a first-class interactive command for this to eglot, essentially bringing expand-region functionality into core?
Beta Was this translation helpful? Give feedback.
All reactions