@@ -599,6 +599,7 @@ If set to `:none' neither of two will be enabled."
599
599
("textDocument/definition" :capability "definitionProvider")
600
600
("workspace/symbol" :capability "workspaceSymbolProvider")
601
601
("textDocument/codeLens" :capability "codeLensProvider")
602
+ ("textDocument/selectionRange" :capability "selectionRangeProvider")
602
603
("textDocument/prepareRename"
603
604
:check-command (lambda (workspace)
604
605
(with-lsp-workspace workspace
@@ -707,6 +708,9 @@ They are added to `markdown-code-lang-modes'")
707
708
(defvar-local lsp--document-symbols nil
708
709
"The latest document symbols.")
709
710
711
+ (defvar-local lsp--document-selection-range-cache nil
712
+ "The document selection cache.")
713
+
710
714
(defvar-local lsp--document-symbols-request-async nil
711
715
"If non-nil, request document symbols asynchronously.")
712
716
@@ -1039,6 +1043,46 @@ to the beginning and ending points in the range correspondingly."
1039
1043
(app (lambda (range) (lsp--position-to-point (gethash "end" range)))
1040
1044
,(cdr region))))
1041
1045
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
+
1042
1086
(defun lsp-warn (message &rest args)
1043
1087
"Display a warning message made from (`format-message' MESSAGE ARGS...).
1044
1088
This is equivalent to `display-warning', using `lsp-mode' as the type and
0 commit comments