SignatureHelp returns parameters ranges instead just the name.
This fixes an issue where a parameter name that is a substring of the function name causes the client to highlight the function name substring instead of the argument. Using ranges of the signature string avoids the problem.
This commit is contained in:
parent
f68d8ba6fc
commit
945eb86b4c
@ -305,13 +305,13 @@ returns the called symbol and the number of the argument closest to byte"
|
||||
|
||||
(λ find-definition [server file symbol ?byte]
|
||||
(if (. file.definitions symbol)
|
||||
(. file.definitions symbol)
|
||||
(search-main server file symbol {:stop-early? false} {:byte ?byte})))
|
||||
(. file.definitions symbol)
|
||||
(search-main server file symbol {:stop-early? false} {:byte ?byte})))
|
||||
|
||||
(λ find-nearest-definition [server file symbol ?byte]
|
||||
(if (. file.definitions symbol)
|
||||
(. file.definitions symbol)
|
||||
(search-main server file symbol {:stop-early? true} {:byte ?byte})))
|
||||
(. file.definitions symbol)
|
||||
(search-main server file symbol {:stop-early? true} {:byte ?byte})))
|
||||
|
||||
{: find-symbol
|
||||
: find-nearest-call
|
||||
|
||||
@ -19,20 +19,27 @@ user code. Fennel-ls doesn't support user-code formatting as of now."
|
||||
(.. ": " $2 $3)))
|
||||
_ (tostring arg)))
|
||||
|
||||
(fn render-arglist [?arglist]
|
||||
(if ?arglist
|
||||
(icollect [_ arg (ipairs ?arglist)]
|
||||
{:label (render-arg arg)})))
|
||||
|
||||
(fn fn-signature-format [special name args]
|
||||
(let [args (case (type (?. args 1))
|
||||
"Returns the LSP-formatted signature and parameters objects"
|
||||
(fn render-arglist [arglist offset]
|
||||
(var offset offset)
|
||||
(icollect [_ arg (ipairs arglist)]
|
||||
(let [rendered {:label [offset (+ offset (length arg))]}]
|
||||
(set offset (+ 1 (. rendered :label 2)))
|
||||
rendered)))
|
||||
|
||||
(let [name (tostring (or name special))
|
||||
args (case (type (?. args 1))
|
||||
:table (icollect [_ v (ipairs args)]
|
||||
(render-arg v))
|
||||
_ args)]
|
||||
(.. "("
|
||||
(tostring (or name special)) " "
|
||||
(table.concat args " ")
|
||||
")")))
|
||||
_ args)
|
||||
;; + 2 for the opening paren and the space
|
||||
args-offset (+ 2 (length name))]
|
||||
(values (.. "("
|
||||
name " "
|
||||
(table.concat args " ")
|
||||
")")
|
||||
(render-arglist args args-offset))))
|
||||
|
||||
(fn fn-format [special name args docstring]
|
||||
(.. (code-block (fn-signature-format special name args))
|
||||
@ -96,20 +103,26 @@ fntype is one of fn or λ or lambda"
|
||||
"Return a signatureHelp lsp object
|
||||
|
||||
symbol can be an actual ast symbol or a binding object from a docset"
|
||||
(case (analyze-fn symbol.definition)
|
||||
(case-try (analyze-fn symbol.definition)
|
||||
{:fntype ?fntype :name ?name :arglist ?arglist :docstring ?docstring}
|
||||
{:label (fn-signature-format ?fntype ?name ?arglist)
|
||||
(fn-signature-format ?fntype ?name ?arglist)
|
||||
(signature parameters)
|
||||
{:label signature
|
||||
:documentation ?docstring
|
||||
:parameters (render-arglist ?arglist)}
|
||||
_ (case symbol
|
||||
{: binding :metadata {:fnl/arglist arglist :fnl/docstring docstring}}
|
||||
{:label (fn-signature-format :fn binding arglist)
|
||||
:documentation docstring
|
||||
:parameters (render-arglist arglist)}
|
||||
_ {:label (.. "ERROR: don't know how to format "
|
||||
(view symbol {:one-line? true :depth 3}))
|
||||
:documentation (code-block
|
||||
(view symbol {:depth 3}))})))
|
||||
:parameters parameters}
|
||||
;; if we couldn't get the info from the ast, try the metadata
|
||||
(catch _ (case-try symbol
|
||||
{: binding :metadata {:fnl/arglist arglist
|
||||
:fnl/docstring docstring}}
|
||||
(fn-signature-format "" binding arglist)
|
||||
(signature parameters)
|
||||
{:label signature
|
||||
:documentation docstring
|
||||
:parameters parameters}
|
||||
(catch _ {:label (.. "ERROR: don't know how to format "
|
||||
(view symbol {:one-line? true :depth 3}))
|
||||
:documentation (code-block
|
||||
(view symbol {:depth 3}))})))))
|
||||
|
||||
(λ hover-format [result]
|
||||
"Format code that will appear when the user hovers over a symbol"
|
||||
|
||||
@ -92,12 +92,10 @@ LSP json objects."
|
||||
:edit {:changes {uri (diagnostic.quickfix)}}}))
|
||||
|
||||
(λ symbol->signature-help [_server _file _call signature active-parameter]
|
||||
(let [params-count (length signature.parameters)
|
||||
{:label last} (. signature.parameters params-count)]
|
||||
(let [params-count (length signature.parameters)]
|
||||
{:signatures [signature]
|
||||
:activeSignature 0 ; we only ever have one signature
|
||||
:activeParameter (if (and (>= active-parameter params-count)
|
||||
(= last "..."))
|
||||
:activeParameter (if (>= active-parameter params-count)
|
||||
(- params-count 1)
|
||||
(>= active-parameter 0)
|
||||
active-parameter)}))
|
||||
|
||||
@ -4,10 +4,11 @@
|
||||
|
||||
(λ check-signature [expected response]
|
||||
(case response
|
||||
{:signatures [{:label signature}]}
|
||||
{:signatures [{:label signature : parameters}]}
|
||||
(do
|
||||
(faith.= expected.signature signature)
|
||||
(faith.= expected.activeParameter response.activeParameter))
|
||||
(faith.= expected.activeParameter response.activeParameter)
|
||||
(faith.= expected.parameters parameters))
|
||||
;; fail
|
||||
_ (faith.is nil (.. "Invalid response: " (view response)))))
|
||||
|
||||
@ -16,166 +17,237 @@
|
||||
[{: result}] (client:signature-help uri cursor)]
|
||||
(check-signature expected result)))
|
||||
|
||||
(local fn-signature "(fn name? args docstring? ...)")
|
||||
(local fn-params [{:label [4 9]}
|
||||
{:label [10 14]}
|
||||
{:label [15 25]}
|
||||
{:label [26 29]}])
|
||||
|
||||
(local err-signature "(error message ?level)")
|
||||
(local err-params [{:label [7 14]}
|
||||
{:label [15 21]}])
|
||||
|
||||
(local let-signature "(let [name1 val1 ... nameN valN] ...)")
|
||||
(local let-params [{:label [5 32]}
|
||||
{:label [33 36]}])
|
||||
|
||||
(local function-signature "(func arg1 arg2)")
|
||||
(local function-params [{:label [6 10]}
|
||||
{:label [11 15]}])
|
||||
|
||||
(fn test-fn-definition []
|
||||
(check "(fn |)"
|
||||
{:signature "(fn name? args docstring? ...)"
|
||||
:activeParameter 0})
|
||||
{:signature fn-signature
|
||||
:activeParameter 0
|
||||
:parameters fn-params})
|
||||
|
||||
(check "(fn some-nam|)"
|
||||
{:signature "(fn name? args docstring? ...)"
|
||||
:activeParameter 0})
|
||||
{:signature fn-signature
|
||||
:activeParameter 0
|
||||
:parameters fn-params})
|
||||
|
||||
(check "(fn some-name [|]"
|
||||
{:signature "(fn name? args docstring? ...)"
|
||||
:activeParameter 1})
|
||||
{:signature fn-signature
|
||||
:activeParameter 1
|
||||
:parameters fn-params})
|
||||
|
||||
(check "(fn some-name [arg|])"
|
||||
{:signature "(fn name? args docstring? ...)"
|
||||
:activeParameter 1})
|
||||
{:signature fn-signature
|
||||
:activeParameter 1
|
||||
:parameters fn-params})
|
||||
|
||||
(check "(fn some-name [arg1 arg2]
|
||||
\"docstring|\")"
|
||||
{:signature "(fn name? args docstring? ...)"
|
||||
:activeParameter 2})
|
||||
{:signature fn-signature
|
||||
:activeParameter 2
|
||||
:parameters fn-params})
|
||||
|
||||
(check "(fn some-name [arg1 arg2]
|
||||
\"docstring\"
|
||||
|"
|
||||
{:signature "(fn name? args docstring? ...)"
|
||||
:activeParameter 2}))
|
||||
{:signature fn-signature
|
||||
:activeParameter 2
|
||||
:parameters fn-params}))
|
||||
|
||||
(fn test-local-function []
|
||||
(check "(fn func [arg1 arg2] (print :hello))
|
||||
(func|)"
|
||||
{:signature "(func arg1 arg2)"
|
||||
:activeParameter nil})
|
||||
{:signature function-signature
|
||||
:activeParameter nil
|
||||
:parameters function-params})
|
||||
|
||||
(check "(fn func [arg1 arg2] (print :hello))
|
||||
(func |)"
|
||||
{:signature "(func arg1 arg2)"
|
||||
:activeParameter 0})
|
||||
{:signature function-signature
|
||||
:activeParameter 0
|
||||
:parameters function-params})
|
||||
|
||||
(check "(fn func [arg1 arg2] (print :hello))
|
||||
(func a1|)"
|
||||
{:signature "(func arg1 arg2)"
|
||||
:activeParameter 0})
|
||||
{:signature function-signature
|
||||
:activeParameter 0
|
||||
:parameters function-params})
|
||||
|
||||
(check "(fn func [arg1 arg2] (print :hello))
|
||||
(func a|1 a2)"
|
||||
{:signature "(func arg1 arg2)"
|
||||
:activeParameter 0})
|
||||
{:signature function-signature
|
||||
:activeParameter 0
|
||||
:parameters function-params})
|
||||
|
||||
(check "(fn func [arg1 arg2] (print :hello))
|
||||
(func a1 a2|)"
|
||||
{:signature "(func arg1 arg2)"
|
||||
:activeParameter 1})
|
||||
{:signature function-signature
|
||||
:activeParameter 1
|
||||
:parameters function-params})
|
||||
|
||||
(check "(fn func [arg1 arg2] (print :hello))
|
||||
(func a1 a|2)"
|
||||
{:signature "(func arg1 arg2)"
|
||||
:activeParameter 1}))
|
||||
{:signature function-signature
|
||||
:activeParameter 1
|
||||
:parameters function-params}))
|
||||
|
||||
(fn test-literals []
|
||||
(check "(fn func [arg1 arg2] (print :hello))
|
||||
(func arg 10|2)"
|
||||
{:signature "(func arg1 arg2)"
|
||||
:activeParameter 1})
|
||||
{:signature function-signature
|
||||
:activeParameter 1
|
||||
:parameters function-params})
|
||||
|
||||
(check "(fn func [arg1 arg2] (print :hello))
|
||||
(func arg \"10|2\")"
|
||||
{:signature "(func arg1 arg2)"
|
||||
:activeParameter 1}))
|
||||
{:signature function-signature
|
||||
:activeParameter 1
|
||||
:parameters function-params}))
|
||||
|
||||
(fn test-vararg []
|
||||
(local or-params [{:label [4 5]}
|
||||
{:label [6 7]}
|
||||
{:label [8 11]}])
|
||||
|
||||
(check "(or a b|)"
|
||||
{:signature "(or a b ...)"
|
||||
:activeParameter 1})
|
||||
:activeParameter 1
|
||||
:parameters or-params})
|
||||
|
||||
(check "(or a b c|)"
|
||||
{:signature "(or a b ...)"
|
||||
:activeParameter 2})
|
||||
:activeParameter 2
|
||||
:parameters or-params})
|
||||
|
||||
(check "(or a b c d e|)"
|
||||
{:signature "(or a b ...)"
|
||||
:activeParameter 2}))
|
||||
:activeParameter 2
|
||||
:parameters or-params}))
|
||||
|
||||
(fn test-lua-builtin []
|
||||
(check "(error msg|)"
|
||||
{:signature err-signature
|
||||
:activeParameter 0
|
||||
:parameters err-params})
|
||||
|
||||
(check "(error msg lvl|)"
|
||||
{:signature "(error message ?level)"
|
||||
:activeParameter 1})
|
||||
{:signature err-signature
|
||||
:activeParameter 1
|
||||
:parameters err-params})
|
||||
|
||||
(check "(error msg lvl extr|)"
|
||||
{:signature "(error message ?level)"
|
||||
:activeParameter 2}))
|
||||
{:signature err-signature
|
||||
:activeParameter 1
|
||||
:parameters err-params}))
|
||||
|
||||
(fn test-multisym []
|
||||
(check "(table.concat tbl s|)"
|
||||
{:signature "(table.concat list ?sep ?i ?j)"
|
||||
:activeParameter 1}))
|
||||
:activeParameter 1
|
||||
:parameters [{:label [14 18]}
|
||||
{:label [19 23]}
|
||||
{:label [24 26]}
|
||||
{:label [27 29]}]}))
|
||||
|
||||
(fn test-destructuring-arg []
|
||||
(local dstr-params [{:label [6 19]}
|
||||
{:label [20 24]}])
|
||||
|
||||
(check "(fn dstr [{:field name} arg2] {})
|
||||
(dstr |)"
|
||||
{:signature "(dstr {:field name} arg2)"
|
||||
:activeParameter 0})
|
||||
:activeParameter 0
|
||||
:parameters dstr-params})
|
||||
|
||||
(check "(fn dstr [{:field name} arg2] {})
|
||||
(dstr arg1 ar|)"
|
||||
{:signature "(dstr {:field name} arg2)"
|
||||
:activeParameter 1})
|
||||
:activeParameter 1
|
||||
:parameters dstr-params})
|
||||
|
||||
(check "(fn dstr [{:field |} arg2] {})"
|
||||
{:signature "(fn name? args docstring? ...)"
|
||||
:activeParameter 1}))
|
||||
{:signature fn-signature
|
||||
:activeParameter 1
|
||||
:parameters fn-params}))
|
||||
|
||||
(fn test-binding-form []
|
||||
(local each-signature "(each [key value (iterator)] ...)")
|
||||
(local each-params [{:label [6 28]}
|
||||
{:label [29 32]}])
|
||||
|
||||
(check "(each |)"
|
||||
{:signature "(each [key value (iterator)] ...)"
|
||||
:activeParameter 0})
|
||||
{:signature each-signature
|
||||
:activeParameter 0
|
||||
:parameters each-params})
|
||||
|
||||
(check "(each [|])"
|
||||
{:signature "(each [key value (iterator)] ...)"
|
||||
:activeParameter 0})
|
||||
{:signature each-signature
|
||||
:activeParameter 0
|
||||
:parameters each-params})
|
||||
|
||||
(check "(each [k val|])"
|
||||
{:signature "(each [key value (iterator)] ...)"
|
||||
:activeParameter 0})
|
||||
{:signature each-signature
|
||||
:activeParameter 0
|
||||
:parameters each-params})
|
||||
|
||||
(check "(let [a 0]
|
||||
(error |))"
|
||||
{:signature "(error message ?level)"
|
||||
:activeParameter 0})
|
||||
{:signature err-signature
|
||||
:activeParameter 0
|
||||
:parameters err-params})
|
||||
|
||||
(check "(let [a|] (error))"
|
||||
{:signature "(let [name1 val1 ... nameN valN] ...)"
|
||||
:activeParameter 0}))
|
||||
{:signature let-signature
|
||||
:activeParameter 0
|
||||
:parameters let-params}))
|
||||
|
||||
(fn test-indirect-definition []
|
||||
(check "(let [a error]
|
||||
(a |))"
|
||||
{:signature "(error message ?level)"
|
||||
:activeParameter 0}))
|
||||
{:signature err-signature
|
||||
:activeParameter 0
|
||||
:parameters err-params}))
|
||||
|
||||
(fn test-destructuring-binding []
|
||||
(check "(let [(a b|) {}]"
|
||||
{:signature "(let [name1 val1 ... nameN valN] ...)"
|
||||
:activeParameter 0})
|
||||
{:signature let-signature
|
||||
:activeParameter 0
|
||||
:parameters let-params})
|
||||
|
||||
(check "(let [(a {:b |}) {}]"
|
||||
{:signature "(let [name1 val1 ... nameN valN] ...)"
|
||||
:activeParameter 0})
|
||||
{:signature let-signature
|
||||
:activeParameter 0
|
||||
:parameters let-params})
|
||||
|
||||
(check "(let [{:field |} {}]"
|
||||
{:signature "(let [name1 val1 ... nameN valN] ...)"
|
||||
:activeParameter 0})
|
||||
{:signature let-signature
|
||||
:activeParameter 0
|
||||
:parameters let-params})
|
||||
|
||||
(check "(let [{:field {: nested |"
|
||||
{:signature "(let [name1 val1 ... nameN valN] ...)"
|
||||
:activeParameter 0})
|
||||
{:signature let-signature
|
||||
:activeParameter 0
|
||||
:parameters let-params})
|
||||
|
||||
(check "(let [{:field {: nested &as |}} {}]"
|
||||
{:signature "(let [name1 val1 ... nameN valN] ...)"
|
||||
:activeParameter 0}))
|
||||
{:signature let-signature
|
||||
:activeParameter 0
|
||||
:parameters let-params}))
|
||||
|
||||
{: test-fn-definition
|
||||
: test-local-function
|
||||
|
||||
Loading…
Reference in New Issue
Block a user