diff options
Diffstat (limited to 'lua/clever_f/sequence_state.lua')
| -rw-r--r-- | lua/clever_f/sequence_state.lua | 302 |
1 files changed, 0 insertions, 302 deletions
diff --git a/lua/clever_f/sequence_state.lua b/lua/clever_f/sequence_state.lua deleted file mode 100644 index e31752d..0000000 --- a/lua/clever_f/sequence_state.lua +++ /dev/null @@ -1,302 +0,0 @@ -local domain = require("clever_f.domain") - -local M = {} -local State = {} -M.State = State - -local MAP_FIELDS = { - "previous_descriptor", - "previous_landing", - "first_move", - "previous_target", -} - -local MAP_FIELD_SET = {} -for _, field in ipairs(MAP_FIELDS) do - MAP_FIELD_SET[field] = true -end - -local data = { - previous_descriptor = {}, - previous_landing = {}, - first_move = {}, - previous_target = {}, - known_contexts = {}, - last_input_context = nil, - moved_forward = false, - moved_forward_initialized = false, - migemo_cache = {}, - repeat_timestamp_ms = 0, - highlight_timer = nil, - target_overlays = {}, - temporary_overlays = {}, - finalizers = {}, -} - -local function fail(message, level) - error(message, (level or 1) + 1) -end - -local function normalize_context(context, name) - if domain.ModeContext.is(context) then - return domain.ModeContext.from_full_mode(context.full_mode) - end - if type(context) ~= "string" or context == "" then - fail((name or "context") .. " must be a ModeContext or full mode string", 2) - end - return domain.ModeContext.from_full_mode(context) -end - -local function copy_map(source) - local result = {} - for key, value in pairs(source) do - result[key] = value - end - return result -end - -local function copy_resource(resource) - local result = {} - for key, value in pairs(resource) do - result[key] = value - end - return result -end - -local function copy_resources(resources) - local result = {} - for index, resource in ipairs(resources) do - result[index] = copy_resource(resource) - end - return result -end - -local function sorted_contexts() - local result = {} - for context in pairs(data.known_contexts) do - result[#result + 1] = context - end - table.sort(result, function(left, right) - return left.key < right.key - end) - return result -end - -local function context_record(context) - return { - context = context, - previous_descriptor = data.previous_descriptor[context], - previous_landing = data.previous_landing[context], - first_move = data.first_move[context], - previous_target = data.previous_target[context], - } -end - -local function context_records() - local result = {} - for _, context in ipairs(sorted_contexts()) do - result[context.key] = context_record(context) - end - return result -end - -function State:get_previous_descriptor(context) - context = normalize_context(context) - return data.previous_descriptor[context] -end - -function State:get_previous_landing(context) - context = normalize_context(context) - return data.previous_landing[context] -end - -function State:get_first_move(context) - context = normalize_context(context) - return data.first_move[context] -end - -function State:get_previous_target(context) - context = normalize_context(context) - return data.previous_target[context] -end - -function State:get_context(context) - context = normalize_context(context) - return context_record(context) -end - -State.context = State.get_context - -function State:has_previous_landing(context) - return self:get_previous_landing(context) ~= nil -end - -function State:get_migemo(encoding) - if type(encoding) ~= "string" or encoding == "" then - fail("encoding must be a nonempty string", 2) - end - return data.migemo_cache[encoding] -end - -function State:target_overlay_identities() - local result = {} - for index, resource in ipairs(data.target_overlays) do - result[index] = resource.identity - end - return result -end - -function State:temporary_overlay_identities() - local result = {} - for index, resource in ipairs(data.temporary_overlays) do - result[index] = resource.identity - end - return result -end - -function State:finalizer_identities() - local result = {} - for index, resource in ipairs(data.finalizers) do - result[index] = resource.identity - end - return result -end - -function State:resources() - return { - highlight_timer = data.highlight_timer, - target_overlays = copy_resources(data.target_overlays), - temporary_overlays = copy_resources(data.temporary_overlays), - finalizers = copy_resources(data.finalizers), - } -end - -function State:snapshot() - local snapshot = { - contexts = context_records(), - last_input_context = data.last_input_context, - moved_forward = data.moved_forward, - moved_forward_initialized = data.moved_forward_initialized, - migemo_cache = copy_map(data.migemo_cache), - repeat_timestamp_ms = data.repeat_timestamp_ms, - highlight_timer = data.highlight_timer, - target_overlays = copy_resources(data.target_overlays), - temporary_overlays = copy_resources(data.temporary_overlays), - finalizers = copy_resources(data.finalizers), - } - for _, field in ipairs(MAP_FIELDS) do - snapshot[field] = copy_map(data[field]) - end - return snapshot -end - -local function target_to_table(target) - return target and target:to_table() or nil -end - -function State:to_table() - local contexts = {} - for _, context in ipairs(sorted_contexts()) do - local record = context_record(context) - contexts[context.key] = { - previous_descriptor = record.previous_descriptor - and record.previous_descriptor.value - or nil, - previous_landing = record.previous_landing - and record.previous_landing:to_table() - or nil, - first_move = record.first_move, - previous_target = target_to_table(record.previous_target), - } - end - - local cache_keys = {} - for encoding in pairs(data.migemo_cache) do - cache_keys[#cache_keys + 1] = encoding - end - table.sort(cache_keys) - - return { - contexts = contexts, - last_input_context = data.last_input_context and data.last_input_context.key or nil, - moved_forward = data.moved_forward, - moved_forward_initialized = data.moved_forward_initialized, - migemo_cache = cache_keys, - repeat_timestamp_ms = data.repeat_timestamp_ms, - highlight_timer = data.highlight_timer, - target_overlays = self:target_overlay_identities(), - temporary_overlays = self:temporary_overlay_identities(), - finalizers = self:finalizer_identities(), - } -end - -local state -local state_metatable = { - __index = function(_, key) - local method = State[key] - if method ~= nil then - return method - end - if MAP_FIELD_SET[key] then - return copy_map(data[key]) - end - if key == "contexts" then - return context_records() - end - if key == "last_input_context" - or key == "moved_forward" - or key == "moved_forward_initialized" - or key == "highlight_timer" - then - return data[key] - end - if key == "repeat_timestamp" or key == "repeat_timestamp_ms" then - return data.repeat_timestamp_ms - end - if key == "migemo_cache" then - return copy_map(data.migemo_cache) - end - if key == "target_overlays" - or key == "temporary_overlays" - or key == "finalizers" - then - return copy_resources(data[key]) - end - return nil - end, - __newindex = function() - fail("SequenceState is read-only; use StateTransitions", 2) - end, - __metatable = "clever_f.sequence_state.State", -} -state = setmetatable({}, state_metatable) - -function M.get() - return state -end - -function M.new() - return state -end - -function M.is(value) - return value == state -end - -M.global = state - -function M._mutate(target, mutation) - if target ~= state then - fail("StateTransitions must use the plugin-global SequenceState", 2) - end - if type(mutation) ~= "function" then - fail("state mutation must be a function", 2) - end - return mutation(data) -end - -function M._normalize_context(context) - return normalize_context(context) -end - -return M |
