Skip to content

Commit dd32ffc

Browse files
committed
feat(lsp): add completion kinds
1 parent 5349ff3 commit dd32ffc

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

elsa-lsp-core.el

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,19 @@ be re-analysed during textDocument/didOpen handler.")))
180180
(cl-defun elsa-lsp--list-completion-items (list &key transform kind)
181181
(setq transform (or transform #'identity))
182182
(apply #'vector
183-
(mapcar (lambda (item)
184-
(lsp-make-completion-item
185-
:label (funcall transform item)
186-
:kind (or kind lsp/completion-item-kind-text)))
187-
list)))
188-
189-
(defun elsa-lsp--completions ()
183+
(mapcar
184+
(lambda (item)
185+
(let ((completion (funcall transform item)))
186+
(lsp-make-completion-item
187+
:label (if (listp completion)
188+
(plist-get completion :label)
189+
completion)
190+
:kind (if (listp completion)
191+
(plist-get completion :kind)
192+
(or kind lsp/completion-item-kind-text)))))
193+
list)))
194+
195+
(defun elsa-lsp--function-completions ()
190196
;; only used to extract start and end... we can reimplement it later
191197
(-when-let ((beg end) (elsa-lsp--completions-bounds))
192198
(message "bounds %s %s" beg end)
@@ -199,10 +205,10 @@ be re-analysed during textDocument/didOpen handler.")))
199205
(maphash
200206
(lambda (k v)
201207
(when (string-prefix-p prefix (symbol-name k))
202-
(push k candidates)))
208+
(push v candidates)))
203209
(oref elsa-global-state defuns))
204210
(message "has %d functions for prefix %s" (length candidates) prefix)))
205-
(mapcar #'symbol-name candidates))))
211+
candidates)))
206212

207213
(defun elsa-lsp--capf-completions ()
208214
"Fallback completions engine is the `elisp-completion-at-point'."
@@ -236,7 +242,7 @@ be re-analysed during textDocument/didOpen handler.")))
236242
:line (1- (oref form end-line))
237243
:character (oref form end-column))))
238244

239-
(defun elsa-lsp--analyze-textDocument/hover (form state method params)
245+
(defun elsa-lsp--analyze-textDocument/hover (form _state _method params)
240246
(-let* (((&HoverParams :position (&Position :line :character))
241247
params))
242248
(when (and (= (oref form line) (1+ line))
@@ -275,9 +281,11 @@ be re-analysed during textDocument/didOpen handler.")))
275281
(lsp--make-response id value)))))))
276282

277283
(defun elsa-lsp--analyze-textDocument/completion (form state method params)
278-
(-let* ((lgr (lgr-get-logger "elsa.lsp.analyzer"))
279-
((&CompletionParams :position (&Position :line :character))
280-
params))
284+
(-let ((lgr (lgr-get-logger "elsa.lsp.analyzer"))
285+
(scope (oref state scope))
286+
((&CompletionParams :position (&Position :line :character))
287+
params))
288+
(lgr-debug lgr "form before %s" (elsa-tostring form))
281289
(when (and (= (oref form line) (1+ line))
282290
(<= (oref form column) character)
283291
(or (< (1+ line) (oref form end-line))
@@ -290,25 +298,24 @@ be re-analysed during textDocument/didOpen handler.")))
290298
(elsa-form-function-call-p (oref form parent))
291299
(oref form parent)))))
292300
;; special completion inside a function call form
293-
(lgr-debug lgr "call-formadsadasdasdadx %s" (elsa-tostring call-form))
301+
(lgr-debug lgr "call-form %s" (elsa-tostring call-form))
294302
(cond
295-
((eq (elsa-get-name call-form) 'oref)
296-
(lgr-debug lgr "call-form is oref")
297-
(let* ((inst-form (elsa-cadr call-form))
298-
(inst-type (elsa-get-type inst-form)))
299-
(lgr-debug lgr "instance type is %s" (elsa-tostring inst-type))
303+
;; complete the slot for oref or oset
304+
((memq (elsa-get-name call-form) '(oref oset))
305+
(when-let* ((inst-form (elsa-cadr call-form))
306+
(inst-type (elsa-get-type inst-form)))
300307
(when (elsa-class-type-p inst-type)
301-
(lgr-debug lgr "is class type of name %s" (oref inst-type name))
302308
(when-let* ((class (elsa-state-get-defclass state (oref inst-type name))))
303-
(lgr-debug lgr "has class")
304-
(let ((slots (--map
305-
(oref it name)
306-
(elsa-get-slots class))))
309+
(let ((slots (elsa-get-slots class)))
307310
(throw 'lsp-response
308311
(lsp-make-completion-list
309312
:is-incomplete json-false
310313
:items (elsa-lsp--list-completion-items
311-
slots :transform #'symbol-name))))))))))
314+
slots
315+
:transform (lambda (x) (symbol-name (elsa-get-name x)))
316+
:kind lsp/completion-item-kind-field))))))))
317+
318+
))
312319

313320
;; Here we complete the function name if the point is at the
314321
;; first position in a list
@@ -318,11 +325,19 @@ be re-analysed during textDocument/didOpen handler.")))
318325
(lgr-debug lgr "completing function name %s" (elsa-tostring form))
319326
(save-excursion
320327
(goto-char (1- (oref form end)))
321-
(when-let ((candidates (elsa-lsp--completions)))
328+
(when-let ((candidates (elsa-lsp--function-completions)))
322329
(throw 'lsp-response
323330
(lsp-make-completion-list
324331
:is-incomplete json-false
325-
:items (elsa-lsp--list-completion-items candidates))))))
332+
:items (elsa-lsp--list-completion-items
333+
candidates
334+
:transform
335+
(lambda (def)
336+
(list :label (symbol-name (oref def name))
337+
:kind (if (memq (oref def defun-type)
338+
'(cl-defmethod cl-defgeneric))
339+
lsp/completion-item-kind-method
340+
lsp/completion-item-kind-function)))))))))
326341

327342
;; regular symbol, we should use defvars and scope
328343
;; variables

0 commit comments

Comments
 (0)