Commitfb8e92beRecorded18 Apr 2026Repositorysigil-lsp

sigil-lsp: add filterText + textEdit to completion items so eglot applies them

Changed
 src/sigil/lsp/completion.sgl | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
Diff
src/sigil/lsp/completion.sglmodified
@@ -65,7 +65,17 @@
65
((>= i n) (reverse acc))
66
(else (loop (cdr xs) (+ i 1) (cons (car xs) acc))))))
67
68
(define (result->item r)
+68
;; A TextEdit replacing the current prefix with the completion label.
+69
;; Without this, eglot filters labels by the text between its
+70
;; completion start and point using a heuristic that drops anything
+71
;; whose label doesn't begin at the exact match position — e.g. a
+72
;; user typing "tcp-" sees nothing because `call-with-tcp-…` exists.
+73
(define (make-text-edit line0 start-char end-char new-text)
+74
`((range . ((start . ((line . ,line0) (character . ,start-char)))
+75
(end . ((line . ,line0) (character . ,end-char)))))
+76
(newText . ,new-text)))
+77
+78
(define (result->item r line0 start-char end-char)
79
(let ((name (search-result-name r))
80
(mod (search-result-module r))
81
(kind (search-result-kind r))
@@ -73,6 +83,8 @@
83
`((label . ,name)
84
(kind . ,(kind->lsp-kind kind))
85
(detail . ,mod)
+86
(filterText . ,name)
+87
(textEdit . ,(make-text-edit line0 start-char end-char name))
88
(documentation . ((kind . "markdown")
89
(value . ,(or summary "")))))))
90
@@ -83,7 +95,10 @@
95
(prefix (and text (prefix-at text line0 char0))))
96
(if (or (not prefix) (string=? prefix ""))
97
`((isIncomplete . #f) (items . #()))
86
(let ((results (guard (e (else '())) (search-docs prefix))))
+98
(let* ((results (guard (e (else '())) (search-docs prefix)))
+99
(plen (string-length prefix))
+100
(start-char (- char0 plen)))
101
`((isIncomplete . #f)
88
(items . ,(map result->item
+102
(items . ,(map (lambda (r)
+103
(result->item r line0 start-char char0))
104
(limit-results results 100))))))))))