aboutsummaryrefslogtreecommitdiff
path: root/fnl/nvrc/macro/set.fnl
diff options
context:
space:
mode:
Diffstat (limited to 'fnl/nvrc/macro/set.fnl')
-rw-r--r--fnl/nvrc/macro/set.fnl79
1 files changed, 79 insertions, 0 deletions
diff --git a/fnl/nvrc/macro/set.fnl b/fnl/nvrc/macro/set.fnl
new file mode 100644
index 0000000..144bdef
--- /dev/null
+++ b/fnl/nvrc/macro/set.fnl
@@ -0,0 +1,79 @@
+(local {: fn? : gensym-checksum : vlua} (require :nvrc.macro.toolkit))
+
+(fn str? [x]
+ (= :string (type x)))
+
+(fn ->str [x]
+ (tostring x))
+
+(fn nil? [x]
+ (= nil x))
+
+(fn includes? [xs x]
+ (accumulate [is? false _ v (ipairs xs) :until is?]
+ (= v x)))
+
+(lambda set! [name ?value]
+ "Set a vim option via the lua API.
+ The name of the option must a symbol.
+ If no value is specified, if the name begins with 'no' the value
+ becomes false, true otherwise."
+ (assert-compile (sym? name) "expected symbol for name" name)
+ (let [name (->str name)
+ value (or ?value (not (name:match "^no")))
+ name (or (name:match "^no(.+)$") name)]
+ (if (fn? value)
+ (let [vsym (gensym-checksum "__" value)]
+ `(do
+ (global ,vsym ,value)
+ (tset vim.opt ,name ,(vlua vsym))))
+ (match (name:sub -1)
+ "+" `(: (. vim.opt ,(name:sub 1 -2)) :append ,value)
+ "-" `(: (. vim.opt ,(name:sub 1 -2)) :remove ,value)
+ "^" `(: (. vim.opt ,(name:sub 1 -2)) :prepend ,value)
+ _ `(tset vim.opt ,name ,value)))))
+
+(lambda setl! [name ?value]
+ "Set a vim local option via the lua API.
+ The name of the option must a symbol.
+ If no value is specified, if the name begins with 'no' the value
+ becomes false, true otherwise."
+ (assert-compile (sym? name) "expected symbol for name" name)
+ (let [name (->str name)
+ value (or ?value
+ (not (name:match "^no")))
+ name (or (name:match "^no(.+)$")
+ name)]
+ (if (fn? value)
+ (let [fsym (gensym-checksum "__" value)]
+ `(do
+ (global ,fsym ,value)
+ (tset vim.opt_local ,name ,(vlua fsym))))
+ (match (name:sub -1)
+ :+ `(: (. vim.opt_local ,(name:sub 1 -2)) :append ,value)
+ :- `(: (. vim.opt_local ,(name:sub 1 -2)) :remove ,value)
+ :^ `(: (. vim.opt_local ,(name:sub 1 -2)) :prepend ,value)
+ _ `(tset vim.opt_local ,name ,value)))))
+
+(lambda setv! [name value]
+ "Set a vim variable via the lua API.
+ The name can be either a symbol or a string.
+ If the name begins with [gbwt] followed by [/:.], the name
+ is scoped to the respective scope."
+ (assert-compile (or (str? name) (sym? name))
+ "expected string or symbol for name" name)
+ (let [name (->str name)
+ scope (when (includes? ["g/" "b/" "w/" "t/"
+ "g." "b." "w." "t."
+ "g:" "b:" "w:" "t:"] (name:sub 1 2))
+ (name:sub 1 1))
+ name (if
+ (nil? scope) name
+ (name:sub 3))]
+ `(tset ,(match scope
+ :b 'vim.b
+ :w 'vim.w
+ :t 'vim.t
+ _ 'vim.g) ,name ,value)))
+
+{: set! : setl! : setv!}