From 5c4d0530f855212cca7aa8fef330546221d1fdb9 Mon Sep 17 00:00:00 2001 From: XeroOl Date: Sat, 17 Sep 2022 20:01:25 -0500 Subject: [PATCH] consider which part of a multisym the cursor is on For goto-definition and hovering. --- src/fennel-ls/compiler.fnl | 3 +-- src/fennel-ls/handlers.fnl | 4 ++-- src/fennel-ls/language.fnl | 4 ++-- src/fennel-ls/state.fnl | 6 +++--- test/goto-definition-test.fnl | 6 ++++++ test/hover-test.fnl | 3 +++ test/test-project/goto-definition.fnl | 3 +++ 7 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/fennel-ls/compiler.fnl b/src/fennel-ls/compiler.fnl index e865cd0..205a7a0 100644 --- a/src/fennel-ls/compiler.fnl +++ b/src/fennel-ls/compiler.fnl @@ -14,7 +14,6 @@ later by fennel-ls.language to answer requests from the client." (local -λ- (sym :λ)) (local -lambda- (sym :lambda)) - (λ multisym? [t] ;; check if t is a symbol with multiple parts, eg. foo.bar.baz (and (sym? t) @@ -36,7 +35,7 @@ later by fennel-ls.language to answer requests from the client." (tset self key val) val))}) -(λ compile [file] +(λ compile [self file] "Compile the file, and record all the useful information from the compiler into the file object" ;; The useful information being recorded: (let [definitions-by-scope (doto {} (setmetatable has-tables-mt)) diff --git a/src/fennel-ls/handlers.fnl b/src/fennel-ls/handlers.fnl index a0ddd10..7bebc5f 100644 --- a/src/fennel-ls/handlers.fnl +++ b/src/fennel-ls/handlers.fnl @@ -76,7 +76,7 @@ Every time the client sends a message, it gets handled by a function in the corr (if (. file.require-calls parent) (language.search self file parent [] {:stop-early? true}))) nil - (language.search-main self file symbol {:stop-early? true})) + (language.search-main self file symbol {:stop-early? true} byte)) (result result-file) (message.range-and-uri (or result.binding result.definition) @@ -87,7 +87,7 @@ Every time the client sends a message, it gets handled by a function in the corr (let [file (state.get-by-uri self uri) byte (pos->byte file.text position.line position.character)] (match-try (language.find-symbol file.ast byte) - symbol (language.search-main self file symbol {}) + symbol (language.search-main self file symbol {} byte) result {:contents {:kind "markdown" :value (formatter.hover-format result)}} (catch _ nil)))) diff --git a/src/fennel-ls/language.fnl b/src/fennel-ls/language.fnl index ef5ebe5..d19e09d 100644 --- a/src/fennel-ls/language.fnl +++ b/src/fennel-ls/language.fnl @@ -85,14 +85,14 @@ the data provided by compiler.fnl." (= 0 (length stack)) {:definition item} ;; BASE CASE !! (error (.. "I don't know what to do with " (view item)))))) -(λ search-main [self file symbol opts] +(λ search-main [self file symbol opts ?byte] ;; TODO partial byting, go to different defitition sites depending on which section of the symbol the trigger happens on ;; The stack is the multi-sym parts still to search ;; for example, if I'm searching for "foo.bar.baz", my "item" or "symbol" is foo, ;; and the stack has ["baz" "bar"], with "bar" at the "top"/"end" of the stack as the next key to search. (local stack - (let [split (utils.multi-sym-split symbol)] + (let [split (utils.multi-sym-split symbol (if ?byte (+ 1 (- ?byte symbol.bytestart))))] (fcollect [i (length split) 2 -1] (. split i)))) (match (values (. file.references symbol) (. file.definitions symbol)) diff --git a/src/fennel-ls/state.fnl b/src/fennel-ls/state.fnl index 76323a0..9cd151b 100644 --- a/src/fennel-ls/state.fnl +++ b/src/fennel-ls/state.fnl @@ -22,7 +22,7 @@ object." (λ get-by-uri [self uri] (or (. self.files uri) (let [file (read-file uri)] - (compile file) + (compile self file) (tset self.files uri file) file))) @@ -51,14 +51,14 @@ object." (do (when (not= text file.text) (set file.text text) - (compile file)) + (compile self file)) file) ;; create new file nil (let [file {: uri : text}] (tset self.files uri file) - (compile file) + (compile self file) file))) {: get-by-uri diff --git a/test/goto-definition-test.fnl b/test/goto-definition-test.fnl index d410bf7..9af2bd4 100644 --- a/test/goto-definition-test.fnl +++ b/test/goto-definition-test.fnl @@ -49,6 +49,9 @@ (it "can go to a function inside a table" (check :goto-definition.fnl 28 6 :goto-definition.fnl 4 4 4 7)) + (it "can go to the table containing a function" + (check :goto-definition.fnl 28 3 :goto-definition.fnl 26 7 26 10)) + (it "can go to a field inside of a table literal" (check :goto-definition.fnl 35 19 :goto-definition.fnl 34 20 34 35)) @@ -72,6 +75,9 @@ (it "goes to the last form of `do` and `let`" (check :goto-definition.fnl 47 13 :goto-definition.fnl 47 30 47 52)) + (it "can go to `a.b` from an `a.b.c` symbol" + (check :goto-definition.fnl 54 9 :goto-definition.fnl 53 13 53 25)) + ;; TODO ;; (it "doesn't leak function arguments to the surrounding scope") ;; (it "can go to a function in another file imported via destructuring assignment") ;; WORKS, just needs a test case diff --git a/test/hover-test.fnl b/test/hover-test.fnl index f938243..52c96b3 100644 --- a/test/hover-test.fnl +++ b/test/hover-test.fnl @@ -46,6 +46,9 @@ (it "hovers over λ function" (check "hover.fnl" 18 6 "```fnl\n(fn lambda-fn [arg1 arg2] ...)\n```\ndocstring")) + (it "hovers the first part of a multisym" + (check "hover.fnl" 9 14 "```fnl\n{:field1 10 :field2 :colon-string}\n```")) + (it "hovers over literally the very first character" (local state (doto [] setup-server)) (let [message (dispatch.handle* state diff --git a/test/test-project/goto-definition.fnl b/test/test-project/goto-definition.fnl index 7f5ec58..d050eb8 100644 --- a/test/test-project/goto-definition.fnl +++ b/test/test-project/goto-definition.fnl @@ -50,3 +50,6 @@ (local module {}) (fn module.my-function [a b c] "docstring" (let [body (+ a b c)] body)) (module.my-function 1 2 3) + +(local x {:y {:z (+ 1 1)}}) +(print x.y.z)