fix documentation for macros, and fix completion item kind
This commit is contained in:
parent
3f1c2ea361
commit
5bb3f76050
@ -5,13 +5,7 @@
|
|||||||
(local fennel (require :fennel))
|
(local fennel (require :fennel))
|
||||||
(local message (require :fennel-ls.message))
|
(local message (require :fennel-ls.message))
|
||||||
(local format (require :fennel-ls.formatter))
|
(local format (require :fennel-ls.formatter))
|
||||||
|
(local {:metadata METADATA} (require :fennel.compiler))
|
||||||
;; 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})
|
|
||||||
|
|
||||||
(λ textDocument/completion [server _send {: position :textDocument {: uri}}]
|
(λ textDocument/completion [server _send {: position :textDocument {: uri}}]
|
||||||
;; get the file
|
;; get the file
|
||||||
@ -31,51 +25,46 @@
|
|||||||
results []
|
results []
|
||||||
seen {}]
|
seen {}]
|
||||||
|
|
||||||
(fn add-completion [definition name]
|
(fn add-completion! [name definition ?kind]
|
||||||
(table.insert results
|
(table.insert results (format.completion-item-format name definition range ?kind)))
|
||||||
(doto (format.completion-item-format name definition)
|
|
||||||
(tset :filterText name)
|
|
||||||
(tset :textEdit {:newText name : range}))))
|
|
||||||
|
|
||||||
(fn add-completion-recursively [definition name]
|
(fn add-completion-recursively! [name definition]
|
||||||
"add the completion. also recursively adds the fields' completions"
|
"add the completion. also recursively adds the fields' completions"
|
||||||
(when (not (. seen definition))
|
|
||||||
(set (. seen definition) true)
|
(fn thing [field def]
|
||||||
(add-completion definition name)
|
"TODO name this thing"
|
||||||
(when (= (type definition.definition) :string)
|
(if (or (= :self (tostring (?. def :metadata :fnl/arglist 1)))
|
||||||
(each [key value (pairs (-> (docs.get-global server :string) (. :fields)))]
|
|
||||||
(add-completion-recursively value (.. name ":" key))))
|
|
||||||
(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)
|
(and (fennel.list? def.definition)
|
||||||
;; TODO check that arg is called `self`
|
|
||||||
(or (and (fennel.sym? (. def.definition 1) "fn")
|
(or (and (fennel.sym? (. def.definition 1) "fn")
|
||||||
(fennel.sym? (?. def.definition 2 1) "self"))
|
(fennel.sym? (?. def.definition 2 1) "self"))
|
||||||
(and (fennel.sym? (. def.definition 1) "λ")
|
(and (fennel.sym? (. def.definition 1) "λ")
|
||||||
(fennel.sym? (?. def.definition 2 1) "self")))))
|
(fennel.sym? (?. def.definition 2 1) "self")))))
|
||||||
(add-completion-recursively def (.. name ":" field))
|
(add-completion-recursively! (.. name ":" field) def)
|
||||||
(add-completion-recursively def (.. name "." field)))
|
(add-completion-recursively! (.. name "." field) def)))
|
||||||
|
|
||||||
|
(when (not (. seen definition))
|
||||||
|
(set (. seen definition) true)
|
||||||
|
(add-completion! name definition)
|
||||||
|
(when (= (type definition.definition) :string)
|
||||||
|
(each [key value (pairs (-> (docs.get-global server :string) (. :fields)))]
|
||||||
|
(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 [] {})
|
||||||
|
;; TODO deduplicate code! copy 1
|
||||||
|
def (thing field def)
|
||||||
_ (do
|
_ (do
|
||||||
(io.stderr:write "BAD!!!! undocumented field: " (tostring field) "\n")
|
(io.stderr:write "BAD!!!! undocumented field: " (tostring field) "\n")
|
||||||
{:label field})))))
|
{:label field})))))
|
||||||
(when definition.fields
|
(when definition.fields
|
||||||
(each [field value (pairs definition.fields)]
|
(each [field def (pairs definition.fields)]
|
||||||
(when (= (type field) :string)
|
(when (= (type field) :string)
|
||||||
(if (or (= :self (tostring (?. value :metadata :fnl/arglist 1)))
|
;; TODO deduplicate code! copy 2
|
||||||
(and (fennel.list? value.definition)
|
(thing field def))))
|
||||||
;; 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))))))
|
|
||||||
|
|
||||||
(set (. seen definition) false)))
|
(set (. seen definition) false)))
|
||||||
;; end yield
|
;; endfn add-completion-recursively
|
||||||
|
|
||||||
(local seen-manglings {})
|
(local seen-manglings {})
|
||||||
|
|
||||||
@ -85,11 +74,11 @@
|
|||||||
(case (analyzer.search-name-and-scope server file global* scope)
|
(case (analyzer.search-name-and-scope server file global* scope)
|
||||||
def (if (and (= :_G (tostring global*))
|
def (if (and (= :_G (tostring global*))
|
||||||
(not (: (tostring ?symbol) :match "_G[:.]")))
|
(not (: (tostring ?symbol) :match "_G[:.]")))
|
||||||
(add-completion def global*)
|
(add-completion! global* def)
|
||||||
(add-completion-recursively def global*))
|
(add-completion-recursively! global* def))
|
||||||
_ (do
|
_ (do
|
||||||
(io.stderr:write "BAD!!!! undocumented global: " (tostring global*) "\n")
|
(io.stderr:write "BAD!!!! undocumented global: " (tostring global*) "\n")
|
||||||
{:label global*}))))
|
(add-completion! global* {})))))
|
||||||
|
|
||||||
|
|
||||||
(var scope scope)
|
(var scope scope)
|
||||||
@ -98,16 +87,19 @@
|
|||||||
(when (not (. seen-manglings mangling))
|
(when (not (. seen-manglings mangling))
|
||||||
(set (. seen-manglings mangling) true)
|
(set (. seen-manglings mangling) true)
|
||||||
(case (analyzer.search-name-and-scope server file mangling scope)
|
(case (analyzer.search-name-and-scope server file mangling scope)
|
||||||
def (add-completion-recursively def mangling)
|
def (add-completion-recursively! mangling def)
|
||||||
_ (add-completion-recursively {} mangling))))
|
_ (add-completion-recursively! mangling {}))))
|
||||||
|
|
||||||
(when in-call-position?
|
(when in-call-position?
|
||||||
(each [macro* (pairs scope.macros)]
|
(each [macro* macro-value (pairs scope.macros)]
|
||||||
(table.insert results {:label macro* :filterText macro* :textEdit {:newText macro* : range}}))
|
(add-completion! macro*
|
||||||
|
{:binding macro*
|
||||||
|
:metadata (. METADATA macro-value)}
|
||||||
|
:Keyword))
|
||||||
|
|
||||||
(each [special (pairs scope.specials)]
|
(each [special (pairs scope.specials)]
|
||||||
(case (analyzer.search-name-and-scope server file special scope)
|
(case (analyzer.search-name-and-scope server file special scope)
|
||||||
def (add-completion-recursively def special)
|
def (add-completion! special def :Operator)
|
||||||
_ (do
|
_ (do
|
||||||
(io.stderr:write "BAD!!!! undocumented special: " (tostring special) "\n")
|
(io.stderr:write "BAD!!!! undocumented special: " (tostring special) "\n")
|
||||||
{:label special}))))
|
{:label special}))))
|
||||||
|
|||||||
@ -172,15 +172,17 @@ fntype is one of fn or λ or lambda"
|
|||||||
:Snippet 15 :Color 16 :File 17 :Reference 18 :Folder 19 :EnumMember 20
|
:Snippet 15 :Color 16 :File 17 :Reference 18 :Folder 19 :EnumMember 20
|
||||||
:Constant 21 :Struct 22 :Event 23 :Operator 24 :TypeParameter 25})
|
: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"
|
"Makes a completion item"
|
||||||
(doto
|
{:label name
|
||||||
(case (analyze-fn result.definition)
|
:documentation (hover-format definition)
|
||||||
{:fntype _} {: label
|
:filterText name
|
||||||
:kind (if (label:find ":") kinds.Method kinds.Function)}
|
:textEdit {:newText name : range}
|
||||||
_ {: label
|
:kind (or (if ?kind (. kinds ?kind))
|
||||||
:kind (. kinds (?. result :metadata :fls/itemKind))})
|
(. kinds (?. definition :metadata :fls/itemKind))
|
||||||
(tset :documentation (hover-format result))))
|
(if (or (?. definition :metadata :fnl/arglist)
|
||||||
|
(?. (analyze-fn definition.definition)) :fntype)
|
||||||
|
(if (name:find ":") kinds.Method kinds.Function)))})
|
||||||
|
|
||||||
{: signature-help-format
|
{: signature-help-format
|
||||||
: hover-format
|
: hover-format
|
||||||
|
|||||||
@ -199,6 +199,13 @@
|
|||||||
;; builtin macros
|
;; builtin macros
|
||||||
{:label :-?>
|
{:label :-?>
|
||||||
:kind kinds.Keyword
|
:kind kinds.Keyword
|
||||||
|
:documentation true}
|
||||||
|
;; builtin globals
|
||||||
|
{:label :table
|
||||||
|
:kind kinds.Module
|
||||||
|
:documentation true}
|
||||||
|
{:label :_G
|
||||||
|
:kind kinds.Variable
|
||||||
:documentation true}]
|
:documentation true}]
|
||||||
[{:documentation #(= nil $) :label #(not (. things-that-are-allowed-to-have-missing-docs $))}
|
[{:documentation #(= nil $) :label #(not (. things-that-are-allowed-to-have-missing-docs $))}
|
||||||
{:kind #(= 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}]
|
||||||
(t."
|
(t."
|
||||||
[:x]
|
[:x]
|
||||||
[:_G
|
[{:documentation #(= nil $)}
|
||||||
{:documentation #(= nil $)}
|
|
||||||
{:kind #(= nil $)}
|
{:kind #(= nil $)}
|
||||||
{:label #(= nil $)}])
|
{:label #(= nil $)}])
|
||||||
|
|
||||||
(check "(let [x :hi]
|
(check "(let [x :hi]
|
||||||
(x.|))"
|
(x:|))"
|
||||||
[:gsub
|
[:x:gsub
|
||||||
:gmatch
|
:x:match
|
||||||
:match
|
:x:match
|
||||||
:sub
|
:x:sub
|
||||||
:len
|
:x:len
|
||||||
:find]
|
:x:find]
|
||||||
[{:documentation #(= nil $)}])
|
[{:documentation #(= nil $)}])
|
||||||
|
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(fn test-module []
|
(fn test-module []
|
||||||
(check "(coroutine.y|"
|
(check "(coroutine.y|"
|
||||||
[{:label "yield"
|
[{:label "coroutine.yield"
|
||||||
:documentation #(and $.value ($.value:find "```fnl\n(coroutine.yield ...)\n```" 1 true))}]
|
:documentation #(and $.value ($.value:find "```fnl\n(coroutine.yield ...)\n```" 1 true))}]
|
||||||
[{:documentation #(= nil $)}])
|
[{:documentation #(= nil $)}])
|
||||||
(check "(local c coroutine)
|
(check "(local c coroutine)
|
||||||
@ -238,10 +244,10 @@
|
|||||||
[{:documentation #(= nil $)}])
|
[{:documentation #(= nil $)}])
|
||||||
(check "(local t table)
|
(check "(local t table)
|
||||||
(t.i"
|
(t.i"
|
||||||
["insert"]
|
["table.insert" "t.insert"]
|
||||||
[{:documentation #(= nil $)}])
|
[{:documentation #(= nil $)}])
|
||||||
(check "debug.deb|"
|
(check "debug.deb|"
|
||||||
[{:label "debug"
|
[{:label "debug.debug"
|
||||||
:documentation #(and $.value ($.value:find "```fnl\n(debug.debug)\n```" 1 true))}]
|
:documentation #(and $.value ($.value:find "```fnl\n(debug.debug)\n```" 1 true))}]
|
||||||
[])
|
[])
|
||||||
nil)
|
nil)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user