summaryrefslogtreecommitdiff
path: root/lua/clever_f/repeat_resolver.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/clever_f/repeat_resolver.lua')
-rw-r--r--lua/clever_f/repeat_resolver.lua72
1 files changed, 72 insertions, 0 deletions
diff --git a/lua/clever_f/repeat_resolver.lua b/lua/clever_f/repeat_resolver.lua
new file mode 100644
index 0000000..1b74420
--- /dev/null
+++ b/lua/clever_f/repeat_resolver.lua
@@ -0,0 +1,72 @@
+local domain = require("clever_f.domain")
+local sequence_state = require("clever_f.sequence_state")
+
+local M = {}
+local RepeatResolver = {}
+M.RepeatResolver = RepeatResolver
+
+local resolver_records = setmetatable({}, { __mode = "k" })
+
+local function fail(message, level)
+ error(message, (level or 1) + 1)
+end
+
+local resolver_metatable = {
+ __index = RepeatResolver,
+ __newindex = function()
+ fail("RepeatResolver values are immutable", 2)
+ end,
+ __tostring = function()
+ return "repeat-resolver"
+ end,
+ __metatable = "clever_f.repeat_resolver.RepeatResolver",
+}
+
+function RepeatResolver.new(options)
+ if RepeatResolver.is(options) then
+ return options
+ end
+ if options == nil then
+ options = {}
+ elseif sequence_state.is(options) then
+ options = { state = options }
+ elseif type(options) ~= "table" then
+ fail("RepeatResolver options must be a table", 2)
+ end
+
+ local state = options.state or sequence_state.get()
+ if not sequence_state.is(state) then
+ fail("RepeatResolver state must be the plugin-global SequenceState", 2)
+ end
+
+ local resolver = setmetatable({}, resolver_metatable)
+ resolver_records[resolver] = {
+ state = state,
+ }
+ return resolver
+end
+
+function RepeatResolver.is(value)
+ return type(value) == "table" and resolver_records[value] ~= nil
+end
+
+function RepeatResolver:previous_landing(context)
+ context = domain.ModeContext.from_full_mode(context)
+ return resolver_records[self].state:get_previous_landing(context)
+end
+
+function M.new(options)
+ return RepeatResolver.new(options)
+end
+
+M.landing = function(context, options)
+ return RepeatResolver.new(options):previous_landing(context)
+end
+
+setmetatable(M, {
+ __call = function(_, options)
+ return RepeatResolver.new(options)
+ end,
+})
+
+return M