completions textEdit initial code
This commit is contained in:
parent
8a988cb8be
commit
25e279eda3
2
TODO.md
2
TODO.md
@ -63,7 +63,7 @@ Here is my feature wishlist. I don't expect to ever get all of this done, but th
|
|||||||
- [X] Unused locals
|
- [X] Unused locals
|
||||||
- [X] Unknown fields of modules
|
- [X] Unknown fields of modules
|
||||||
- [ ] Discarding results from pcall/xpcall/other functions
|
- [ ] Discarding results from pcall/xpcall/other functions
|
||||||
- [ ] `unpack` or `values` into a special
|
- [.] `unpack` or `values` into a special
|
||||||
- [ ] `do`/`values` with only one inner form
|
- [ ] `do`/`values` with only one inner form
|
||||||
- [ ] redundant `do` as the last/only item in a form that accepts a "body"
|
- [ ] redundant `do` as the last/only item in a form that accepts a "body"
|
||||||
- [ ] `var` forms that could be `local`
|
- [ ] `var` forms that could be `local`
|
||||||
|
|||||||
@ -99,9 +99,11 @@ fntype is one of fn or λ or lambda"
|
|||||||
(doto
|
(doto
|
||||||
(case (analyze-fn def.definition)
|
(case (analyze-fn def.definition)
|
||||||
{:fntype _} {: label
|
{:fntype _} {: label
|
||||||
:kind (if (label:find ":") kinds.Method kinds.Function)}
|
:kind (if (label:find ":") kinds.Method kinds.Function)
|
||||||
|
:textEdit {:newText label}}
|
||||||
_ {: label
|
_ {: label
|
||||||
:kind kinds.Variable})
|
:kind kinds.Variable
|
||||||
|
:textEdit {:newText label}})
|
||||||
(tset :documentation (hover-format def))))
|
(tset :documentation (hover-format def))))
|
||||||
|
|
||||||
{: hover-format
|
{: hover-format
|
||||||
|
|||||||
@ -128,10 +128,9 @@ Every time the client sends a message, it gets handled by a function in the corr
|
|||||||
:Constant 21 :Struct 22 :Event 23 :Operator 24 :TypeParameter 25})
|
:Constant 21 :Struct 22 :Event 23 :Operator 24 :TypeParameter 25})
|
||||||
|
|
||||||
(λ make-completion-item [self file name scope]
|
(λ make-completion-item [self file name scope]
|
||||||
;; TODO consider passing stop-early?
|
|
||||||
(case (language.search-name-and-scope self file name scope)
|
(case (language.search-name-and-scope self file name scope)
|
||||||
def (formatter.completion-item-format name def)
|
def (formatter.completion-item-format name def)
|
||||||
_ {:label name}))
|
_ {:label name :textEdit {:newText name}}))
|
||||||
|
|
||||||
(λ scope-completion [self file byte ?symbol parents]
|
(λ scope-completion [self file byte ?symbol parents]
|
||||||
(let [scope (or (accumulate [result nil
|
(let [scope (or (accumulate [result nil
|
||||||
@ -142,7 +141,8 @@ Every time the client sends a message, it gets handled by a function in the corr
|
|||||||
?parent (. parents 1)
|
?parent (. parents 1)
|
||||||
result []
|
result []
|
||||||
in-call-position? (and ?parent (= ?symbol (. ?parent 1)))]
|
in-call-position? (and ?parent (= ?symbol (. ?parent 1)))]
|
||||||
(collect-scope scope :manglings #(make-completion-item self file $ scope) result)
|
(collect-scope scope :manglings #(doto (make-completion-item self file $ scope) (tset :kind kinds.Variable)) result)
|
||||||
|
|
||||||
(when in-call-position?
|
(when in-call-position?
|
||||||
(collect-scope scope :macros #(doto (make-completion-item self file $ scope) (tset :kind kinds.Keyword)) result)
|
(collect-scope scope :macros #(doto (make-completion-item self file $ scope) (tset :kind kinds.Keyword)) result)
|
||||||
(collect-scope scope :specials #(doto (make-completion-item self file $ scope) (tset :kind kinds.Operator)) result))
|
(collect-scope scope :specials #(doto (make-completion-item self file $ scope) (tset :kind kinds.Operator)) result))
|
||||||
@ -159,26 +159,40 @@ Every time the client sends a message, it gets handled by a function in the corr
|
|||||||
(case (values definition (type definition))
|
(case (values definition (type definition))
|
||||||
;; fields of a string are hardcoded to "string"
|
;; fields of a string are hardcoded to "string"
|
||||||
(_str :string) (icollect [label _ (pairs string)]
|
(_str :string) (icollect [label _ (pairs string)]
|
||||||
{: label :kind kinds.Field})
|
{: label :kind kinds.Field :textEdit {:newText label}})
|
||||||
;; fields of a table
|
;; fields of a table
|
||||||
(tbl :table) (icollect [label _ (pairs tbl)]
|
(tbl :table) (icollect [label _ (pairs tbl)]
|
||||||
(if (= (type label) :string)
|
(if (= (type label) :string)
|
||||||
(case (language.search-ast self file tbl [label] {})
|
(case (language.search-ast self file tbl [label] {})
|
||||||
def (formatter.completion-item-format label def)
|
def (formatter.completion-item-format label def)
|
||||||
_ {: label :kind kinds.Field}))))
|
_ {: label :kind kinds.Field :textEdit {:newText label}}))))
|
||||||
_ nil))))
|
_ nil))))
|
||||||
|
|
||||||
(λ _create-completion-item [self file name scope]
|
|
||||||
(let [result (language.search-name-and-scope self file name scope)]
|
|
||||||
{:label result.label :kind result.kind}))
|
|
||||||
|
|
||||||
(λ requests.textDocument/completion [self send {: position :textDocument {: uri}}]
|
(λ requests.textDocument/completion [self send {: position :textDocument {: uri}}]
|
||||||
(let [file (state.get-by-uri self uri)
|
(let [file (state.get-by-uri self uri)
|
||||||
byte (utils.position->byte file.text position self.position-encoding)
|
byte (utils.position->byte file.text position self.position-encoding)
|
||||||
(?symbol parents) (language.find-symbol file.ast byte)]
|
(?symbol parents) (language.find-symbol file.ast byte)]
|
||||||
(case (-?> ?symbol utils.multi-sym-split)
|
(case (-?> ?symbol utils.multi-sym-split)
|
||||||
(where (or nil [_ nil])) (scope-completion self file byte ?symbol parents)
|
|
||||||
[_a _b &as split] (field-completion self file ?symbol split))))
|
;; completion from current scope
|
||||||
|
(where (or nil [_ nil]))
|
||||||
|
(let [input-range (if ?symbol (message.multisym->range self file ?symbol -1) {:start position :end position})
|
||||||
|
?completions (scope-completion self file byte ?symbol parents)]
|
||||||
|
(if ?completions
|
||||||
|
(each [_ completion (ipairs ?completions)]
|
||||||
|
(set completion.textEdit.range input-range)))
|
||||||
|
?completions)
|
||||||
|
|
||||||
|
;; completion from field
|
||||||
|
[_a _b &as split]
|
||||||
|
(let [input-range (message.multisym->range self file ?symbol -1)
|
||||||
|
?completions (field-completion self file ?symbol split input-range)]
|
||||||
|
(if ?completions
|
||||||
|
(each [_ completion (ipairs ?completions)]
|
||||||
|
(set completion.textEdit.range input-range)))
|
||||||
|
?completions))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(λ requests.textDocument/rename [self send {: position :textDocument {: uri} :newName new-name}]
|
(λ requests.textDocument/rename [self send {: position :textDocument {: uri} :newName new-name}]
|
||||||
(let [file (state.get-by-uri self uri)
|
(let [file (state.get-by-uri self uri)
|
||||||
|
|||||||
@ -67,7 +67,8 @@ to look to fix this in the future."
|
|||||||
self.position-encoding)}))
|
self.position-encoding)}))
|
||||||
|
|
||||||
(λ multisym->range [self file ast n]
|
(λ multisym->range [self file ast n]
|
||||||
(let [spl (utils.multi-sym-split ast)]
|
(let [spl (utils.multi-sym-split ast)
|
||||||
|
n (if (< n 0) (+ n 1 (length spl)) n)]
|
||||||
(case (values (utils.get-ast-info ast :bytestart)
|
(case (values (utils.get-ast-info ast :bytestart)
|
||||||
(utils.get-ast-info ast :byteend))
|
(utils.get-ast-info ast :byteend))
|
||||||
(bytestart byteend)
|
(bytestart byteend)
|
||||||
|
|||||||
@ -143,7 +143,8 @@
|
|||||||
(where
|
(where
|
||||||
{:label :local
|
{:label :local
|
||||||
:kind (= kinds.Operator)
|
:kind (= kinds.Operator)
|
||||||
:documentation documentation}
|
:documentation documentation
|
||||||
|
:textEdit {:range {:start {:line 0 :character 1} :end {:line 0 :character 1}}}}
|
||||||
(not= documentation :nil)))))
|
(not= documentation :nil)))))
|
||||||
|
|
||||||
(it "offers rich information about builtin-macro completions"
|
(it "offers rich information about builtin-macro completions"
|
||||||
|
|||||||
@ -109,7 +109,6 @@
|
|||||||
(: :open-file! :foo.fnl "(local [x y] (values [1 2] [3 4]))\n(local (a b) (values {:x y : y} {: x : y}))\n(print b.x a)"))
|
(: :open-file! :foo.fnl "(local [x y] (values [1 2] [3 4]))\n(local (a b) (values {:x y : y} {: x : y}))\n(print b.x a)"))
|
||||||
[find_b] (c:definition :foo.fnl 2 9)]
|
[find_b] (c:definition :foo.fnl 2 9)]
|
||||||
;; it finds the first `x` symbol
|
;; it finds the first `x` symbol
|
||||||
(print (view find_b))
|
|
||||||
(is.same find_b.result.range {:start {:line 0 :character 8} :end {:line 0 :character 9}})
|
(is.same find_b.result.range {:start {:line 0 :character 8} :end {:line 0 :character 9}})
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
|
|||||||
@ -28,8 +28,6 @@
|
|||||||
(is.same ["a" "b" "c" "d" "e" "f"] (utils.multi-sym-split "a.b.c.d.e.f"))
|
(is.same ["a" "b" "c" "d" "e" "f"] (utils.multi-sym-split "a.b.c.d.e.f"))
|
||||||
(is.same ["obj" "bar"] (utils.multi-sym-split (fennel.sym "obj.bar")))))
|
(is.same ["obj" "bar"] (utils.multi-sym-split (fennel.sym "obj.bar")))))
|
||||||
|
|
||||||
(describe "utf8") ;; TODO
|
|
||||||
|
|
||||||
(describe "find-symbol"
|
(describe "find-symbol"
|
||||||
(it "finds a symbol and parents"
|
(it "finds a symbol and parents"
|
||||||
(let [state (doto (create-client)
|
(let [state (doto (create-client)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user