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) (case (. file.references symbol)
ref ref
(let [stack (fcollect [i (- (length split) 1) 2 -1] (let [stack (fcollect [i (- (length split) 1) 2 -1]
(. split i))] (. split i))
(case (language.search-assignment self file ref stack {}) last-found-binding []]
(case (language.search-assignment self file ref stack {:save-last-binding last-found-binding})
{: definition : file} {: definition : file}
(case (values definition (type definition)) (case (values definition (type definition))
;; fields of a string are hardcoded to "string" ;; fields of a string are hardcoded to "string"
(_str :string) (icollect [label _ (pairs string)] (_str :string) (icollect [label _ (pairs string)]
{: label :kind kinds.Field :textEdit {:newText label}}) {: label :kind kinds.Field :textEdit {:newText label}})
;; fields of a table ;; fields of a table
(tbl :table) (icollect [label _ (pairs tbl)] (tbl :table) (let [keys []]
(if (= (type label) :string) (icollect [label _ (pairs tbl) &into keys]
(case (language.search-ast self file tbl [label] {}) label)
def (formatter.completion-item-format label def) (when (?. last-found-binding 1 :fields)
_ {: label :kind kinds.Field :textEdit {:newText label}})))) (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)))) _ nil))))
(λ requests.textDocument/completion [self send {: position :textDocument {: uri}}] (λ 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 _}` # A definition: `{:definition _ :file _}`
The search succeeded and found a file with a user definition of a value. 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 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. of a true definition. A binding is a place where an identifier gets introduced.
@ -72,6 +72,9 @@ a user-written file.
:keys ?keys :keys ?keys
:multival ?multival :multival ?multival
:fields ?fields}} assignment] :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?) (if (and (= 0 (length stack)) opts.stop-early?)
assignment.target ;; BASE CASE!! assignment.target ;; BASE CASE!!
;; search a virtual field from :fields ;; search a virtual field from :fields

View File

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