fix completions in comments and strings, and more reliable binding completions

This commit is contained in:
XeroOl 2025-07-11 14:04:11 -05:00
parent 28e20f74cb
commit 7b215e15e8
2 changed files with 46 additions and 17 deletions

View File

@ -5,6 +5,7 @@
(local message (require :fennel-ls.message))
(local format (require :fennel-ls.formatter))
(local navigate (require :fennel-ls.navigate))
(local compiler (require :fennel-ls.compiler))
(local {:metadata METADATA} (require :fennel.compiler))
(local hardcoded-completions
@ -20,16 +21,21 @@
(let [file (files.get-by-uri server uri)
;; find where the cursor is
byte (utils.position->byte file.text position server.position-encoding)
;; create a brand new file
file {:text (.. (file.text:sub 1 (- byte 1)) "|" (file.text:sub byte)) :uri file.uri}
_ (compiler.compile server file)
;; find what ast objects are under the cursor
(?symbol parents) (analyzer.find-symbol file.ast byte)
(symbol parents) (analyzer.find-symbol file.ast byte)
;; check what context I'm in
in-call-position? (and (fennel.list? (. parents 1))
(= ?symbol (. parents 1 1)))
(= symbol (. parents 1 1)))
;; find the first one that contains a scope
scope (or (accumulate [?find nil _ parent (ipairs parents) &until ?find]
(. file.scopes parent))
file.scope)
range (if ?symbol (message.ast->range server file ?symbol) {:start position :end position})
range (case (message.ast->range server file symbol)
r (do (set r.end.character (- r.end.character 1)) r)
_ {:start position :end position})
results []
seen {}]
@ -67,7 +73,7 @@
(set (. seen-manglings global*) true)
(case (analyzer.search-name-and-scope server file global* scope)
def (if (and (= :_G (tostring global*))
(not (: (tostring ?symbol) :match "_G[:.]")))
(not (: (tostring symbol) :match "_G[:.]")))
(add-completion! global* def)
(add-completion-recursively! global* def))
_ (do
@ -104,10 +110,10 @@
(case (message:match "unknown identifier: ([a-zA-Z0-9_-]+)")
identifier (add-completion! identifier {} :Variable))))
(if (. file.definitions ?symbol)
(binding-completions)
(expression-completions))
(when symbol
(if (. file.definitions symbol)
(binding-completions)
(expression-completions)))
(if server.can-do-good-completions?
{:itemDefaults {:editRange range :data {: uri : byte}}

View File

@ -39,7 +39,7 @@
(= e.textEdit.range.end.line c.textEdit.range.end.line)
(= e.textEdit.range.end.character c.textEdit.range.end.character)
(= e.textEdit.newText c.textEdit.newText))
(and (= (type e.textEdit) :function)) (e.textEdit c.textEdit))))
(and (= (type e.textEdit) :function) (e.textEdit c.textEdit)))))
i)))
(fn check [file-contents expected unexpected ?client-opts]
@ -121,8 +121,8 @@
(check "(local x {:field {:deep 100}})\n(if de" [:x.field.deep] [])
(check "(local t {:field (fn [foo] nil)})\n(t|" [:t.field] [])
(check "(local t {:field (fn [self] nil)})\n(t|" [:t:field] [])
(check "(local t {})\n(fn t.field [foo] nil)})\n(t|" [:t.field] [])
(check "(local t {})\n(fn t.field [self] nil)})\n(t|" [:t:field] [])
(check "(local t {})\n(fn t.field [foo] nil)\n(t|" [:t.field] [])
(check "(local t {})\n(fn t.field [self] nil)\n(t|" [:t:field] [])
nil)
(fn test-builtin []
@ -258,13 +258,35 @@
nil)
(fn test-destructure []
;; this is a binding variable, we don't want all the normal completions
(check "(local f|)\n(print foo)"
;; this is in a destructure location, so we don't want all the normal completions
(check "(local |)
(print foo)"
[:foo]
[:setmetatable :_G])
(check "(let [f|]\n(print foo)"
[:math])
(check "(local f|)
(print foo)"
[:foo]
[:setmetatable :_G])
[:math])
(check "(let [f|]
(print foo))"
[:foo]
[:math])
(check "(let [foo |] ; cursor is in an expression so we want expressions now
(print foo))"
[:math]
[])
nil)
(fn test-no-completion []
(check "; ("
[]
[:math])
(check "\" (|\n\""
[]
[:math])
(check "\"\n(|\""
[]
[:math])
nil)
;; ;; Future tests / features
@ -294,4 +316,5 @@
: test-field
: test-docs
: test-module
: test-destructure}
: test-destructure
: test-no-completion}