Skip to content

Commit 8691e92

Browse files
Match multiple space-separated strings
1 parent f6e3211 commit 8691e92

File tree

1 file changed

+64
-42
lines changed

1 file changed

+64
-42
lines changed

lsp-ivy.el

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,25 @@
112112
(cons string face)
113113
(cons string face)))
114114

115-
116-
(defun lsp-ivy--format-symbol-match (symbol-information-match)
115+
(eval-when-compile
116+
(lsp-interface
117+
(lsp-ivy:FormattedSymbolInformation
118+
(:kind :name :location :textualRepresentation)
119+
(:containerName :deprecated))))
120+
121+
(lsp-defun lsp-ivy--workspace-symbol-action
122+
((&SymbolInformation
123+
:location (&Location :uri :range (&Range :start (&Position :line :character)))))
124+
"Jump to selected candidate."
125+
(find-file (lsp--uri-to-path uri))
126+
(goto-char (point-min))
127+
(forward-line line)
128+
(forward-char character))
129+
130+
(defun lsp-ivy--format-symbol-match (symbol-information)
117131
"Convert the match returned by `lsp-mode` into a candidate string.
118-
SYMBOL-INFORMATION-MATCH is a cons cell whose cdr is the SymbolInformation interface from `lsp-mode`."
119-
(-let* (((&SymbolInformation :name :kind :container-name?) (cdr symbol-information-match))
132+
SYMBOL-INFORMATION is a SymbolInformation object from `lsp-mode`."
133+
(-let* (((&SymbolInformation :name :kind :container-name?) symbol-information)
120134
(type (elt lsp-ivy-symbol-kind-to-face kind))
121135
(typestr (if lsp-ivy-show-symbol-kind
122136
(propertize (format "[%s] " (car type)) 'face (cdr type))
@@ -125,49 +139,57 @@ SYMBOL-INFORMATION-MATCH is a cons cell whose cdr is the SymbolInformation inter
125139
(format "%s" name)
126140
(format "%s.%s" container-name? name)))))
127141

128-
(defun lsp-ivy--workspace-symbol-action (symbol-information-candidate)
129-
"Jump to selected SYMBOL-INFORMATION-CANDIDATE, a cons cell whose cdr is a a SymbolInformation."
130-
(-let (((&SymbolInformation :location
131-
(&Location :uri
132-
:range
133-
(&Range :start
134-
(&Position :line :character))))
135-
(cdr symbol-information-candidate)))
136-
(find-file (lsp--uri-to-path uri))
137-
(goto-char (point-min))
138-
(forward-line line)
139-
(forward-char character)))
140-
141-
(lsp-defun lsp-ivy--filter-func ((&SymbolInformation :kind))
142-
"Filter candidate kind from symbol kinds."
143-
(member kind lsp-ivy-filter-symbol-kind))
142+
(lsp-defun lsp-ivy--transform-candidate ((symbol-information &as &SymbolInformation :kind)
143+
filter-regexps?)
144+
"Map candidate to nil if it should be excluded based on `lsp-ivy-filter-symbol-kind' or
145+
FILTER-REGEXPS?, otherwise convert it to an `lsp-ivy:FormattedSymbolInformation' object."
146+
(unless (member kind lsp-ivy-filter-symbol-kind)
147+
(let ((textual-representation (lsp-ivy--format-symbol-match symbol-information)))
148+
(when (--all? (string-match-p it textual-representation) filter-regexps?)
149+
(lsp-put symbol-information :textualRepresentation textual-representation)
150+
symbol-information))))
144151

145152
(defun lsp-ivy--workspace-symbol (workspaces prompt initial-input)
146153
"Search against WORKSPACES with PROMPT and INITIAL-INPUT."
147-
(ivy-read
148-
prompt
149-
(lambda (user-input)
150-
(with-lsp-workspaces workspaces
151-
(lsp-request-async
152-
"workspace/symbol"
153-
(lsp-make-workspace-symbol-params :query user-input)
154-
(lambda (result)
155-
(ivy-update-candidates
156-
(mapcar
157-
(-lambda ((symbol-information &as &SymbolInformation :name))
158-
(cons name symbol-information))
159-
(-remove #'lsp-ivy--filter-func result))))
160-
:mode 'detached
161-
:cancel-token :workspace-symbol))
162-
0)
163-
:dynamic-collection t
164-
:require-match t
165-
:initial-input initial-input
166-
:action #'lsp-ivy--workspace-symbol-action
167-
:caller 'lsp-ivy-workspace-symbol))
154+
(let* ((prev-query nil)
155+
(unfiltered-candidates '())
156+
(filtered-candidates nil)
157+
(update-candidates
158+
(lambda (all-candidates filter-regexps?)
159+
(setq filtered-candidates
160+
(--keep (lsp-ivy--transform-candidate it filter-regexps?)
161+
all-candidates))
162+
(ivy-update-candidates filtered-candidates))))
163+
(ivy-read
164+
prompt
165+
(lambda (user-input)
166+
(let* ((parts (split-string user-input))
167+
(query (or (car parts) ""))
168+
(filter-regexps? (mapcar #'regexp-quote (cdr parts))))
169+
(when query
170+
(if (string-equal prev-query query)
171+
(funcall update-candidates unfiltered-candidates filter-regexps?)
172+
(with-lsp-workspaces workspaces
173+
(lsp-request-async
174+
"workspace/symbol"
175+
(lsp-make-workspace-symbol-params :query query)
176+
(lambda (result)
177+
(setq unfiltered-candidates result)
178+
(funcall update-candidates unfiltered-candidates filter-regexps?))
179+
:mode 'detached
180+
:cancel-token :workspace-symbol))))
181+
(setq prev-query query))
182+
(or filtered-candidates 0))
183+
:dynamic-collection t
184+
:require-match t
185+
:initial-input initial-input
186+
:action #'lsp-ivy--workspace-symbol-action
187+
:caller 'lsp-ivy-workspace-symbol)))
168188

169189
(ivy-configure 'lsp-ivy-workspace-symbol
170-
:display-transformer-fn #'lsp-ivy--format-symbol-match)
190+
:display-transformer-fn
191+
(-lambda ((&lsp-ivy:FormattedSymbolInformation :textual-representation))
192+
textual-representation))
171193

172194
;;;###autoload
173195
(defun lsp-ivy-workspace-symbol (arg)

0 commit comments

Comments
 (0)