simplify completions

This commit is contained in:
XeroOl 2025-07-02 19:11:10 -05:00
parent ad136b00ec
commit 0641b1b098
4 changed files with 31 additions and 47 deletions

View File

@ -77,18 +77,18 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
"searches for the definition of the ast, adjusted to 1 value"
(search-multival server file ?ast stack 1 opts))
(λ search-assignment [server file assignment stack opts]
(let [{:target {:binding _
:definition ?definition
:keys ?keys
:multival ?multival
:fields ?fields}} assignment]
(λ search-definition [server file definition stack opts]
(let [{:binding _
:definition ?definition
:keys ?keys
:multival ?multival
:fields ?fields} definition]
(if (and (= 0 (length stack)) opts.stop-early?)
assignment.target ;; BASE CASE!!
definition ;; BASE CASE!!
;; :fields
(and (not= 0 (length stack)) (?. ?fields (. stack (length stack))))
(search-assignment server file {:target (. ?fields (table.remove stack))} stack opts)
(search-definition server file (. ?fields (table.remove stack)) stack opts)
;; This case is hard to explain.
;; Under these conditions, search-multival is planning on returning {:definition ?definition : file}
@ -101,7 +101,7 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
(= 1 (or 1 ?multival))
(not (sym? ?definition))
(= 0 (length stack)))
assignment.target
definition
(search-multival server file ?definition (stack-add-keys! stack ?keys) (or ?multival 1) opts))))
@ -109,7 +109,7 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
(if ref.target.metadata
(search-document server ref.target stack opts)
ref.target.binding
(search-assignment server file ref stack opts)))
(search-definition server file ref.target stack opts)))
(λ search-symbol [server file symbol stack opts]
(if (= (tostring symbol) :nil)
@ -237,7 +237,7 @@ initialization-opts: {:stack ?list[ast]
(case (docs.get-builtin server base-name)
metadata (search-document server metadata stack opts)
_ (case (find-local-definition file base-name scope)
def (search-val server file def.definition (stack-add-keys! stack def.keys) opts)
def (search-definition server file def [] opts)
_ (case (docs.get-global server base-name)
metadata (search-document server metadata stack opts))))))
@ -328,13 +328,11 @@ returns the called symbol and the number of the argument closest to byte"
(catch _ nil)))
(λ find-definition [server file symbol ?byte]
(if (. file.definitions symbol)
(. file.definitions symbol)
(or (. file.definitions symbol)
(search server file symbol {:stop-early? false} {:byte ?byte})))
(λ find-nearest-definition [server file symbol ?byte]
(if (. file.definitions symbol)
(. file.definitions symbol)
(or (. file.definitions symbol)
(search server file symbol {:stop-early? true} {:byte ?byte})))
{: find-symbol

View File

@ -65,9 +65,6 @@ identifiers are declared / referenced in which places."
(λ line+byte->range [server file line byte]
(let [line (- line 1)
;; some errors in fennel erroneously say column -1
;; try compiling "(do\n" to see what I mean
byte (math.max 0 byte)
position (utils.pos->position file.text line byte server.position-encoding)]
{:start position :end position}))

View File

@ -1,10 +1,10 @@
(local files (require :fennel-ls.files))
(local utils (require :fennel-ls.utils))
(local analyzer (require :fennel-ls.analyzer))
(local docs (require :fennel-ls.docs))
(local fennel (require :fennel))
(local message (require :fennel-ls.message))
(local format (require :fennel-ls.formatter))
(local navigate (require :fennel-ls.navigate))
(local {:metadata METADATA} (require :fennel.compiler))
(λ textDocument/completion [server _send {: position :textDocument {: uri}}]
@ -30,37 +30,22 @@
(fn add-completion-recursively! [name definition]
"add the completion. also recursively adds the fields' completions"
(fn add-field-recursively! [field def]
"TODO name this thing"
(if (or (= :self (tostring (?. def :metadata :fnl/arglist 1)))
(and (fennel.list? def.definition)
(or (and (fennel.sym? (. def.definition 1) "fn")
(fennel.sym? (?. def.definition 2 1) "self"))
(and (fennel.sym? (. def.definition 1) "λ")
(fennel.sym? (?. def.definition 2 1) "self")))))
(add-completion-recursively! (.. name ":" field) def)
(add-completion-recursively! (.. name "." field) def)))
(when (not (. seen definition))
(set (. seen definition) true)
(add-completion! name definition)
(when (= (type definition.definition) :string)
(each [key value (pairs (-> (docs.get-global server :string) (. :fields)))]
(add-completion-recursively! (.. name ":" key) value)))
(when (fennel.table? definition.definition)
(each [field value (pairs definition.definition)]
(when (= (type field) :string)
(case (analyzer.search server definition.file value {} {})
def (add-field-recursively! field def)
_ (do
(io.stderr:write "BAD!!!! undocumented field: " (tostring field) "\n")
{:label field})))))
(when definition.fields
(each [field def (pairs definition.fields)]
(when (= (type field) :string)
(add-field-recursively! field def))))
(each [field def ?string-method (navigate.iter-fields server definition)]
(if (or (= :self (tostring (?. def :metadata :fnl/arglist 1)))
?string-method
(and (fennel.list? def.definition)
(or (fennel.sym? (. def.definition 1) "fn")
(fennel.sym? (. def.definition 1) "λ"))
(or (and (fennel.table? (. def.definition 2))
(fennel.sym? (. def.definition 2 1) "self"))
(and (fennel.sym? (. def.definition 2))
(fennel.table? (. def.definition 3))
(fennel.sym? (?. def.definition 3 1) "self")))))
(add-completion-recursively! (.. name ":" field) def)
(add-completion-recursively! (.. name "." field) def)))
(set (. seen definition) false)))
(local seen-manglings {})

View File

@ -119,6 +119,10 @@
;; stretchy completions
(check "(local x {:field 100})\n(if fi" [:x.field] [])
(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] [])
nil)
(fn test-builtin []