about summary refs log tree commit diff
path: root/fnl/nvrc/macro/set.fnl
blob: 144bdef3596e77ea6ec89f067dab5b3b133ca59a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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!}