fix completions for M style modules

This commit is contained in:
XeroOl 2024-03-01 15:22:32 -06:00
parent 45ab692db4
commit 66bcfc65e5
3 changed files with 26 additions and 16 deletions

View File

@ -156,19 +156,27 @@ Every time the client sends a message, it gets handled by a function in the corr
(case (. file.references symbol)
ref
(let [stack (fcollect [i (- (length split) 1) 2 -1]
(. split i))]
(case (language.search-assignment self file ref stack {})
(. split i))
last-found-binding []]
(case (language.search-assignment self file ref stack {:save-last-binding last-found-binding})
{: definition : file}
(case (values definition (type definition))
;; fields of a string are hardcoded to "string"
(_str :string) (icollect [label _ (pairs string)]
{: label :kind kinds.Field :textEdit {:newText label}})
;; fields of a table
(tbl :table) (icollect [label _ (pairs tbl)]
(if (= (type label) :string)
(case (language.search-ast self file tbl [label] {})
def (formatter.completion-item-format label def)
_ {: label :kind kinds.Field :textEdit {:newText label}}))))
(tbl :table) (let [keys []]
(icollect [label _ (pairs tbl) &into keys]
label)
(when (?. last-found-binding 1 :fields)
(icollect [label _ (pairs (. last-found-binding 1 :fields)) &into keys]
label))
(icollect [_ label (pairs keys)]
(if (= (type label) :string)
(case (language.search-ast self file tbl [label] {})
def (formatter.completion-item-format label def)
_ {: label :kind kinds.Field :textEdit {:newText label}})))))
_ nil))))
(λ requests.textDocument/completion [self send {: position :textDocument {: uri}}]

View File

@ -23,7 +23,7 @@ The search failed, and encountered something that isn't implemented.
# A definition: `{:definition _ :file _}`
The search succeeded and found a file with a user definition of a value.
# A binding: `{:definition _ :file _ :binding _ :multival ?_ :keys ?_ :referenced-by ?_ :var? ?true}`
# A binding: `{:definition _ :file _ :binding _ :multival ?_ :keys ?_ :referenced-by ?_ :var? ?true :fields ?extra_fields}`
If you set the option `opts.stop-early?`, search may stop at a binding instead
of a true definition. A binding is a place where an identifier gets introduced.
@ -72,6 +72,9 @@ a user-written file.
:keys ?keys
:multival ?multival
:fields ?fields}} assignment]
(when (and (= 0 (length stack))
opts.save-last-binding)
(tset opts.save-last-binding 1 assignment.target))
(if (and (= 0 (length stack)) opts.stop-early?)
assignment.target ;; BASE CASE!!
;; search a virtual field from :fields

View File

@ -143,14 +143,13 @@
:fooo.fnl "(fn my-export [x] (print x))
{: my-export :constant 10}"}
[:my-export :constant]
[:_G :local :doto :+]
;; TODO fix completions of virtual fields
; (check
; {:main.fnl "(let [foo (require :fooo)]
; foo.|)))"
; :fooo.fnl "(local M {:constant 10})
; (fn M.my-export [x] (print x))
; M"}
[:_G :local :doto :+])
(check
{:main.fnl "(let [foo (require :fooo)]
foo.|)))"
:fooo.fnl "(local M {:constant 10})
(fn M.my-export [x] (print x))
M"}
[:my-export :constant]
[:_G :local :doto :+]) ;; no globals, specials, macros, or others
(check "(local x {:field (fn [])})\n(x:fi|" [:field] [:table])