clean up configuration code a little bit
This commit is contained in:
parent
9be6628bf0
commit
ef9cf289c5
@ -13,7 +13,7 @@ to server.configuration. Every other use case should be read-only."
|
||||
(local utils (require :fennel-ls.utils))
|
||||
(local lint (require :fennel-ls.lint))
|
||||
(local message (require :fennel-ls.message))
|
||||
(local {: view} (require :fennel))
|
||||
(local {: view &as fennel} (require :fennel))
|
||||
|
||||
(local option-mt {})
|
||||
(fn option [default-value ?validate]
|
||||
@ -41,43 +41,43 @@ to server.configuration. Every other use case should be read-only."
|
||||
?root (.. ?root "." extra)
|
||||
extra))
|
||||
|
||||
(fn make-configuration-from-template [template ?user ?parent ?path invalid]
|
||||
(if (= (getmetatable template) option-mt)
|
||||
(let [setting (case-try ?user
|
||||
(fn apply-default-configuration [default ?flsproject ?parent ?name invalid]
|
||||
(if (= (getmetatable default) option-mt)
|
||||
(let [setting (case-try ?flsproject
|
||||
nil (?. ?parent :all)
|
||||
nil template.default-value)]
|
||||
(if (not= (type setting) (type template.default-value))
|
||||
(do (invalid (.. (or ?path "flsproject.fnl") " must be a " (type template.default-value)) ?user ?parent)
|
||||
template.default-value)
|
||||
template.validate
|
||||
(case-try (template.validate setting #(invalid $ ?user ?parent))
|
||||
nil template.default-value)
|
||||
nil default.default-value)]
|
||||
(if (not= (type setting) (type default.default-value))
|
||||
(do (invalid (.. (or ?name "flsproject.fnl") " must be a " (type default.default-value)) ?flsproject ?parent)
|
||||
default.default-value)
|
||||
default.validate
|
||||
(case-try (default.validate setting #(invalid $ ?flsproject ?parent))
|
||||
nil default.default-value)
|
||||
setting))
|
||||
(= :table (type template))
|
||||
(case (type ?user)
|
||||
(= :table (type default))
|
||||
(case (type ?flsproject)
|
||||
(where (or :table :nil))
|
||||
(do
|
||||
(when (= (type ?user) :table)
|
||||
(each [k (pairs ?user)]
|
||||
(when (not (. template k))
|
||||
(invalid (.. "didn't expect " (or (extend-path ?path k) "flsproject.fnl") "\n"
|
||||
"valid keys: " (view (doto (icollect [k (pairs template)] k)
|
||||
(when (= (type ?flsproject) :table)
|
||||
(each [k (pairs ?flsproject)]
|
||||
(when (not (. default k))
|
||||
(invalid (.. "didn't expect " (or (extend-path ?name k) "flsproject.fnl") "\n"
|
||||
"valid keys: " (view (doto (icollect [k (pairs default)] k)
|
||||
table.sort)))
|
||||
(. ?user k)
|
||||
?user))))
|
||||
(collect [k (pairs template)]
|
||||
k (make-configuration-from-template
|
||||
(. template k)
|
||||
(?. ?user k)
|
||||
?user
|
||||
(extend-path ?path k)
|
||||
(. ?flsproject k)
|
||||
?flsproject))))
|
||||
(collect [k (pairs default)]
|
||||
k (apply-default-configuration
|
||||
(. default k)
|
||||
(?. ?flsproject k)
|
||||
?flsproject
|
||||
(extend-path ?name k)
|
||||
invalid)))
|
||||
_ (do (invalid (.. "expected " (or ?path "flsproject.fnl") " to be a table") ?user ?parent)
|
||||
(make-configuration-from-template template nil ?parent ?path invalid)))
|
||||
(error (.. "This is a bug with fennel-ls: default-configuration has a key that isn't a table or option: " ?path))))
|
||||
_ (do (invalid (.. "expected " (or ?name "flsproject.fnl") " to be a table") ?flsproject ?parent)
|
||||
(apply-default-configuration default nil ?parent ?name invalid)))
|
||||
(error (.. "This is a bug with fennel-ls: default-configuration has a key that isn't a table or option: " ?name))))
|
||||
|
||||
(λ make-configuration [?c invalid]
|
||||
(make-configuration-from-template default-configuration ?c nil nil invalid))
|
||||
(λ make-configuration [?flsproject invalid]
|
||||
(apply-default-configuration default-configuration ?flsproject nil nil invalid))
|
||||
|
||||
(λ choose-position-encoding [init-params]
|
||||
"fennel-ls natively uses utf-8, so the goal is to choose positionEncoding=\"utf-8\".
|
||||
@ -92,28 +92,26 @@ However, when not an option, fennel-ls will fall back to positionEncoding=\"utf-
|
||||
(= encoding :utf8)))
|
||||
false)]
|
||||
(if utf8?
|
||||
:utf-8
|
||||
:utf-16)))
|
||||
:utf-8
|
||||
:utf-16)))
|
||||
|
||||
(λ parse-flsconfig [{: text : uri}]
|
||||
(local fennel (require :fennel))
|
||||
(local [ok? _err result] [(pcall (fennel.parser text uri))])
|
||||
(if ok? result))
|
||||
|
||||
(λ load-config [server invalid]
|
||||
"This is where we can put anything that needs to react to config changes"
|
||||
(make-configuration
|
||||
(-?> server.root-uri
|
||||
utils.uri->path
|
||||
(utils.path-join "flsproject.fnl")
|
||||
utils.path->uri
|
||||
(->> (files.read-file server))
|
||||
parse-flsconfig)
|
||||
invalid))
|
||||
(fn flsproject-path [server]
|
||||
(-?> server.root-uri
|
||||
utils.uri->path
|
||||
(utils.path-join "flsproject.fnl")
|
||||
utils.path->uri))
|
||||
|
||||
(λ reload [server]
|
||||
;; clear out macros from fennel
|
||||
(each [k (pairs fennel.macro-loaded)]
|
||||
(tset fennel.macro-loaded k nil))
|
||||
(set server.configuration
|
||||
(load-config server
|
||||
(make-configuration
|
||||
(case-try (flsproject-path server)
|
||||
path (files.read-file server path)
|
||||
{: text : uri} (let [[ok? _err result] [(pcall (fennel.parser text uri))]]
|
||||
(if ok? result))
|
||||
(catch _ nil))
|
||||
;; according to the spec it is valid to send showMessage during initialization
|
||||
;; but eglot will only flash the message briefly before replacing it with
|
||||
;; another message, and probably other clients will do similarly. so queue
|
||||
@ -137,4 +135,5 @@ However, when not an option, fennel-ls will fall back to positionEncoding=\"utf-
|
||||
|
||||
{: initialize
|
||||
: reload
|
||||
: make-configuration}
|
||||
: make-configuration
|
||||
: flsproject-path}
|
||||
|
||||
@ -21,7 +21,9 @@ Every time the client sends a message, it gets handled by a function in the corr
|
||||
(config.initialize server params)
|
||||
(let [capabilities
|
||||
{:positionEncoding server.position-encoding
|
||||
:textDocumentSync {:openClose true :change 2}
|
||||
:textDocumentSync {:openClose true
|
||||
:change 2
|
||||
:save true}
|
||||
;; :notebookDocumentSync nil
|
||||
:completionProvider {:workDoneProgress false
|
||||
:resolveProvider server.can-do-good-completions?
|
||||
@ -229,9 +231,8 @@ Every time the client sends a message, it gets handled by a function in the corr
|
||||
(λ notifications.textDocument/didSave [server _send {:textDocument {: uri}}]
|
||||
(when (utils.endswith uri "flsproject.fnl")
|
||||
(config.reload server))
|
||||
|
||||
;; TODO recompute for files when macro is changed
|
||||
(set fennel.macro-loaded []))
|
||||
(each [k (pairs fennel.macro-loaded)] (tset fennel.macro-loaded k nil)))
|
||||
|
||||
(λ notifications.textDocument/didClose [server _send {:textDocument {: uri}}]
|
||||
(local file (files.get-by-uri server uri))
|
||||
|
||||
@ -775,13 +775,11 @@ You can read more about how to add lints in docs/linting.md"
|
||||
:since :0.2.2-dev
|
||||
:type :other
|
||||
:impl (fn [server file]
|
||||
(when (and (= file.uri (-?> server.root-uri
|
||||
utils.uri->path
|
||||
(utils.path-join "flsproject.fnl")
|
||||
utils.path->uri))
|
||||
(not (. file.diagnostics 1)))
|
||||
;; circular dependency! don't tell anyone ^_^
|
||||
(let [config (require :fennel-ls.config)]
|
||||
(let [config-module :fennel-ls.config
|
||||
config (require config-module)]
|
||||
(when (and (= file.uri (config.flsproject-path server))
|
||||
(not (. file.diagnostics 1)))
|
||||
;; circular dependency! don't tell anyone ^_^
|
||||
(config.make-configuration (. file.ast 1)
|
||||
#(coroutine.yield {:code :invalid-flsproject-settings
|
||||
:range (or (message.ast->range server file $2)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user