Refactor work and remove all unnecessary fnlfmt changes
This commit is contained in:
parent
3de4def951
commit
72c9a30343
@ -17,30 +17,33 @@ There are no global settings. They're all stored in the `server` object.
|
||||
(fn option [default-value] (doto [default-value] (setmetatable option-mt)))
|
||||
|
||||
(local default-configuration
|
||||
{:fennel-path (option "./?.fnl;./?/init.fnl;src/?.fnl;src/?/init.fnl")
|
||||
:macro-path (option "./?.fnl;./?/init-macros.fnl;./?/init.fnl;src/?.fnl;src/?/init-macros.fnl;src/?/init.fnl")
|
||||
:lua-version (option :lua54)
|
||||
:lints {:unused-definition (option true)
|
||||
:unknown-module-field (option true)
|
||||
:unnecessary-method (option true)
|
||||
:bad-unpack (option true)
|
||||
:var-never-set (option true)
|
||||
:op-with-no-arguments (option true)
|
||||
:multival-in-middle-of-call (option true)}
|
||||
:libraries {:love2d (option false) :tic-80 (option false)}
|
||||
:extra-globals (option "")})
|
||||
{:fennel-path (option "./?.fnl;./?/init.fnl;src/?.fnl;src/?/init.fnl")
|
||||
:macro-path (option "./?.fnl;./?/init-macros.fnl;./?/init.fnl;src/?.fnl;src/?/init-macros.fnl;src/?/init.fnl")
|
||||
:lua-version (option "lua54")
|
||||
:lints {:unused-definition (option true)
|
||||
:unknown-module-field (option true)
|
||||
:unnecessary-method (option true)
|
||||
:bad-unpack (option true)
|
||||
:var-never-set (option true)
|
||||
:op-with-no-arguments (option true)
|
||||
:multival-in-middle-of-call (option true)}
|
||||
:libraries {:love2d (option false) :tic-80 (option false)}
|
||||
:extra-globals (option "")})
|
||||
|
||||
(fn make-configuration-from-template [default ?user ?parent]
|
||||
(if (= option-mt (getmetatable default))
|
||||
(let [setting (case-try ?user
|
||||
nil (?. ?parent :all)
|
||||
nil (. default 1))]
|
||||
(let [setting
|
||||
(case-try ?user
|
||||
nil (?. ?parent :all)
|
||||
nil (. default 1))]
|
||||
(assert (= (type (. default 1)) (type setting)))
|
||||
setting)
|
||||
(= :table (type default))
|
||||
(collect [k _ (pairs default)]
|
||||
k
|
||||
(make-configuration-from-template (. default k) (?. ?user k) ?user))
|
||||
k (make-configuration-from-template
|
||||
(. default k)
|
||||
(?. ?user k)
|
||||
?user))
|
||||
(error "This is a bug with fennel-ls: default-configuration has a key that isn't a table or option")))
|
||||
|
||||
(λ make-configuration [?c]
|
||||
@ -49,14 +52,18 @@ There are no global settings. They're all stored in the `server` object.
|
||||
(λ choose-position-encoding [init-params]
|
||||
"fennel-ls natively uses utf-8, so the goal is to choose positionEncoding=\"utf-8\".
|
||||
However, when not an option, fennel-ls will fall back to positionEncoding=\"utf-16\" (with a performance hit)."
|
||||
(let [?position-encodings (?. init-params :capabilities :general
|
||||
:positionEncodings)
|
||||
utf8? (if (= (type ?position-encodings) :table)
|
||||
(accumulate [utf-8? false _ encoding (ipairs ?position-encodings)
|
||||
&until utf-8?]
|
||||
(or (= encoding :utf-8) (= encoding :utf8)))
|
||||
false)]
|
||||
(if utf8? :utf-8 :utf-16)))
|
||||
(let [?position-encodings (?. init-params :capabilities :general :positionEncodings)
|
||||
utf8?
|
||||
(if (= (type ?position-encodings) :table)
|
||||
(accumulate [utf-8? false
|
||||
_ encoding (ipairs ?position-encodings)
|
||||
&until utf-8?]
|
||||
(or (= encoding :utf-8)
|
||||
(= encoding :utf8)))
|
||||
false)]
|
||||
(if utf8?
|
||||
:utf-8
|
||||
:utf-16)))
|
||||
|
||||
(λ try-parsing [{: text : uri}]
|
||||
(local fennel (require :fennel))
|
||||
@ -65,11 +72,11 @@ However, when not an option, fennel-ls will fall back to positionEncoding=\"utf-
|
||||
|
||||
(λ load-config [server]
|
||||
"This is where we can put anything that needs to react to config changes"
|
||||
(make-configuration (when server.root-uri
|
||||
(-?> (files.read-file server
|
||||
(utils.path->uri (utils.path-join (utils.uri->path server.root-uri)
|
||||
:flsproject.fnl)))
|
||||
try-parsing))))
|
||||
|
||||
(make-configuration
|
||||
(when server.root-uri
|
||||
(-?> (files.read-file server (utils.path->uri (utils.path-join (utils.uri->path server.root-uri) "flsproject.fnl")))
|
||||
try-parsing))))
|
||||
|
||||
(λ reload [server]
|
||||
(set server.configuration (load-config server)))
|
||||
@ -82,7 +89,7 @@ However, when not an option, fennel-ls will fall back to positionEncoding=\"utf-
|
||||
(reload server)
|
||||
;; Eglot does completions differently than every other client I've seen so far, in that it considers foo.bar to be one "symbol".
|
||||
;; If the user types `foo.b`, every other client accepts `bar` as a completion, bun eglot wants the full `foo.bar` symbol.
|
||||
(set server.EGLOT_COMPLETION_QUIRK_MODE
|
||||
(= (?. params :clientInfo :name) :Eglot)))
|
||||
(set server.EGLOT_COMPLETION_QUIRK_MODE (= (?. params :clientInfo :name) :Eglot)))
|
||||
|
||||
{: initialize : reload}
|
||||
{: initialize
|
||||
: reload}
|
||||
|
||||
@ -1,31 +1,32 @@
|
||||
(local fennel (require :fennel))
|
||||
(local {:metadata METADATA
|
||||
:scopes {:global {:specials SPECIALS :macros MACROS}}}
|
||||
(require :fennel.compiler))
|
||||
:scopes {:global {:specials SPECIALS
|
||||
:macros MACROS}}}
|
||||
(require :fennel.compiler))
|
||||
|
||||
(local specials (collect [name value (pairs SPECIALS)]
|
||||
name
|
||||
{:binding name :metadata (. METADATA value)}))
|
||||
(local specials
|
||||
(collect [name value (pairs SPECIALS)]
|
||||
name {:binding name :metadata (. METADATA value)}))
|
||||
|
||||
(local macros* (collect [name value (pairs MACROS)]
|
||||
name
|
||||
{:binding name :metadata (. METADATA value)}))
|
||||
(local macros*
|
||||
(collect [name value (pairs MACROS)]
|
||||
name {:binding name :metadata (. METADATA value)}))
|
||||
|
||||
(local lua-versions
|
||||
{:lua51 (require :fennel-ls.docs.generated.lua51)
|
||||
:lua52 (require :fennel-ls.docs.generated.lua52)
|
||||
:lua53 (require :fennel-ls.docs.generated.lua53)
|
||||
:lua54 (require :fennel-ls.docs.generated.lua54)})
|
||||
{:lua51 (require :fennel-ls.docs.generated.lua51)
|
||||
:lua52 (require :fennel-ls.docs.generated.lua52)
|
||||
:lua53 (require :fennel-ls.docs.generated.lua53)
|
||||
:lua54 (require :fennel-ls.docs.generated.lua54)})
|
||||
|
||||
(fn get-lua-version [version]
|
||||
(when (not (. lua-versions version))
|
||||
(error (.. "fennel-ls doesn't know about lua version " version "\n"
|
||||
"The allowed versions are: "
|
||||
(fennel.view (doto (icollect [key (pairs lua-versions)] key)
|
||||
table.sort)))))
|
||||
(fennel.view (doto (icollect [key (pairs lua-versions)] key) table.sort)))))
|
||||
(. lua-versions version))
|
||||
|
||||
(local libraries {:tic-80 (require :fennel-ls.docs.generated.tic80)})
|
||||
(local libraries
|
||||
{:tic-80 (require :fennel-ls.docs.generated.tic80)})
|
||||
|
||||
;; can't just pcall require because we want to trigger require-as-include
|
||||
(case (pcall #(require :fennel-ls.docs.generated.love2d))
|
||||
@ -35,8 +36,7 @@
|
||||
(when (not (. libraries library))
|
||||
(error (.. "fennel-ls doesn't know about library " library "\n"
|
||||
"The builtin libraries are: "
|
||||
(fennel.view (doto (icollect [key (pairs libraries)] key)
|
||||
table.sort)))))
|
||||
(fennel.view (doto (icollect [key (pairs libraries)] key) table.sort)))))
|
||||
(. libraries library))
|
||||
|
||||
(fn get-all-globals [server]
|
||||
@ -45,8 +45,7 @@
|
||||
(when enabled?
|
||||
(icollect [name (pairs (get-library library)) &into result]
|
||||
name)))
|
||||
(icollect [name (pairs (get-lua-version server.configuration.lua-version))
|
||||
&into result]
|
||||
(icollect [name (pairs (get-lua-version server.configuration.lua-version)) &into result]
|
||||
name)))
|
||||
|
||||
(fn get-library-global [server global-name]
|
||||
@ -59,8 +58,11 @@
|
||||
(. (get-lua-version server.configuration.lua-version) global-name)))
|
||||
|
||||
(fn get-builtin [_server builtin-name]
|
||||
(or (. specials builtin-name) (. macros* builtin-name)))
|
||||
(or (. specials builtin-name)
|
||||
(. macros* builtin-name)))
|
||||
|
||||
;; TODO get-module-metadata
|
||||
|
||||
{: get-global : get-builtin : get-all-globals}
|
||||
{: get-global
|
||||
: get-builtin
|
||||
: get-all-globals}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
;; auto-generated by `make docs` from fennel-ls. Contents come from https://www.lua.org/manual/5.4/manual.html
|
||||
;; Lua Lua 5.4 Reference Manual last updated Thu Jun 13 22:15:52 UTC 2024
|
||||
;; Lua Lua 5.4 Reference Manual last updated Tue May 2 20:09:38 UTC 2023
|
||||
(local docs {:_G {:binding "_G"
|
||||
:metadata {:fnl/docstring "A global variable (not a function) that
|
||||
holds the global environment
|
||||
@ -223,13 +223,13 @@ The returned table can contain all the fields returned by `lua_getinfo`,
|
||||
with the string `?what` describing which fields to fill in.
|
||||
The default for `?what` is to get all information available,
|
||||
except the table of valid lines.
|
||||
The option `\"f\"`
|
||||
If present,
|
||||
the option `\"f\"`
|
||||
adds a field named `func` with the function itself.
|
||||
The option `\"L\"` adds a field named `activelines`
|
||||
with the table of valid lines,
|
||||
provided the function is a Lua function.
|
||||
If the function has no debug information,
|
||||
the table is empty.
|
||||
If present,
|
||||
the option `\"L\"`
|
||||
adds a field named `activelines` with the table of
|
||||
valid lines.
|
||||
|
||||
For instance, the expression `debug.getinfo(1,\"n\").name` returns
|
||||
a name for the current function,
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
(local fennel (require :deps.fennel))
|
||||
|
||||
(fn curl-cached [url]
|
||||
(let [filename (.. :build/ (url:gsub "[/:]" "_"))
|
||||
(let [filename (.. "build/" (url:gsub "[/:]" "_"))
|
||||
file (io.open filename :r)]
|
||||
(if file
|
||||
file
|
||||
(do
|
||||
(sh :curl url [">"] filename)
|
||||
(sh "curl" url [">"] filename)
|
||||
(io.open filename :r)))))
|
||||
|
||||
(fn write-doc-file! [out-filename doc-src doc-tbl]
|
||||
@ -25,20 +25,16 @@
|
||||
(file:read :*a)))))
|
||||
|
||||
(fn main []
|
||||
(sh :mkdir :-p :build/)
|
||||
(sh :mkdir :-p :src/fennel-ls/docs/generated/)
|
||||
(let [generate-love2d-docs? (case arg [:--generate-love2d] true _ false)
|
||||
(sh :mkdir :-p "build/")
|
||||
(sh :mkdir :-p "src/fennel-ls/docs/generated/")
|
||||
(let [generate-love2d-docs? (case arg ["--generate-love2d"] true _ false)
|
||||
{:convert lua-manual} (require :tools.get-docs.lua-manual)
|
||||
{:convert tic80-manual} (require :tools.get-docs.tic80)]
|
||||
(derive-docs-from-url "https://www.lua.org/manual/5.1/manual.html"
|
||||
:lua51.fnl lua-manual)
|
||||
(derive-docs-from-url "https://www.lua.org/manual/5.2/manual.html"
|
||||
:lua52.fnl lua-manual)
|
||||
(derive-docs-from-url "https://www.lua.org/manual/5.3/manual.html"
|
||||
:lua53.fnl lua-manual)
|
||||
(derive-docs-from-url "https://www.lua.org/manual/5.4/manual.html"
|
||||
:lua54.fnl lua-manual)
|
||||
(derive-docs-from-url "https://tic80.com/learn" :tic80.fnl tic80-manual)
|
||||
{:convert tic-manual} (require :tools.get-docs.tic80)]
|
||||
(derive-docs-from-url "https://www.lua.org/manual/5.1/manual.html" "lua51.fnl" lua-manual)
|
||||
(derive-docs-from-url "https://www.lua.org/manual/5.2/manual.html" "lua52.fnl" lua-manual)
|
||||
(derive-docs-from-url "https://www.lua.org/manual/5.3/manual.html" "lua53.fnl" lua-manual)
|
||||
(derive-docs-from-url "https://www.lua.org/manual/5.4/manual.html" "lua54.fnl" lua-manual)
|
||||
(derive-docs-from-url "https://tic80.com/learn" :tic80.fnl tic-manual)
|
||||
(when generate-love2d-docs?
|
||||
(let [{:convert download-and-convert-love2d-manual!} (require :tools.get-docs.love2d)]
|
||||
(write-doc-file! :love2d.fnl
|
||||
|
||||
@ -18,9 +18,7 @@
|
||||
(when ?fields (set lsp-value.fields ?fields))
|
||||
lsp-value))
|
||||
|
||||
(fn download-love-api-tooling! []
|
||||
"Clones the LÖVE-API git repository that contains tooling to scrape and
|
||||
convert the LÖVE Wiki into a Lua table."
|
||||
(fn clone-love-api! []
|
||||
(when (not (io.open :build/love-api))
|
||||
(git-clone love-api-build-directory
|
||||
"https://github.com/love2d-community/love-api")))
|
||||
@ -37,74 +35,70 @@
|
||||
;
|
||||
; PARSERS
|
||||
; -------
|
||||
(fn variant-arguments->names [arguments]
|
||||
(fn get-fn-argument-names [fn-arguments]
|
||||
"Given an array of arguments, return all names as an array."
|
||||
(icollect [_i {:description _ : name :type _} (ipairs arguments)]
|
||||
(icollect [_i {:description _ : name :type _} (ipairs fn-arguments)]
|
||||
name))
|
||||
|
||||
(fn variant-return->string [returns]
|
||||
"Given an array of return values, return a formatted description."
|
||||
(accumulate [x "\n\nReturns -" _i {: description : name :type return-type} (ipairs returns)]
|
||||
(fn format-description-of-fn-return-values [fn-returns]
|
||||
(accumulate [x "\n\nReturns -" _i {: description : name :type return-type} (ipairs fn-returns)]
|
||||
(.. x "\n" " * " name " (`" return-type "`) - " description)))
|
||||
|
||||
(fn parse-first-function-variant [[variant]]
|
||||
(fn parse-first-fn-variant [[variant]]
|
||||
"Given an array of fuction variants, format and return the first variant
|
||||
for the LSP."
|
||||
(collect [v-key v-value (pairs variant)]
|
||||
(case v-key
|
||||
:returns (values :returns (variant-return->string v-value))
|
||||
:arguments (values :args (variant-arguments->names v-value)))))
|
||||
(collect [k v (pairs variant)]
|
||||
(case k
|
||||
:returns (values :returns (format-description-of-fn-return-values v))
|
||||
:arguments (values :args (get-fn-argument-names v)))))
|
||||
|
||||
(fn love-functions->lsp [docs-tbl prefix]
|
||||
"Given an array of documented functions for a LÖVE module, generate a table
|
||||
for the Fennel LSP."
|
||||
(fn get-all-love-api-functions [love-api]
|
||||
[(table.unpack love-api.functions) (table.unpack love-api.callbacks)])
|
||||
|
||||
(fn love-functions->lsp-table [docs-tbl namespace]
|
||||
(collect [_i value (ipairs docs-tbl)]
|
||||
(let [{: name : description} value
|
||||
binding (.. prefix name)
|
||||
binding (.. namespace name)
|
||||
?variants (?. value :variants)
|
||||
; LÖVE functions have several variants, e.g. different arities or
|
||||
; types; however, it's uncertain how to best display all of that
|
||||
; information, so the first is selected here as a reasonable default.
|
||||
first-variant (if ?variants
|
||||
(parse-first-function-variant ?variants)
|
||||
(parse-first-fn-variant ?variants)
|
||||
nil)
|
||||
?args (?. first-variant :args)
|
||||
?returns (or (?. first-variant :returns) "")
|
||||
docstring (.. description ?returns)]
|
||||
(values name (build-lsp-value binding ?args docstring)))))
|
||||
|
||||
(fn module-list->fields [modules ?prefix]
|
||||
"Given a list of LÖVE modules from the LÖVE-API Lua library, recursively
|
||||
generate LSP data for Fennel."
|
||||
(fn module-list->lsp-table [modules ?namespace]
|
||||
(collect [_i module (ipairs modules)]
|
||||
(let [{: name} module ; Other keys - :enum, :functions, :types
|
||||
prefix (if ?prefix (.. ?prefix ".") "")
|
||||
binding (.. prefix name)
|
||||
namespace (if ?namespace (.. ?namespace ".") "")
|
||||
binding (.. namespace name)
|
||||
?docstring (?. module :description)
|
||||
?functions (?. module :functions)
|
||||
?modules (?. module :modules)
|
||||
function-keys (if ?functions
|
||||
(love-functions->lsp ?functions (.. binding "."))
|
||||
(love-functions->lsp-table ?functions (.. binding "."))
|
||||
{})
|
||||
module-keys (if ?modules (module-list->fields ?modules binding) {})
|
||||
module-keys (if ?modules (module-list->lsp-table ?modules binding) {})
|
||||
fields (merge function-keys module-keys)]
|
||||
(values name (build-lsp-value binding nil ?docstring fields)))))
|
||||
|
||||
(fn get-all-love-api-functions [love-api]
|
||||
[(table.unpack love-api.functions) (table.unpack love-api.callbacks)])
|
||||
|
||||
(fn love-api->lsp [love-api]
|
||||
"Given documentation for the entire LÖVE framework from the LÖVE-API Lua
|
||||
library, generate the root LÖVE object suitable for the Fennel LSP."
|
||||
(fn love-api->lsp-table [love-api]
|
||||
(let [root-module {:description (.. "LÖVE is a framework for making 2D "
|
||||
"games in the Lua programming language.")
|
||||
:functions (get-all-love-api-functions love-api)
|
||||
:modules love-api.modules
|
||||
:name :love}]
|
||||
(module-list->fields [root-module])))
|
||||
(module-list->lsp-table [root-module])))
|
||||
|
||||
(fn convert []
|
||||
"Convert LÖVE framework from Lua table to a configuration object
|
||||
used by fennel-ls."
|
||||
(download-love-api-tooling!)
|
||||
"Download documentation for the LÖVE framework via the love-api repo and
|
||||
convert it to a Lua table usable for fennel-ls."
|
||||
(clone-love-api!)
|
||||
(let [love-api (require-love-api)]
|
||||
(fennel.view (love-api->lsp love-api))))
|
||||
(fennel.view (love-api->lsp-table love-api))))
|
||||
|
||||
{: convert}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user