summaryrefslogtreecommitdiff
path: root/dot_config/nvim/lua/transformer.lua
diff options
context:
space:
mode:
authorChloe Kudryavtsev <code@toast.bunkerlabs.net>2022-11-08 13:06:08 -0500
committerChloe Kudryavtsev <code@toast.bunkerlabs.net>2022-11-08 13:06:08 -0500
commit946b25db1aa005bf072c3c468cb0641cf2fac45d (patch)
tree1afe414f65b2ff978cf3227ee424c21835158672 /dot_config/nvim/lua/transformer.lua
parentgit: update config (diff)
nvim: init bootstrappable config
Diffstat (limited to '')
-rw-r--r--dot_config/nvim/lua/transformer.lua80
1 files changed, 80 insertions, 0 deletions
diff --git a/dot_config/nvim/lua/transformer.lua b/dot_config/nvim/lua/transformer.lua
new file mode 100644
index 0000000..a479826
--- /dev/null
+++ b/dot_config/nvim/lua/transformer.lua
@@ -0,0 +1,80 @@
+--[[
+ Transformer.lua
+ A transforming meta-flow originally built for packer.
+
+ TL;DR you have a function to which you want to eventually pass a table.
+ With this, you can construct the table piece by piece.
+ It will finally call out once you pass () or a string.
+ The string will *prepend* itself to the object.
+
+ Merging rules are a bit complicated:
+ For tables, we merge the ipairs in order (left to right).
+ The final '' is an exception.
+ Then we merge the map-like keys recursively.
+ If the target is a table but the merged key isn't, we append it.
+ Otherwise we always overwrite.
+]]--
+
+---@diagnostic disable-next-line: unused-vararg
+local function tables(...)
+ for i=1,select('#') do
+ if type(select(i)) ~= 'table' then return false end
+ end
+ return true
+end
+
+local function imerge(t1, t2) -- mutates t1
+ for _, v in ipairs(t2) do table.insert(t1, v) end
+end
+
+local bigmerge -- forward declaration
+
+local function kmerge(t1, t2) -- mutates t2
+ for k, v in pairs(t2) do
+ if type(k) == 'number' and k >= 1 and k <= #t1 then
+ -- skip, we did this in imerge
+ else
+ if t1[k] and type(t1[k]) == 'table' then
+ if type(v) == 'table' then
+ t1[k] = bigmerge(t1[k], v)
+ else
+ table.insert(t1[k], v)
+ end
+ else
+ t1[k] = v
+ end
+ end
+ end
+end
+
+bigmerge = function(t1, t2)
+ assert(tables(t1, t2))
+ local out = {}
+ imerge(out, t1)
+ imerge(out, t2)
+ kmerge(out, t1)
+ kmerge(out, t2)
+ return out
+end
+
+local function tgen(use) return function (self, obj)
+ if obj == nil then return use(self) end
+
+ if type(obj) == 'string' then
+ local out = { obj }
+ imerge(out, self)
+ kmerge(out, self)
+ return setmetatable(out, getmetatable(self))()
+ elseif type(obj) == 'table' then
+ local out = bigmerge(self, obj)
+ return setmetatable(out, getmetatable(self))
+
+ else
+ error 'Invalid argument.'
+ end
+
+end end
+
+return function(use)
+ return setmetatable({}, { __call = tgen(use) })
+end