From 61947d321969a3f17e8756e23bd8ccf641086210 Mon Sep 17 00:00:00 2001 From: XeroOl Date: Thu, 4 Aug 2022 00:33:50 -0500 Subject: [PATCH] Goto definiton for destructuring --- README.md | 10 +++++++--- src/fennel-ls/plugin.fnl | 18 +++++++++++++----- src/fennel-ls/the-actual-code.fnl | 1 - test/goto-definition-test.fnl | 11 ++++++----- test/test-project/example.fnl | 5 +++-- 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 954026e..aa0d72f 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,20 @@ THIS PROJECT IS NOT IN A USABLE STATE YET. CHECK BACK LATER. A language server for fennel-ls. (Planned) Features: +[ ] for planned features +[X] for implemented features + * [X] Able to connect to a client * [ ] Support for UTF-8 characters that aren't just plain ASCII. (especially `λ`) * [ ] Settings to configure lua / fennel path, allowed globals, etc * [ ] Builds for anything other than arch linux * [X] Go-to-definition for (require) statements -* [ ] Go-to-definition for in-file definitions +* [X] basic go-to-definition for in-file definitions +* [ ] Go-to-definition for in-file definitions in all cases * [ ] Go-to-definition for definitions in other files * [ ] Go-to-definition into lua code -* [ ] Report compiler errors -* [ ] Report linting issues +* [ ] Reports compiler errors +* [ ] Reports linting issues * [ ] basic completion suggestions * [ ] Hover over a symbol for documentation * [ ] Signature help diff --git a/src/fennel-ls/plugin.fnl b/src/fennel-ls/plugin.fnl index 9ea4ec9..429c7d6 100644 --- a/src/fennel-ls/plugin.fnl +++ b/src/fennel-ls/plugin.fnl @@ -44,13 +44,21 @@ (λ reference [ast scope] "called whenever a variable is referenced" (assert (fennel.sym? ast)) - (let [name (string.match (tostring ast) "[^%.:]+")] - (table.insert file.references {:from ast :to (find-reference name scope)}))) + (let [name (string.match (tostring ast) "[^%.:]+") + target (find-reference name scope)] + (table.insert file.references {:from ast :to target}))) (λ define [?definition binding scope] "called whenever a local variable or destructure statement is introduced" - (when (fennel.sym? binding) ;; for now, I am going to bury my head in the sand and ignore destructure logic - (tset (. scope-notes scope) (tostring binding) binding))) + ;; right now I'm not keeping track of *how* the symbol was destructured: just finding all the symbols for now. + (λ recurse [binding] + (if (fennel.sym? binding) + ;; this seems to defeat match's symbols in specifically the one case I've tested + (if (not (?. scope :parent :gensyms (tostring binding))) + (tset (. scope-notes scope) (tostring binding) binding)) + (each [k v ((if (fennel.list? binding) ipairs pairs) binding)] + (recurse v)))) + (recurse binding)) (λ define-function-name [ast scope] (match ast @@ -66,7 +74,7 @@ (where [_fn args] (fennel.sequence? args)) args (where [_fn _name args] (fennel.sequence? args)) args)) (each [_ argument (ipairs args)] - (define nil argument scope))) ;; we say arguments are bound to "nil" for now + (define nil argument scope))) ;; we say function arguments are "nil" for now (λ define-function [ast scope] "Introduces the various symbols exported by a function. diff --git a/src/fennel-ls/the-actual-code.fnl b/src/fennel-ls/the-actual-code.fnl index 2c1a6d7..9ba61e9 100644 --- a/src/fennel-ls/the-actual-code.fnl +++ b/src/fennel-ls/the-actual-code.fnl @@ -69,7 +69,6 @@ Every time the client sends a message, it gets handled by a function in the corr (λ requests.textDocument/definition [self send {: position :textDocument {: uri}}] (local file (state.get-by-uri self uri)) (local byte (util.pos->byte file.text position.line position.character)) - (log file) (accumulate [result nil _ reference (ipairs file.references) &until (or result (parser.past? reference.from byte))] (if (parser.contains? reference.from byte) diff --git a/test/goto-definition-test.fnl b/test/goto-definition-test.fnl index ebdf0c3..af3228d 100644 --- a/test/goto-definition-test.fnl +++ b/test/goto-definition-test.fnl @@ -48,14 +48,15 @@ (check "example.fnl" 19 12 "example.fnl" 17 8 17 9)) (it "can sort out the unification rule with match (variable introduced)" - (check "example.fnl" 20 12 "example.fnl" 20 9 20 10))) + (check "example.fnl" 20 12 "example.fnl" 20 9 20 10)) - ;; (it "doesn't have ghost definitions from the same byte ranges as the macro files it's using") - ;; (it "can go to a reference that occurs in a macro") + (it "can go to a destructured local" + (check "example.fnl" 21 9 "example.fnl" 16 13 16 16))) ;; (it "can go to a function inside a table") - ;; (it "can go to an field inside of a table") - ;; (it "can go to a destructured local") + ;; (it "can go to a field inside of a table") ;; (it "can go to a destructured function argument") + ;; (it "can go to a reference that occurs in a macro") + ;; (it "doesn't have ghost definitions from the same byte ranges as the macro files it's using") ;; (it "can go to a function in another file when accessed by multisym") ;; (it "can go to a function in another file imported via destructuring assignment") ;; (it "can work with a custom fennelpath") diff --git a/test/test-project/example.fnl b/test/test-project/example.fnl index 78eb634..3150b99 100644 --- a/test/test-project/example.fnl +++ b/test/test-project/example.fnl @@ -14,10 +14,11 @@ (let [bar "shadowed"] (print bar)) -(λ test [{: foo}] +(fn test [{: foo}] (let [a 10] (match [0 10] [1 a] a - [0 b] b))) + [0 b] b)) + (print foo)) {: bar}