better completions in destructure bindings
This commit is contained in:
parent
b7e497228f
commit
28e20f74cb
@ -293,7 +293,16 @@ identifiers are declared / referenced in which places."
|
||||
(let [old (tostring ?ast)]
|
||||
(tset ?ast 1 "!!invalid-multi-symbol!!")
|
||||
(table.insert defer #(tset ?ast 1 old))
|
||||
true))))
|
||||
true))
|
||||
(when (and (= 1 (msg:find "expected name and value"))
|
||||
(list? ?ast))
|
||||
(when (= 1 (length ?ast))
|
||||
(table.insert ?ast (sym "_"))
|
||||
(table.insert defer #(table.remove ?ast)))
|
||||
(when (= 2 (length ?ast))
|
||||
(table.insert ?ast nil*)
|
||||
(table.insert defer #(table.remove ?ast)))
|
||||
(= 3 (length ?ast)))))
|
||||
|
||||
(λ on-compile-error [_ msg ast call-me-to-reset-the-compiler]
|
||||
(let [range (or (message.ast->range server file ast)
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
"add the completion. also recursively adds the fields' completions"
|
||||
(when (not (. seen definition))
|
||||
(set (. seen definition) true)
|
||||
(add-completion! name definition)
|
||||
(add-completion! name definition "Value")
|
||||
(each [field def ?string-method (navigate.iter-fields server definition)]
|
||||
(if (or (= :self (tostring (?. def :metadata :fnl/arglist 1)))
|
||||
?string-method
|
||||
@ -56,62 +56,77 @@
|
||||
(add-completion-recursively! (.. name "." field) def)))
|
||||
(set (. seen definition) false)))
|
||||
|
||||
(each [name documentation (pairs hardcoded-completions)]
|
||||
(add-completion! name documentation))
|
||||
(fn expression-completions []
|
||||
(each [name documentation (pairs hardcoded-completions)]
|
||||
(add-completion! name documentation))
|
||||
|
||||
(local seen-manglings {})
|
||||
(local seen-manglings {})
|
||||
|
||||
(each [_ global* (ipairs file.allowed-globals)]
|
||||
(when (not (. seen-manglings global*))
|
||||
(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[:.]")))
|
||||
(add-completion! global* def)
|
||||
(add-completion-recursively! global* def))
|
||||
_ (do
|
||||
(io.stderr:write "BAD!!!! undocumented global: " (tostring global*) "\n")
|
||||
(add-completion! global* {})))))
|
||||
(each [_ global* (ipairs file.allowed-globals)]
|
||||
(when (not (. seen-manglings global*))
|
||||
(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[:.]")))
|
||||
(add-completion! global* def)
|
||||
(add-completion-recursively! global* def))
|
||||
_ (do
|
||||
(io.stderr:write "BAD!!!! undocumented global: " (tostring global*) "\n")
|
||||
(add-completion! global* {})))))
|
||||
|
||||
(var scope scope)
|
||||
(while scope
|
||||
(each [mangling (pairs scope.manglings)]
|
||||
(when (not (. seen-manglings mangling))
|
||||
(set (. seen-manglings mangling) true)
|
||||
(case (analyzer.search-name-and-scope server file mangling scope)
|
||||
def (add-completion-recursively! mangling def)
|
||||
_ (add-completion-recursively! mangling {}))))
|
||||
|
||||
(when in-call-position?
|
||||
(each [macro* macro-value (pairs scope.macros)]
|
||||
(add-completion! macro*
|
||||
{:binding macro*
|
||||
:metadata (. METADATA macro-value)}
|
||||
:Keyword))
|
||||
|
||||
(each [special (pairs scope.specials)]
|
||||
(case (analyzer.search-name-and-scope server file special scope)
|
||||
def (add-completion! special def :Operator)
|
||||
_ (do
|
||||
(io.stderr:write "BAD!!!! undocumented special: " (tostring special) "\n")
|
||||
{:label special}))))
|
||||
(set scope scope.parent)))
|
||||
|
||||
(fn binding-completions []
|
||||
"completions when you're writing a destructure pattern. We suggest identifiers which are unknown"
|
||||
(each [_ {: message} (ipairs file.diagnostics)]
|
||||
(case (message:match "unknown identifier: ([a-zA-Z0-9_-]+)")
|
||||
identifier (add-completion! identifier {} :Variable))))
|
||||
|
||||
(if (. file.definitions ?symbol)
|
||||
(binding-completions)
|
||||
(expression-completions))
|
||||
|
||||
|
||||
(var scope scope)
|
||||
(while scope
|
||||
(each [mangling (pairs scope.manglings)]
|
||||
(when (not (. seen-manglings mangling))
|
||||
(set (. seen-manglings mangling) true)
|
||||
(case (analyzer.search-name-and-scope server file mangling scope)
|
||||
def (add-completion-recursively! mangling def)
|
||||
_ (add-completion-recursively! mangling {}))))
|
||||
|
||||
(when in-call-position?
|
||||
(each [macro* macro-value (pairs scope.macros)]
|
||||
(add-completion! macro*
|
||||
{:binding macro*
|
||||
:metadata (. METADATA macro-value)}
|
||||
:Keyword))
|
||||
|
||||
(each [special (pairs scope.specials)]
|
||||
(case (analyzer.search-name-and-scope server file special scope)
|
||||
def (add-completion! special def :Operator)
|
||||
_ (do
|
||||
(io.stderr:write "BAD!!!! undocumented special: " (tostring special) "\n")
|
||||
{:label special}))))
|
||||
(set scope scope.parent))
|
||||
(if server.can-do-good-completions?
|
||||
{:itemDefaults {:editRange range :data {: uri : byte}}
|
||||
:items results}
|
||||
results)))
|
||||
|
||||
(fn completionItem/resolve [server _send completion-item]
|
||||
(or (. hardcoded-completions completion-item.label)
|
||||
(let [{: uri : byte} completion-item.data
|
||||
file (files.get-by-uri server uri)
|
||||
(_symbol parents) (analyzer.find-symbol file.ast byte)
|
||||
scope (or (accumulate [?find nil _ parent (ipairs parents) &until ?find]
|
||||
(. file.scopes parent))
|
||||
file.scope)]
|
||||
(case (analyzer.search-name-and-scope server file completion-item.label scope)
|
||||
result (doto completion-item (tset :documentation (format.hover-format server completion-item.label result)))))))
|
||||
(let [result
|
||||
(or (. hardcoded-completions completion-item.name)
|
||||
(let [{: uri : byte} completion-item.data
|
||||
file (files.get-by-uri server uri)
|
||||
(_symbol parents) (analyzer.find-symbol file.ast byte)
|
||||
scope (or (accumulate [?find nil _ parent (ipairs parents) &until ?find]
|
||||
(. file.scopes parent))
|
||||
file.scope)]
|
||||
(analyzer.search-name-and-scope server file completion-item.label scope)))]
|
||||
(when result
|
||||
(set completion-item.documentation (format.hover-format server completion-item.label result)))
|
||||
completion-item))
|
||||
|
||||
{: textDocument/completion
|
||||
: completionItem/resolve}
|
||||
|
||||
@ -193,12 +193,13 @@ fntype is one of fn or λ or lambda"
|
||||
{:label name
|
||||
:documentation (when (not server.can-do-good-completions?) (hover-format server name definition))
|
||||
:textEdit (when (not server.can-do-good-completions?) {:newText name : range})
|
||||
:kind (or (?. kinds ?kind)
|
||||
:kind (or (if (not= ?kind :Value) (?. kinds ?kind))
|
||||
(case (navigate.getmetadata server definition)
|
||||
metadata
|
||||
(or (?. kinds metadata.fls/itemKind)
|
||||
(when metadata.fnl/arglist
|
||||
(if (name:find ":") kinds.Method kinds.Function))))
|
||||
(?. kinds ?kind)
|
||||
kinds.Text)})
|
||||
|
||||
{: signature-help-format
|
||||
|
||||
@ -164,7 +164,8 @@
|
||||
(check "(local x {:field (fn [self])})\n(x::f" [] [])
|
||||
(check
|
||||
"(let [my-table {:foo 10 :bar 20}]\n my-table.|)))"
|
||||
[:my-table.foo :my-table.bar]
|
||||
[{:label :my-table.foo :kind kinds.Value}
|
||||
{:label :my-table.bar :kind kinds.Value}]
|
||||
[])
|
||||
(check
|
||||
{:main.fnl "(let [foo (require :fooo)]
|
||||
@ -256,6 +257,15 @@
|
||||
[])
|
||||
nil)
|
||||
|
||||
(fn test-destructure []
|
||||
;; this is a binding variable, we don't want all the normal completions
|
||||
(check "(local f|)\n(print foo)"
|
||||
[:foo]
|
||||
[:setmetatable :_G])
|
||||
(check "(let [f|]\n(print foo)"
|
||||
[:foo]
|
||||
[:setmetatable :_G])
|
||||
nil)
|
||||
|
||||
;; ;; Future tests / features
|
||||
;; ;; Scope Ordering Rules
|
||||
@ -283,4 +293,5 @@
|
||||
: test-fn-arg
|
||||
: test-field
|
||||
: test-docs
|
||||
: test-module}
|
||||
: test-module
|
||||
: test-destructure}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user