diff options
| author | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 10:18:07 +0200 |
|---|---|---|
| committer | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 10:18:07 +0200 |
| commit | e8271f4b75e50983e82fba4155be0bd09e0251d7 (patch) | |
| tree | cb2de41d56896f5e638d740d65cdf4554dac0804 /lua/clever_f/destination_engine.lua | |
| parent | 14675353d21a63815901a729e3230d5928550868 (diff) | |
Define destination engine inputs
Diffstat (limited to 'lua/clever_f/destination_engine.lua')
| -rw-r--r-- | lua/clever_f/destination_engine.lua | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/lua/clever_f/destination_engine.lua b/lua/clever_f/destination_engine.lua new file mode 100644 index 0000000..c7345d5 --- /dev/null +++ b/lua/clever_f/destination_engine.lua @@ -0,0 +1,83 @@ +local domain = require("clever_f.domain") +local text_topology = require("clever_f.text_topology") + +local M = {} +local DestinationEngine = {} +M.DestinationEngine = DestinationEngine + +local engines = setmetatable({}, { __mode = "k" }) + +local function fail(message, level) + error(message, (level or 1) + 1) +end + +local engine_metatable = { + __index = DestinationEngine, + __newindex = function() + fail("DestinationEngine values are immutable", 2) + end, + __tostring = function() + return "destination-engine" + end, + __metatable = "clever_f.destination_engine.DestinationEngine", +} + +function DestinationEngine.new() + local engine = setmetatable({}, engine_metatable) + engines[engine] = true + return engine +end + +function DestinationEngine.is(value) + return type(value) == "table" and engines[value] == true +end + +local function calculation_inputs(view, origin, plan, count, first_move) + if not text_topology.TextView.is(view) then + fail("destination calculation view must be a TextView", 3) + end + + origin = domain.Position.coerce(origin) + if not view:is_valid_cursor_position(origin) then + fail("destination calculation origin must be a valid cursor position", 3) + end + if not domain.ResolvedMotionPlan.is(plan) then + fail("destination calculation plan must be a ResolvedMotionPlan", 3) + end + count = domain.Count.new(count) + if type(first_move) ~= "boolean" then + fail("destination calculation first_move must be a Boolean", 3) + end + + return { + view = view, + origin = origin, + plan = plan, + count = count, + first_move = first_move, + } +end + +function DestinationEngine:calculate(view, origin, plan, count, first_move) + local request = calculation_inputs(view, origin, plan, count, first_move) + return domain.SearchOutcome.boundary_before_any(request.origin) +end + +function M.new() + return DestinationEngine.new() +end + +function M.calculate(view, origin, plan, count, first_move) + return DestinationEngine.new():calculate(view, origin, plan, count, first_move) +end + +M.resolve = M.calculate +M.search = M.calculate + +setmetatable(M, { + __call = function() + return DestinationEngine.new() + end, +}) + +return M |
