Skip to content

Commit dc86bbb

Browse files
committed
Support textDocument/selectionRange
1 parent 4877161 commit dc86bbb

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

lsp-mode.el

+44
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ If set to `:none' neither of two will be enabled."
599599
("textDocument/definition" :capability "definitionProvider")
600600
("workspace/symbol" :capability "workspaceSymbolProvider")
601601
("textDocument/codeLens" :capability "codeLensProvider")
602+
("textDocument/selectionRange" :capability "selectionRangeProvider")
602603
("textDocument/prepareRename"
603604
:check-command (lambda (workspace)
604605
(with-lsp-workspace workspace
@@ -707,6 +708,9 @@ They are added to `markdown-code-lang-modes'")
707708
(defvar-local lsp--document-symbols nil
708709
"The latest document symbols.")
709710

711+
(defvar-local lsp--document-selection-range-cache nil
712+
"The document selection cache.")
713+
710714
(defvar-local lsp--document-symbols-request-async nil
711715
"If non-nil, request document symbols asynchronously.")
712716

@@ -1039,6 +1043,46 @@ to the beginning and ending points in the range correspondingly."
10391043
(app (lambda (range) (lsp--position-to-point (gethash "end" range)))
10401044
,(cdr region))))
10411045

1046+
(defun lsp--find-wrapping-range (current-selection-range)
1047+
(-let* (((&hash "parent" "range") current-selection-range)
1048+
((start . end) (lsp--range-to-region range)))
1049+
(cond
1050+
((and
1051+
(region-active-p)
1052+
(<= start (region-beginning) end)
1053+
(<= start (region-end) end)
1054+
(or (not (= start (region-beginning)))
1055+
(not (= end (region-end)))))
1056+
(cons start end))
1057+
((and (<= start (point) end)
1058+
(not (region-active-p)))
1059+
(cons start end))
1060+
(parent (lsp--find-wrapping-range parent)))))
1061+
1062+
(defun lsp--get-selection-range ()
1063+
(or
1064+
(-when-let ((cache . cache-tick) lsp--document-selection-range-cache)
1065+
(when (= cache-tick (buffer-modified-tick)) cache))
1066+
(let ((response (cl-first
1067+
(lsp-request
1068+
"textDocument/selectionRange"
1069+
(list :textDocument (lsp--text-document-identifier)
1070+
:positions (vector (lsp--cur-position)))))))
1071+
(setq-local lsp--document-selection-range-cache
1072+
(cons response (buffer-modified-tick)))
1073+
response)))
1074+
1075+
(defun lsp-extend-selection ()
1076+
"Extend selection."
1077+
(interactive)
1078+
(unless (lsp--capability "selectionRangeProvider")
1079+
(signal 'lsp-capability-not-supported (list "selectionRangeProvider")))
1080+
(-when-let ((start . end) (lsp--find-wrapping-range (lsp--get-selection-range)))
1081+
(goto-char start)
1082+
(set-mark (point))
1083+
(goto-char end)
1084+
(exchange-point-and-mark)))
1085+
10421086
(defun lsp-warn (message &rest args)
10431087
"Display a warning message made from (`format-message' MESSAGE ARGS...).
10441088
This is equivalent to `display-warning', using `lsp-mode' as the type and

0 commit comments

Comments
 (0)