summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/clever_f/repeat_resolver.lua48
-rw-r--r--tests/run.lua18
2 files changed, 64 insertions, 2 deletions
diff --git a/lua/clever_f/repeat_resolver.lua b/lua/clever_f/repeat_resolver.lua
index 4cb1294..fbb50c6 100644
--- a/lua/clever_f/repeat_resolver.lua
+++ b/lua/clever_f/repeat_resolver.lua
@@ -28,9 +28,10 @@ end
local function require_policy(service)
if service ~= nil and (type(service) ~= "table"
- or type(service.sample_timeouts) ~= "function")
+ or type(service.sample_timeouts) ~= "function"
+ or type(service.sample_direction) ~= "function")
then
- fail("RepeatResolver policy must provide sample_timeouts", 3)
+ fail("RepeatResolver policy must sample timeouts and direction", 3)
end
return service
end
@@ -181,6 +182,49 @@ end
RepeatResolver.check_timeout = RepeatResolver.evaluate_timeout
RepeatResolver.resolve_timeout = RepeatResolver.evaluate_timeout
+local function sampled_fixed_direction(resolver)
+ local service = resolver_records[resolver].policy
+ if service == nil then
+ fail("RepeatResolver requires a policy to resolve primary direction", 3)
+ end
+ local sampled = service:sample_direction()
+ local fixed
+ if type(sampled) == "table" then
+ fixed = sampled.fix_key_direction
+ end
+ if type(fixed) ~= "boolean" then
+ fail("fix_key_direction sample must be a Boolean", 3)
+ end
+ return fixed
+end
+
+function M.primary_direction(stored_descriptor, pressed_key, fix_key_direction)
+ local stored = domain.Descriptor.from_string(stored_descriptor)
+ local pressed = domain.Descriptor.from_string(pressed_key)
+ if type(fix_key_direction) ~= "boolean" then
+ fail("fix_key_direction must be a Boolean", 2)
+ end
+ if not fix_key_direction and domain.Descriptor.is_lowercase(pressed) then
+ return stored
+ end
+ return nil
+end
+
+M.resolve_primary_direction = M.primary_direction
+M.effective_primary_descriptor = M.primary_direction
+
+function RepeatResolver:resolve_primary_direction(stored_descriptor, pressed_key)
+ return M.primary_direction(
+ stored_descriptor,
+ pressed_key,
+ sampled_fixed_direction(self)
+ )
+end
+
+RepeatResolver.primary_direction = RepeatResolver.resolve_primary_direction
+RepeatResolver.effective_primary_descriptor =
+ RepeatResolver.resolve_primary_direction
+
function M.new(options)
return RepeatResolver.new(options)
end
diff --git a/tests/run.lua b/tests/run.lua
index 7e5659a..19568fa 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -3989,6 +3989,24 @@ test("Expired repeat applies Public Reset and requests acquisition", function()
same("char-current", cleanup.target_overlays[1].identity)
end)
+test("Relative lower-case keys use the stored descriptor", function()
+ fresh_sequence_state()
+ local host = MemoryHost.new({
+ configuration = { fix_key_direction = false },
+ })
+ local resolver = repeat_resolver.new({ policy = policy.new(host) })
+
+ for _, stored in ipairs({ "f", "F", "t", "T" }) do
+ for _, pressed in ipairs({ "f", "t" }) do
+ same(
+ domain.Descriptor.from_string(stored),
+ resolver:resolve_primary_direction(stored, pressed),
+ stored .. "/" .. pressed
+ )
+ end
+ end
+end)
+
for _, item in ipairs(tests) do
local ok, failure = xpcall(item.body, debug.traceback)
if not ok then