summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua')
-rw-r--r--lua/clever_f/direct_preview_planner.lua72
1 files changed, 61 insertions, 11 deletions
diff --git a/lua/clever_f/direct_preview_planner.lua b/lua/clever_f/direct_preview_planner.lua
index 9a6b0d2..51d7b18 100644
--- a/lua/clever_f/direct_preview_planner.lua
+++ b/lua/clever_f/direct_preview_planner.lua
@@ -1,3 +1,4 @@
+local case_policy = require("clever_f.case_policy")
local domain = require("clever_f.domain")
local text_topology = require("clever_f.text_topology")
@@ -19,14 +20,37 @@ local function require_view(view)
return view
end
-function DirectPreviewPlanner.new()
+local function require_case_resolver(options)
+ options = options or {}
+ if type(options) == "function" then
+ options = { lowercase = options }
+ end
+ if type(options) ~= "table" then
+ fail("DirectPreviewPlanner options must be a table", 3)
+ end
+ local resolver = options.case_resolver
+ if resolver == nil then
+ resolver = case_policy.new({ lowercase = options.lowercase })
+ end
+ if type(resolver) ~= "table" or type(resolver.lowercase) ~= "function" then
+ fail("DirectPreviewPlanner case resolver must provide lowercase", 3)
+ end
+ return resolver
+end
+
+function DirectPreviewPlanner.new(options)
+ if DirectPreviewPlanner.is(options) then
+ return options
+ end
local planner = setmetatable({}, DirectPreviewPlanner)
- planner_records[planner] = true
+ planner_records[planner] = {
+ case_resolver = require_case_resolver(options),
+ }
return planner
end
function DirectPreviewPlanner.is(value)
- return type(value) == "table" and planner_records[value] == true
+ return type(value) == "table" and planner_records[value] ~= nil
end
function DirectPreviewPlanner:scan_current_line(view, origin, direction)
@@ -78,20 +102,40 @@ local function increment_counter(counters, character)
return value
end
-function DirectPreviewPlanner:plan(view, origin, descriptor, count)
+local function require_case_setting(settings, name)
+ local value = settings[name]
+ if value == nil then
+ return false
+ end
+ if type(value) ~= "boolean" then
+ fail("direct preview " .. name .. " must be a Boolean", 3)
+ end
+ return value
+end
+
+function DirectPreviewPlanner:plan(view, origin, descriptor, count, settings)
+ settings = settings or {}
+ if type(settings) ~= "table" then
+ fail("direct preview case settings must be a table", 2)
+ end
+ local ignore_case = require_case_setting(settings, "ignore_case")
local selected_occurrence = self:normalize_count(count)
local counters = {}
local positions = {}
+ local resolver = planner_records[self].case_resolver
for _, record in ipairs(self:scan_for_descriptor(view, origin, descriptor)) do
- if increment_counter(counters, record.character) == selected_occurrence then
+ local counter_key = ignore_case
+ and resolver:lowercase(record.character)
+ or record.character
+ if increment_counter(counters, counter_key) == selected_occurrence then
positions[#positions + 1] = record.position
end
end
return positions
end
-function M.new()
- return DirectPreviewPlanner.new()
+function M.new(options)
+ return DirectPreviewPlanner.new(options)
end
function M.scan_current_line(view, origin, direction)
@@ -102,13 +146,19 @@ function M.scan_for_descriptor(view, origin, descriptor)
return DirectPreviewPlanner.new():scan_for_descriptor(view, origin, descriptor)
end
-function M.plan(view, origin, descriptor, count)
- return DirectPreviewPlanner.new():plan(view, origin, descriptor, count)
+function M.plan(view, origin, descriptor, count, settings, options)
+ return DirectPreviewPlanner.new(options):plan(
+ view,
+ origin,
+ descriptor,
+ count,
+ settings
+ )
end
setmetatable(M, {
- __call = function()
- return DirectPreviewPlanner.new()
+ __call = function(_, options)
+ return DirectPreviewPlanner.new(options)
end,
})