horrible messy code that does deeper completions

This commit is contained in:
XeroOl 2025-04-12 14:24:26 -05:00
parent 61defc86c4
commit 5017177b44
2 changed files with 75 additions and 45 deletions

View File

@ -163,25 +163,6 @@ Every time the client sends a message, it gets handled by a function in the corr
symbol)}
(catch _ nil))))
(λ make-completion-item [server file name scope]
(case (analyzer.search-name-and-scope server file name scope)
def (formatter.completion-item-format name def)
_ {:label name}))
;; All of the helper functions for textDocument/completion are here until I
;; finish refactoring them, and then they can find a home in analyzer.fnl
(λ collect-scope [scope typ server file ?target ?default-kind]
(let [result (or ?target [])]
(var scope scope)
(while scope
(icollect [name (pairs (. scope typ)) &into result]
(let [item (make-completion-item server file name scope)]
(when (= nil item.kind)
(set item.kind ?default-kind))
item))
(set scope scope.parent))
result))
;; CompletionItemKind
(local kinds
{:Text 1 :Method 2 :Function 3 :Constructor 4 :Field 5 :Variable 6 :Class 7
@ -189,6 +170,65 @@ Every time the client sends a message, it gets handled by a function in the corr
:Snippet 15 :Color 16 :File 17 :Reference 18 :Folder 19 :EnumMember 20
:Constant 21 :Struct 22 :Event 23 :Operator 24 :TypeParameter 25})
;; All of the helper functions for textDocument/completion are here until I
;; finish refactoring them, and then they can find a home in analyzer.fnl
(λ field-completion-helper [server ?result last-found-binding]
(case ?result
{: definition : file}
(case (values definition (type definition))
;; fields of a string are hardcoded to "string"
(_str :string) (icollect [label info (pairs (. (docs.get-global server :string) :fields))]
(formatter.completion-item-format label info))
;; fields of a table
(where (tbl :table) (fennel.table? tbl)) (let [keys []
result []]
(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) &into result]
(if (= (type label) :string)
(let [last-found-binding []]
(case (analyzer.search-ast server file tbl [label] {:save-last-binding last-found-binding})
def (do
(icollect [_ completion (ipairs (or (field-completion-helper server def last-found-binding) [])) &into result]
(do
(set completion.filterText completion.label)
(set completion.insertText (.. label "." completion.label))
(set completion.label completion.insertText)
completion))
(formatter.completion-item-format label def))
_ {: label :kind kinds.Field}))))
result))
{: metadata : fields}
(let [_metadata metadata]
(icollect [label info (pairs fields)]
(formatter.completion-item-format label info)))
_ nil))
(λ collect-scope [scope typ server file ?target ?default-kind]
(let [result (or ?target [])]
(var scope scope)
(while scope
(icollect [name (pairs (. scope typ)) &into result]
(let [last-found-binding []
item (case (analyzer.search-name-and-scope server file name scope {:save-last-binding last-found-binding})
def (do
(icollect [_ completion (ipairs (or (field-completion-helper server def last-found-binding) [])) &into result]
(do
(set completion.filterText completion.label)
(set completion.insertText (.. name "." completion.label))
(set completion.label completion.insertText)
completion))
(formatter.completion-item-format name def))
_ {:label name})]
(when (= nil item.kind)
(set item.kind ?default-kind))
item))
(set scope scope.parent))
result))
(λ scope-completion [server file _byte ?symbol parents]
(let [scope (or (accumulate [result nil
_ parent (ipairs parents)
@ -205,36 +245,23 @@ Every time the client sends a message, it gets handled by a function in the corr
(collect-scope scope :macros server file result kinds.Keyword)
(collect-scope scope :specials server file result kinds.Operator))
(icollect [_ k (ipairs file.allowed-globals) &into result]
(make-completion-item server file k scope))))
(let [last-found-binding []]
(case (analyzer.search-name-and-scope server file k scope {:save-last-binding last-found-binding})
def (do (icollect [_ completion (ipairs (or (field-completion-helper server def last-found-binding) [])) &into result]
(do
(set completion.filterText completion.label)
(set completion.insertText (.. k "." completion.label))
(set completion.label completion.insertText)
completion))
(formatter.completion-item-format k def))
_ {:label k})))))
(λ field-completion [server file symbol split]
(let [stack (fcollect [i (- (length split) 1) 2 -1]
(. split i))
last-found-binding []
result (analyzer.search-main server file symbol {:save-last-binding last-found-binding} {: stack})]
(case result
{: definition : file}
(case (values definition (type definition))
;; fields of a string are hardcoded to "string"
(_str :string) (icollect [label info (pairs (. (docs.get-global server :string) :fields))]
(formatter.completion-item-format label info))
;; fields of a table
(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 (analyzer.search-ast server file tbl [label] {})
def (formatter.completion-item-format label def)
_ {: label :kind kinds.Field})))))
{: metadata : fields}
(let [_metadata metadata]
(icollect [label info (pairs fields)]
(formatter.completion-item-format label info)))
_ nil)))
(field-completion-helper server result last-found-binding)))
(λ requests.textDocument/completion [server _send {: position :textDocument {: uri}}]
(let [file (files.get-by-uri server uri)
@ -266,8 +293,6 @@ Every time the client sends a message, it gets handled by a function in the corr
(set completion.textEdit {:newText completion.label :range input-range}))))
?completions))))
(λ requests.textDocument/rename [server _send {: position :textDocument {: uri} :newName new-name}]
(let [file (files.get-by-uri server uri)
byte (utils.position->byte file.text position server.position-encoding)]

View File

@ -77,6 +77,8 @@
(check "#nil\n(" [:_G :debug :table :io :getmetatable :setmetatable
:_VERSION :ipairs :pairs :next] [])
(check "(if ge" [:getmetatable] [])
(check "(table.i" [:insert] [])
(check "(ins" [:table.insert] [])
nil)
(fn test-local []
@ -114,6 +116,9 @@
(+ number-of-x 1)
number-of-x))))
[])
;; stretchy completions
(check "(local x {:field 100})\n(if fi" [:x.field] [])
(check "(local x {:field {:deep 100}})\n(if de" [:x.field.deep] [])
nil)
(fn test-builtin []