basic hovering

This commit is contained in:
XeroOl 2024-06-24 00:48:51 -05:00
parent ac7617dcf1
commit eff9bced51
3 changed files with 32 additions and 10 deletions

View File

@ -164,6 +164,7 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
nil)))) nil))))
(local {:metadata METADATA} (require :fennel.compiler))
;; the options thing is getting out of hand ;; the options thing is getting out of hand
(λ search-main [server file symbol opts initialization-opts] (λ search-main [server file symbol opts initialization-opts]
"Find the definition of a symbol" "Find the definition of a symbol"
@ -184,7 +185,9 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
_ (case (. file.references symbol) _ (case (. file.references symbol)
ref (search-reference server file ref stack opts) ref (search-reference server file ref stack opts)
_ (case (. file.definitions symbol) _ (case (. file.definitions symbol)
def (search-multival server file def.definition (stack-add-keys! stack def.keys) (or def.multival 1) opts))))))) def (search-multival server file def.definition (stack-add-keys! stack def.keys) (or def.multival 1) opts)
_ (case (. file.macro-refs symbol)
ref {:binding symbol :metadata (. METADATA ref)})))))))
(λ find-local-definition [file name ?scope] (λ find-local-definition [file name ?scope]
(when ?scope (when ?scope

View File

@ -64,6 +64,7 @@ identifiers are declared / referenced in which places."
definitions {} ; symbol -> definition definitions {} ; symbol -> definition
diagnostics {} ; [diagnostic] diagnostics {} ; [diagnostic]
references {} ; symbol -> references references {} ; symbol -> references
macro-refs {} ; symbol -> macro
scopes {} ; ast -> scope scopes {} ; ast -> scope
calls {} ; all calls in the macro-expanded code -> true calls {} ; all calls in the macro-expanded code -> true
lexical {} ; all lists, tables, and symbols in the original source lexical {} ; all lists, tables, and symbols in the original source
@ -211,7 +212,7 @@ identifiers are declared / referenced in which places."
(tset scopes ast scope)) (tset scopes ast scope))
(λ call [ast scope] (λ call [ast scope]
"every list that is a call to a special or macro or function" "every list that is a call to a special or function"
(tset calls ast true) (tset calls ast true)
(tset scopes ast scope) (tset scopes ast scope)
;; Most calls aren't interesting, but here's the list of the ones that are: ;; Most calls aren't interesting, but here's the list of the ones that are:
@ -231,6 +232,17 @@ identifiers are declared / referenced in which places."
(let [len (length ast)] (let [len (length ast)]
(table.insert defer #(tset ast (+ len 1) nil)))))) (table.insert defer #(tset ast (+ len 1) nil))))))
(fn macroexpand [ast _transformed scope]
"every list that is a call to a macro"
(let [macro-id (. ast 1)
macro-fn (accumulate [t scope.macros
_ part (ipairs (utils.multi-sym-split macro-id))]
(if (= (type t) :table)
(. t part)))]
(when (= (type macro-fn) :function)
(assert (sym? macro-id) "macros should be syms")
(tset macro-refs macro-id macro-fn))))
(λ attempt-to-recover! [msg ?ast] (λ attempt-to-recover! [msg ?ast]
(or (= 1 (msg:find "unknown identifier")) (or (= 1 (msg:find "unknown identifier"))
(= 1 (msg:find "local %S+ was overshadowed by a special form or macro")) (= 1 (msg:find "local %S+ was overshadowed by a special form or macro"))
@ -300,6 +312,9 @@ identifiers are declared / referenced in which places."
(each [_ v (ipairs (utils.split-spaces server.configuration.extra-globals))] (each [_ v (ipairs (utils.split-spaces server.configuration.extra-globals))]
(table.insert allowed-globals v)) (table.insert allowed-globals v))
(fn parse-ast [parser]
(icollect [ok ast parser &until (not ok)] ast))
;; TODO clean up this code. It's awful now that there is error handling ;; TODO clean up this code. It's awful now that there is error handling
(let [macro-file? (= (file.text:sub 1 24) ";; fennel-ls: macro-file") (let [macro-file? (= (file.text:sub 1 24) ";; fennel-ls: macro-file")
plugin plugin
@ -308,7 +323,7 @@ identifiers are declared / referenced in which places."
: symbol-to-expression : symbol-to-expression
: call : call
: destructure : destructure
;; : macroexpand : macroexpand
;; :fn fn-hook ;; :fn fn-hook
;; :do there's a do hook ;; :do there's a do hook
;; :chunk I don't know what this one is ;; :chunk I don't know what this one is
@ -322,6 +337,7 @@ identifiers are declared / referenced in which places."
opts {:filename file.uri opts {:filename file.uri
:plugins [plugin] :plugins [plugin]
:allowedGlobals allowed-globals :allowedGlobals allowed-globals
:useMetadata true
:requireAsInclude false :requireAsInclude false
: scope} : scope}
filter-errors (fn _filter-errors [component ...] filter-errors (fn _filter-errors [component ...]
@ -339,7 +355,7 @@ identifiers are declared / referenced in which places."
(fn _p1 [p2 p3] (fn _p1 [p2 p3]
(filter-errors :parser (xpcall #(p p2 p3) fennel.traceback)))) (filter-errors :parser (xpcall #(p p2 p3) fennel.traceback))))
ast (icollect [ok ast parser &until (not ok)] ast)] ast (parse-ast parser)]
(λ parsed [ast] (λ parsed [ast]
"runs on every ast tree that was parsed" "runs on every ast tree that was parsed"
@ -385,6 +401,7 @@ identifiers are declared / referenced in which places."
(each [_ cmd (ipairs defer)] (each [_ cmd (ipairs defer)]
(cmd)) (cmd))
;; TODO make this construct an object instead of mutating the file
(set file.ast ast) (set file.ast ast)
(set file.calls calls) (set file.calls calls)
(set file.lexical lexical) (set file.lexical lexical)
@ -395,6 +412,7 @@ identifiers are declared / referenced in which places."
(set file.diagnostics diagnostics) (set file.diagnostics diagnostics)
(set file.references references) (set file.references references)
(set file.require-calls require-calls) (set file.require-calls require-calls)
(set file.allowed-globals allowed-globals)))) (set file.allowed-globals allowed-globals)
(set file.macro-refs macro-refs))))
{: compile} {: compile}

View File

@ -145,11 +145,12 @@ except that it sets a new message handler `msgh`.")
`(let [,a ,b] ,c)) `(let [,a ,b] ,c))
(bind x print |x)" (bind x print |x)"
#($:find "```fnl\n(print ...)\n```" 1 true)) #($:find "```fnl\n(print ...)\n```" 1 true))
; (check "(macro foo [a b c]
; \"docstring!\" (check "(macro foo [a b c]
; `(,a ,b ,c)) \"docstring!\"
; (fo|o print :hello :world)" `(,a ,b ,c))
; "```fnl\n(macro foo [a b c] ...)\n```\ndocstring!") (fo|o print :hello :world)"
"```fnl\n(foo a b c)\n```\ndocstring!")
nil) nil)
(fn test-reader [] (fn test-reader []