From 5bb3f760507cbd1eb2de890493af8c1fa1ccb2f2 Mon Sep 17 00:00:00 2001 From: XeroOl Date: Wed, 23 Apr 2025 23:32:17 -0500 Subject: [PATCH] fix documentation for macros, and fix completion item kind --- src/fennel-ls/completions.fnl | 78 ++++++++++++++++------------------- src/fennel-ls/formatter.fnl | 18 ++++---- test/completion.fnl | 30 ++++++++------ 3 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/fennel-ls/completions.fnl b/src/fennel-ls/completions.fnl index 70ad4aa..1f2e5a7 100644 --- a/src/fennel-ls/completions.fnl +++ b/src/fennel-ls/completions.fnl @@ -5,13 +5,7 @@ (local fennel (require :fennel)) (local message (require :fennel-ls.message)) (local format (require :fennel-ls.formatter)) - -;; CompletionItemKind -(local _kinds - {:Text 1 :Method 2 :Function 3 :Constructor 4 :Field 5 :Variable 6 :Class 7 - :Interface 8 :Module 9 :Property 10 :Unit 11 :Value 12 :Enum 13 :Keyword 14 - :Snippet 15 :Color 16 :File 17 :Reference 18 :Folder 19 :EnumMember 20 - :Constant 21 :Struct 22 :Event 23 :Operator 24 :TypeParameter 25}) +(local {:metadata METADATA} (require :fennel.compiler)) (λ textDocument/completion [server _send {: position :textDocument {: uri}}] ;; get the file @@ -31,51 +25,46 @@ results [] seen {}] - (fn add-completion [definition name] - (table.insert results - (doto (format.completion-item-format name definition) - (tset :filterText name) - (tset :textEdit {:newText name : range})))) + (fn add-completion! [name definition ?kind] + (table.insert results (format.completion-item-format name definition range ?kind))) - (fn add-completion-recursively [definition name] + (fn add-completion-recursively! [name definition] "add the completion. also recursively adds the fields' completions" + + (fn thing [field def] + "TODO name this thing" + (if (or (= :self (tostring (?. def :metadata :fnl/arglist 1))) + (and (fennel.list? def.definition) + (or (and (fennel.sym? (. def.definition 1) "fn") + (fennel.sym? (?. def.definition 2 1) "self")) + (and (fennel.sym? (. def.definition 1) "λ") + (fennel.sym? (?. def.definition 2 1) "self"))))) + (add-completion-recursively! (.. name ":" field) def) + (add-completion-recursively! (.. name "." field) def))) + (when (not (. seen definition)) (set (. seen definition) true) - (add-completion definition name) + (add-completion! name definition) (when (= (type definition.definition) :string) (each [key value (pairs (-> (docs.get-global server :string) (. :fields)))] - (add-completion-recursively value (.. name ":" key)))) + (add-completion-recursively! (.. name ":" key) value))) (when (fennel.table? definition.definition) (each [field value (pairs definition.definition)] (when (= (type field) :string) (case (analyzer.search-ast server definition.file value [] {}) - def (if (or (= :self (tostring (?. def :metadata :fnl/arglist 1))) - (and (fennel.list? def.definition) - ;; TODO check that arg is called `self` - (or (and (fennel.sym? (. def.definition 1) "fn") - (fennel.sym? (?. def.definition 2 1) "self")) - (and (fennel.sym? (. def.definition 1) "λ") - (fennel.sym? (?. def.definition 2 1) "self"))))) - (add-completion-recursively def (.. name ":" field)) - (add-completion-recursively def (.. name "." field))) + ;; TODO deduplicate code! copy 1 + def (thing field def) _ (do (io.stderr:write "BAD!!!! undocumented field: " (tostring field) "\n") {:label field}))))) (when definition.fields - (each [field value (pairs definition.fields)] + (each [field def (pairs definition.fields)] (when (= (type field) :string) - (if (or (= :self (tostring (?. value :metadata :fnl/arglist 1))) - (and (fennel.list? value.definition) - ;; TODO check that arg is called `self` - (or (and (fennel.sym? (. value.definition 1) "fn") - (fennel.sym? (?. value.definition 2 1) "self")) - (and (fennel.sym? (. value.definition 1) "λ") - (fennel.sym? (?. value.definition 2 1) "self"))))) - (add-completion-recursively value (.. name ":" field)) - (add-completion-recursively value (.. name "." field)))))) + ;; TODO deduplicate code! copy 2 + (thing field def)))) (set (. seen definition) false))) - ;; end yield + ;; endfn add-completion-recursively (local seen-manglings {}) @@ -85,11 +74,11 @@ (case (analyzer.search-name-and-scope server file global* scope) def (if (and (= :_G (tostring global*)) (not (: (tostring ?symbol) :match "_G[:.]"))) - (add-completion def global*) - (add-completion-recursively def global*)) + (add-completion! global* def) + (add-completion-recursively! global* def)) _ (do (io.stderr:write "BAD!!!! undocumented global: " (tostring global*) "\n") - {:label global*})))) + (add-completion! global* {}))))) (var scope scope) @@ -98,16 +87,19 @@ (when (not (. seen-manglings mangling)) (set (. seen-manglings mangling) true) (case (analyzer.search-name-and-scope server file mangling scope) - def (add-completion-recursively def mangling) - _ (add-completion-recursively {} mangling)))) + def (add-completion-recursively! mangling def) + _ (add-completion-recursively! mangling {})))) (when in-call-position? - (each [macro* (pairs scope.macros)] - (table.insert results {:label macro* :filterText macro* :textEdit {:newText macro* : range}})) + (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-recursively def special) + def (add-completion! special def :Operator) _ (do (io.stderr:write "BAD!!!! undocumented special: " (tostring special) "\n") {:label special})))) diff --git a/src/fennel-ls/formatter.fnl b/src/fennel-ls/formatter.fnl index b06058f..430bd5b 100644 --- a/src/fennel-ls/formatter.fnl +++ b/src/fennel-ls/formatter.fnl @@ -172,15 +172,17 @@ fntype is one of fn or λ or lambda" :Snippet 15 :Color 16 :File 17 :Reference 18 :Folder 19 :EnumMember 20 :Constant 21 :Struct 22 :Event 23 :Operator 24 :TypeParameter 25}) -(λ completion-item-format [label result] +(λ completion-item-format [name definition range ?kind] "Makes a completion item" - (doto - (case (analyze-fn result.definition) - {:fntype _} {: label - :kind (if (label:find ":") kinds.Method kinds.Function)} - _ {: label - :kind (. kinds (?. result :metadata :fls/itemKind))}) - (tset :documentation (hover-format result)))) + {:label name + :documentation (hover-format definition) + :filterText name + :textEdit {:newText name : range} + :kind (or (if ?kind (. kinds ?kind)) + (. kinds (?. definition :metadata :fls/itemKind)) + (if (or (?. definition :metadata :fnl/arglist) + (?. (analyze-fn definition.definition)) :fntype) + (if (name:find ":") kinds.Method kinds.Function)))}) {: signature-help-format : hover-format diff --git a/test/completion.fnl b/test/completion.fnl index dd56ca0..da97d02 100644 --- a/test/completion.fnl +++ b/test/completion.fnl @@ -199,6 +199,13 @@ ;; builtin macros {:label :-?> :kind kinds.Keyword + :documentation true} + ;; builtin globals + {:label :table + :kind kinds.Module + :documentation true} + {:label :_G + :kind kinds.Variable :documentation true}] [{:documentation #(= nil $) :label #(not (. things-that-are-allowed-to-have-missing-docs $))} {:kind #(= nil $) :label #(not (. things-that-are-allowed-to-have-missing-docs $))} @@ -210,26 +217,25 @@ t {: x}] (t." [:x] - [:_G - {:documentation #(= nil $)} + [{:documentation #(= nil $)} {:kind #(= nil $)} {:label #(= nil $)}]) (check "(let [x :hi] - (x.|))" - [:gsub - :gmatch - :match - :sub - :len - :find] + (x:|))" + [:x:gsub + :x:match + :x:match + :x:sub + :x:len + :x:find] [{:documentation #(= nil $)}]) nil) (fn test-module [] (check "(coroutine.y|" - [{:label "yield" + [{:label "coroutine.yield" :documentation #(and $.value ($.value:find "```fnl\n(coroutine.yield ...)\n```" 1 true))}] [{:documentation #(= nil $)}]) (check "(local c coroutine) @@ -238,10 +244,10 @@ [{:documentation #(= nil $)}]) (check "(local t table) (t.i" - ["insert"] + ["table.insert" "t.insert"] [{:documentation #(= nil $)}]) (check "debug.deb|" - [{:label "debug" + [{:label "debug.debug" :documentation #(and $.value ($.value:find "```fnl\n(debug.debug)\n```" 1 true))}] []) nil)