From 72c9a303434d5d8c0ca3900145d9edbc38b67b63 Mon Sep 17 00:00:00 2001 From: Emma Date: Sat, 7 Sep 2024 22:03:38 -0400 Subject: [PATCH] Refactor work and remove all unnecessary fnlfmt changes --- src/fennel-ls/config.fnl | 73 ++++++++++++++------------ src/fennel-ls/docs.fnl | 44 ++++++++-------- src/fennel-ls/docs/generated/lua54.fnl | 14 ++--- tools/get-docs.fnl | 26 ++++----- tools/get-docs/love2d.fnl | 66 +++++++++++------------ 5 files changed, 111 insertions(+), 112 deletions(-) diff --git a/src/fennel-ls/config.fnl b/src/fennel-ls/config.fnl index 7c2c05b..42ad462 100644 --- a/src/fennel-ls/config.fnl +++ b/src/fennel-ls/config.fnl @@ -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} diff --git a/src/fennel-ls/docs.fnl b/src/fennel-ls/docs.fnl index cbd11b0..322220b 100644 --- a/src/fennel-ls/docs.fnl +++ b/src/fennel-ls/docs.fnl @@ -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} diff --git a/src/fennel-ls/docs/generated/lua54.fnl b/src/fennel-ls/docs/generated/lua54.fnl index 566c6f3..0769d47 100644 --- a/src/fennel-ls/docs/generated/lua54.fnl +++ b/src/fennel-ls/docs/generated/lua54.fnl @@ -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, diff --git a/tools/get-docs.fnl b/tools/get-docs.fnl index 58f7f6f..0beb0b6 100644 --- a/tools/get-docs.fnl +++ b/tools/get-docs.fnl @@ -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 diff --git a/tools/get-docs/love2d.fnl b/tools/get-docs/love2d.fnl index 781abbf..afe363e 100644 --- a/tools/get-docs/love2d.fnl +++ b/tools/get-docs/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}