From 364d02b90de6e41c40fc31a19665cad20041c63a Mon Sep 17 00:00:00 2001 From: XeroOl Date: Sun, 3 Sep 2023 10:23:33 -0500 Subject: [PATCH] Better completions for fields of tables Now it does a two-level-deep search when creating competions for tables, which means that a completion for module fields have better metadata. the completion code is a bit of a mess, so I want to look into refactoring it soon. --- src/fennel-ls/handlers.fnl | 14 ++++++++------ src/fennel-ls/language.fnl | 2 +- test/completion-test.fnl | 36 ++++++++++++++++++------------------ 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/fennel-ls/handlers.fnl b/src/fennel-ls/handlers.fnl index 5a56e0d..1e55e33 100644 --- a/src/fennel-ls/handlers.fnl +++ b/src/fennel-ls/handlers.fnl @@ -157,13 +157,15 @@ Every time the client sends a message, it gets handled by a function in the corr (let [stack (fcollect [i (- (length split) 1) 2 -1] (. split i))] (case (language.search-assignment self file ref stack {}) - {: definition} + ({: definition} file) (case (values definition (type definition)) - (_str :string) (icollect [k _ (pairs string)] - {:label k :kind kinds.Field}) - (tbl :table) (icollect [k _ (pairs tbl)] - (if (= (type k) :string) - {:label k :kind kinds.Field}))) + (_str :string) (icollect [label _ (pairs string)] + {: label :kind kinds.Field}) + (tbl :table) (icollect [label _ (pairs tbl)] + (if (= (type label) :string) + (case (language.search self file tbl [label] {}) + def (formatter.completion-item-format label def) + _ {: label :kind kinds.Field})))) _ nil)))) (λ create-completion-item [self file name scope] diff --git a/src/fennel-ls/language.fnl b/src/fennel-ls/language.fnl index 13beac2..ce03858 100644 --- a/src/fennel-ls/language.fnl +++ b/src/fennel-ls/language.fnl @@ -98,7 +98,7 @@ the data provided by compiler.fnl." (sym? item) (search-symbol self file item stack opts) (list? item) (search-list self file item stack opts) (= :table (type item)) (search-table self file item stack opts) - (= 0 (length stack)) {:definition item}))) ;; BASE CASE !! + (= 0 (length stack)) (values {:definition item} file)))) ;; BASE CASE !! ;; (error (.. "I don't know what to do with " (view item)))))) (local {:metadata METADATA diff --git a/test/completion-test.fnl b/test/completion-test.fnl index 63d7139..a042ead 100644 --- a/test/completion-test.fnl +++ b/test/completion-test.fnl @@ -192,25 +192,25 @@ (is.same (type completion.label) :string "unlabeled completion") (is.same (type completion.kind) :number (.. completion.label " needs a kind")) (is.same (type completion.documentation) :table (.. completion.label " needs documentation")) - (is.not.same completion.documentation :nil (.. completion.label " needs documentation")))))))) + (is.not.same completion.documentation :nil (.. completion.label " needs documentation")))))) - ; (it "offers rich information about fields" - ; (let [client (doto (create-client) - ; (: :open-file! filename "(let [x (fn x [a b c] \"\"\"docstring\"\"\" nil)\n t {: x}]\n (t.")) - ; [{:result completions}] (client:completion filename 2 5) - ; _ (table.sort completions #(< $1.label $2.label)) - ; missing-docs (icollect [_ completion (ipairs completions)] - ; (if (not (and (= (type completion.label) :string) - ; (= (type completion.kind) :number) - ; (= (type completion.documentation) :table))) - ; completion.label)) - ; allowed-missing-docs {}] - ; (each [_ completion (ipairs completions)] - ; (when (not (. allowed-missing-docs completion.label)) - ; (is.same (type completion.label) :string "unlabeled completion") - ; (is.same (type completion.kind) :number (.. completion.label " needs a kind")) - ; (is.same (type completion.documentation) :table (.. completion.label " needs documentation")) - ; (is.not.same completion.documentation :nil (.. completion.label " needs documentation")))))))) + (it "offers rich information about fields" + (let [client (doto (create-client) + (: :open-file! filename "(let [x (fn x [a b c] \"\"\"docstring\"\"\" nil)\n t {: x}]\n (t.")) + [{:result completions}] (client:completion filename 2 5) + _ (table.sort completions #(< $1.label $2.label)) + missing-docs (icollect [_ completion (ipairs completions)] + (if (not (and (= (type completion.label) :string) + (= (type completion.kind) :number) + (= (type completion.documentation) :table))) + completion.label)) + allowed-missing-docs {}] + (each [_ completion (ipairs completions)] + (when (not (. allowed-missing-docs completion.label)) + (is.same (type completion.label) :string "unlabeled completion") + (is.same (type completion.kind) :number (.. completion.label " needs a kind")) + (is.same (type completion.documentation) :table (.. completion.label " needs documentation")) + (is.not.same completion.documentation :nil (.. completion.label " needs documentation"))))))))