diff --git a/src/fennel-ls/handlers.fnl b/src/fennel-ls/handlers.fnl index af5b7c3..6405a85 100644 --- a/src/fennel-ls/handlers.fnl +++ b/src/fennel-ls/handlers.fnl @@ -80,7 +80,8 @@ Every time the client sends a message, it gets handled by a function in the corr ;; regular symbol (language.search-main self file symbol {:stop-early? true} byte)) result - (message.range-and-uri self result.file (or result.binding result.definition)) + (if result.file + (message.range-and-uri self result.file (or result.binding result.definition))) (catch _ nil)))) (λ requests.textDocument/references [self send {: position diff --git a/src/fennel-ls/language.fnl b/src/fennel-ls/language.fnl index e34edb3..d9c8462 100644 --- a/src/fennel-ls/language.fnl +++ b/src/fennel-ls/language.fnl @@ -80,7 +80,9 @@ but that info does (λ search-symbol [self file symbol stack opts] (if (= (tostring symbol) :nil) - {:definition symbol : file} + (if (= 0 (length stack)) + {:definition symbol : file} + nil) ;; TODO globals (case (. file.references symbol) to (search-assignment self file to (stack-add-multisym! stack symbol) opts)))) @@ -120,7 +122,7 @@ but that info does (search-val self file (. call 2) stack opts) (where (or :fn :lambda :λ)) - (if (= multival 1) + (if (and (= multival 1) (= 0 (length stack))) {:definition call : file}) ;; BASE CASE !! ;; TODO expand-macros @@ -151,7 +153,7 @@ but that info does (if (sym? symbol) (let [split (utils.multi-sym-split symbol (if ?byte (+ 1 (- ?byte symbol.bytestart)))) stack (stack-add-split! [] split)] - (case (. METADATA (. SPECIALS (tostring symbol))) + (case (. METADATA (or (. MACROS (tostring symbol)) (. SPECIALS (tostring symbol)))) metadata {:binding symbol : metadata} _ (case (. file.references symbol) ref (search-assignment self file ref stack opts) diff --git a/test/goto-definition-test.fnl b/test/goto-definition-test.fnl index 9df47d6..2eb02df 100644 --- a/test/goto-definition-test.fnl +++ b/test/goto-definition-test.fnl @@ -104,6 +104,12 @@ _response (c:definition :foo.fnl 1 8)] nil)) + (it "doesn't crash when going to hashfn" + (let [c (create-client) + _ (c:open-file! :foo.fnl "#$...") + _response (c:definition :foo.fnl 0 0)] + nil)) + (it "can go through multival destructures" (let [c (doto (create-client) (: :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)")) diff --git a/test/hover-test.fnl b/test/hover-test.fnl index 0a59643..576eea5 100644 --- a/test/hover-test.fnl +++ b/test/hover-test.fnl @@ -81,4 +81,18 @@ (is (hover-x.result.contents.value:find "```fnl\n1\n```")) (is (hover-y.result.contents.value:find "```fnl\n2\n```")) (is (hover-z.result.contents.value:find "```fnl\n3\n```")) - nil))) + nil)) + + (it "hovers over a special" + (let [client (doto (create-client) + (: :open-file! :foo.fnl "(do nil)")) + [hover-do] (client:hover :foo.fnl 0 2)] + (is.equal hover-do.result.contents.value + "```fnl\n(do ...)\n```\nEvaluate multiple forms; return last value."))) + + (it "hovers over a builtin macro" + (let [client (doto (create-client) + (: :open-file! :foo.fnl "(doto nil (print))")) + [hover-do] (client:hover :foo.fnl 0 2)] + (is.equal hover-do.result.contents.value + "```fnl\n(doto val ...)\n```\nEvaluate val and splice it into the first argument of subsequent forms.")))) diff --git a/test/init.fnl b/test/init.fnl index 686e42a..f5170e8 100644 --- a/test/init.fnl +++ b/test/init.fnl @@ -23,4 +23,5 @@ (let [{: passes : errors} (require :test.lust)] (print (.. passes " passes. " errors " errors.")) - (os.exit errors)) + (if (not= errors 0) + (os.exit errors)))