diff options
| author | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 18:44:32 +0200 |
|---|---|---|
| committer | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 18:44:32 +0200 |
| commit | c7b14ffb6d14969c9c41864e827f33f8e80fc24e (patch) | |
| tree | c7c0ac23dc93a4a8b75449d2be4d0e05c4f05f9e /lua/clever_f/destination_engine.lua | |
| parent | 9013636a57144e1f57c9339e7888d588430aae6a (diff) | |
Rename plugin to clever-tee
Diffstat (limited to 'lua/clever_f/destination_engine.lua')
| -rw-r--r-- | lua/clever_f/destination_engine.lua | 201 |
1 files changed, 0 insertions, 201 deletions
diff --git a/lua/clever_f/destination_engine.lua b/lua/clever_f/destination_engine.lua deleted file mode 100644 index 53cb654..0000000 --- a/lua/clever_f/destination_engine.lua +++ /dev/null @@ -1,201 +0,0 @@ -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 - - local bounds = view:match_start_bounds(plan.search_scope, origin) - return { - view = view, - origin = origin, - plan = plan, - count = count, - first_move = first_move, - bounds = bounds, - } -end - -local function candidate_starts(request, origin) - return request.view:iter_strict( - origin, - request.plan.descriptor.direction, - request.bounds - ) -end - -local function regular_destination(request, target_position) - local descriptor = request.plan.descriptor - if descriptor.family == domain.Family.FIND then - return target_position - end - if descriptor.direction == domain.Direction.FORWARD then - return request.view:predecessor(target_position) - end - return request.view:successor(target_position) -end - -local function target_destination(request, target_position) - local descriptor = request.plan.descriptor - if request.plan.endpoint_policy == domain.EndpointPolicy.VISUAL_EXCLUSIVE - and descriptor.direction == domain.Direction.FORWARD - then - if descriptor.family == domain.Family.FIND then - return request.view:successor(target_position) - end - return target_position - end - return regular_destination(request, target_position) -end - -local function strict_destination(descriptor, destination, origin) - local comparison = domain.Position.compare(destination, origin) - if descriptor.direction == domain.Direction.FORWARD then - return comparison > 0 - end - return comparison < 0 -end - -local function acceptable_destination( - request, - destination, - origin, - allow_till_equality -) - local descriptor = request.plan.descriptor - if strict_destination(descriptor, destination, origin) then - return true - end - return descriptor.family == domain.Family.TILL - and allow_till_equality - and domain.Position.equal(destination, origin) -end - -local function next_destination(request, origin, allow_till_equality) - local candidates = candidate_starts(request, origin) - - while true do - local target_position, character = candidates() - if target_position == nil then - return nil - end - if request.plan.target_plan:matches( - character, - target_position, - request.view - ) then - local destination = target_destination(request, target_position) - if destination ~= nil - and acceptable_destination( - request, - destination, - origin, - allow_till_equality - ) - then - return destination - end - end - end -end - -local function till_equality_allowed(request, successful_steps) - return request.first_move and successful_steps == 0 -end - -local function boundary_outcome(request, endpoint, successful_steps) - if successful_steps > 0 then - return domain.SearchOutcome.boundary_after_partial( - endpoint, - successful_steps - ) - end - return domain.SearchOutcome.boundary_before_any(request.origin) -end - -function DestinationEngine:calculate(view, origin, plan, count, first_move) - local request = calculation_inputs(view, origin, plan, count, first_move) - local current_origin = request.origin - local successful_steps = 0 - - while successful_steps < request.count.value do - local destination = next_destination( - request, - current_origin, - till_equality_allowed(request, successful_steps) - ) - if destination == nil then - break - end - current_origin = destination - successful_steps = successful_steps + 1 - end - - if successful_steps == request.count.value then - return domain.SearchOutcome.complete(current_origin, successful_steps) - end - return boundary_outcome(request, current_origin, successful_steps) -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 |
