1

289 lines
7.0 KiB
Lua
Raw Normal View History

2025-01-01 18:51:30 -08:00
local ParamCursorCell = {}
ParamCursorCell.__index = ParamCursorCell
2024-12-30 20:31:50 -08:00
2025-01-01 18:51:30 -08:00
function ParamCursorCell.new(cursor)
2025-01-19 10:52:37 -08:00
local cell = {cursor = cursor}
return setmetatable(cell, ParamCursorCell)
2024-12-30 20:31:50 -08:00
end
2025-01-01 18:51:30 -08:00
function ParamCursorCell:write(builder)
builder:write(self.cursor:get_value())
2024-12-31 10:05:01 -08:00
end
2025-01-01 18:51:30 -08:00
function ParamCursorCell:hit_test(cursor)
if self.cursor == cursor then
2025-01-19 10:52:37 -08:00
return {{char = self.cursor:get_value(), type = 'cursor_cell'}}
2024-12-31 10:05:01 -08:00
end
end
2025-01-18 19:11:04 -08:00
function ParamCursorCell:hit_search(trace, depth)
local frame = trace[depth]
assert(frame.type == 'cursor_cell')
2025-01-19 08:49:53 -08:00
assert(frame.char == self.cursor:get_value())
2025-01-19 09:49:45 -08:00
assert(depth == #trace)
2025-01-18 19:11:04 -08:00
2025-01-19 09:49:45 -08:00
return self
end
function ParamCursorCell:is_before_cursor(cursor)
return self.cursor < cursor
end
function ParamCursorCell:is_after_cursor(cursor)
return self.cursor > cursor
2025-01-01 18:51:30 -08:00
end
2025-01-19 17:04:20 -08:00
function ParamCursorCell:get_start_cursor()
return self.cursor
2025-01-01 18:51:30 -08:00
end
2025-01-19 17:04:20 -08:00
function ParamCursorCell:get_stop_cursor()
return self.cursor
2025-01-01 18:51:30 -08:00
end
function ParamCursorCell:is_empty()
return not self.cursor:get_value():match('%S')
end
local ParamRangeCell = {}
ParamRangeCell.__index = ParamRangeCell
function ParamRangeCell.new(range)
2025-01-19 10:52:37 -08:00
local cell = {range = range}
return setmetatable(cell, ParamRangeCell)
2025-01-01 18:51:30 -08:00
end
function ParamRangeCell:write(builder, wrapped)
self.range:write(builder, wrapped)
end
function ParamRangeCell:hit_test(cursor)
2025-01-18 19:11:04 -08:00
local trace = self.range:hit_test(cursor)
if trace then
table.insert(trace, 1, {type = 'range_cell'})
return trace
end
2025-01-01 18:51:30 -08:00
end
2025-01-19 09:49:45 -08:00
function ParamRangeCell:is_before_cursor(cursor)
return self.range.start_cursor < cursor
end
function ParamRangeCell:is_after_cursor(cursor)
return self.range.stop_cursor > cursor
end
2025-01-01 18:51:30 -08:00
function ParamRangeCell:hit_search(trace, depth)
2025-01-18 19:11:04 -08:00
local frame = trace[depth]
assert(frame.type == 'range_cell')
2025-01-19 09:49:45 -08:00
if depth == #trace then
return self
else
return self.range:hit_search(trace, depth + 1)
end
2025-01-01 18:51:30 -08:00
end
2025-01-19 17:04:20 -08:00
function ParamRangeCell:get_start_cursor()
return self.range.start_cursor
2025-01-01 18:51:30 -08:00
end
2024-12-30 20:31:50 -08:00
2025-01-19 17:04:20 -08:00
function ParamRangeCell:get_stop_cursor()
return self.range.stop_cursor
2025-01-01 18:51:30 -08:00
end
function ParamRangeCell:is_empty()
return false
end
local Param = {}
Param.__index = Param
function Param.new(range, index, cells)
local param = {range = range, index = index, cells = cells or {}}
2024-12-30 20:31:50 -08:00
return setmetatable(param, Param)
end
2025-01-01 18:51:30 -08:00
function Param.new_cursor_cell(cursor)
return ParamCursorCell.new(cursor)
end
function Param.new_range_cell(range)
return ParamRangeCell.new(range)
end
function Param:append(cell)
table.insert(self.cells, cell)
2024-12-30 20:31:50 -08:00
end
function Param:hit_test(cursor)
2025-01-19 10:52:37 -08:00
local start_index = self:get_start_index()
local stop_index = self:get_stop_index()
2025-01-19 08:49:53 -08:00
2025-01-19 10:52:37 -08:00
for i = 1, start_index - 1, 1 do
2025-01-19 08:49:53 -08:00
local cell = self.cells[i]
2025-01-19 10:35:27 -08:00
if cell:hit_test(cursor) then
2025-01-19 08:49:53 -08:00
cursor = cursor:get_next()
end
end
2025-01-19 10:52:37 -08:00
for i = #self.cells, stop_index + 1, -1 do
2025-01-19 08:49:53 -08:00
local cell = self.cells[i]
2025-01-19 10:35:27 -08:00
if cell:hit_test(cursor) then
2025-01-19 08:49:53 -08:00
cursor = cursor:get_previous()
end
end
2025-01-18 20:07:08 -08:00
2025-01-19 08:49:53 -08:00
for i, cell in ipairs(self.cells) do
local trace = cell:hit_test(cursor)
if trace then
2025-01-18 18:24:01 -08:00
table.insert(trace, 1, {
2025-01-18 19:25:38 -08:00
type = 'param',
cell_count = #self.cells,
2025-01-19 10:52:37 -08:00
cell_index = i - start_index + 1,
2025-01-18 18:24:01 -08:00
})
2024-12-30 20:31:50 -08:00
return trace
end
end
end
function Param:hit_search(trace, depth)
2025-01-18 18:24:01 -08:00
local frame = trace[depth]
2025-01-18 19:25:38 -08:00
assert(frame.type == 'param')
2025-01-18 19:11:04 -08:00
2025-01-19 09:49:45 -08:00
if depth == #trace then
return self
else
2025-01-19 10:52:37 -08:00
local index_clamped = frame.cell_index + self:get_start_index() - 1
2025-01-19 09:49:45 -08:00
assert(index_clamped <= #self.cells)
return self.cells[index_clamped]:hit_search(trace, depth + 1)
end
2024-12-30 20:31:50 -08:00
end
function Param:write(builder, wrapped)
2025-01-19 10:52:37 -08:00
for i = self:get_start_index(), self:get_stop_index() do
2025-01-01 18:51:30 -08:00
self.cells[i]:write(builder, wrapped)
2024-12-30 20:31:50 -08:00
end
end
2025-01-19 09:49:45 -08:00
function Param:is_before_cursor(cursor)
if #self.cells > 0 then
return self.cells[1]:is_before_cursor(cursor)
end
end
function Param:is_after_cursor(cursor)
if #self.cells > 0 then
return self.cells[#self.cells]:is_after_cursor(cursor)
end
end
2025-01-01 18:51:30 -08:00
function Param:get_previous()
if self.index > 1 then
return self.range.params[self.index - 1]
2024-12-31 10:05:01 -08:00
end
end
2025-01-01 18:51:30 -08:00
function Param:get_next()
if self.index < #self.range.params then
return self.range.params[self.index + 1]
end
end
2025-01-19 17:04:20 -08:00
function Param:get_start_cursor()
2025-01-01 18:51:30 -08:00
if #self.cells > 0 then
2025-01-19 17:04:20 -08:00
return self.cells[1]:get_start_cursor()
2025-01-01 18:51:30 -08:00
end
end
2025-01-19 17:04:20 -08:00
function Param:get_stop_cursor()
2025-01-01 18:51:30 -08:00
if #self.cells > 0 then
2025-01-19 17:04:20 -08:00
return self.cells[#self.cells]:get_stop_cursor()
2024-12-31 10:05:01 -08:00
end
end
2025-01-19 10:52:37 -08:00
function Param:get_start_index()
2024-12-30 20:31:50 -08:00
for i = 1, #self.cells do
2025-01-01 18:51:30 -08:00
if not self.cells[i]:is_empty() then
2024-12-30 20:31:50 -08:00
return i
end
end
end
2025-01-19 10:52:37 -08:00
function Param:get_stop_index()
2024-12-30 20:31:50 -08:00
for i = #self.cells, 1, -1 do
2025-01-01 18:51:30 -08:00
if not self.cells[i]:is_empty() then
2024-12-30 20:31:50 -08:00
return i
end
end
end
2025-01-19 10:52:37 -08:00
function Param:is_contiguous()
local start_index = self:get_start_index()
local stop_index = self:get_stop_index()
for i = start_index, stop_index - 1 do
local cell = self.cells[i]
local next_cell = self.cells[i + 1]
2025-01-19 17:04:20 -08:00
if cell:get_stop_cursor().row ~= next_cell:get_start_cursor().row then
2025-01-19 10:52:37 -08:00
return false
end
end
return true
end
2025-01-01 18:51:30 -08:00
function Param:is_wrapped()
local previous_param = self:get_previous()
if previous_param then
2025-01-19 17:04:20 -08:00
return previous_param:get_stop_cursor().row ~= self:get_start_cursor().row
2025-01-01 18:51:30 -08:00
else
2025-01-19 17:04:20 -08:00
return self.range.start_cursor.row ~= self:get_start_cursor().row
2025-01-01 18:51:30 -08:00
end
end
2024-12-30 20:31:50 -08:00
function Param:is_empty()
2025-01-19 10:52:37 -08:00
return self:get_start_index() == nil
2024-12-30 20:31:50 -08:00
end
2025-01-19 17:04:20 -08:00
function Param:select(inner)
if #self.cells == 0 then
return
end
local start_cursor = nil
local stop_cursor = nil
if inner then
local start_index = self:get_start_index()
start_cursor = self.cells[start_index]:get_start_cursor()
2025-01-19 18:09:00 -08:00
local stop_index = self:get_stop_index()
2025-01-19 17:04:20 -08:00
stop_cursor = self.cells[stop_index]:get_stop_cursor()
else
local previous_param = self:get_previous()
if previous_param then
2025-01-19 18:09:00 -08:00
local stop_index = previous_param:get_stop_index()
start_cursor = previous_param.cells[stop_index]:get_stop_cursor():get_next()
2025-01-19 19:28:15 -08:00
stop_cursor = self.cells[#self.cells]:get_stop_cursor()
2025-01-19 17:04:20 -08:00
else
local next_param = self:get_next()
if next_param then
2025-01-19 18:09:00 -08:00
local start_index = next_param:get_start_index()
2025-01-19 19:28:15 -08:00
start_cursor = self.cells[1]:get_start_cursor()
2025-01-19 18:09:00 -08:00
stop_cursor = next_param.cells[start_index]:get_start_cursor():get_previous()
else
start_cursor = self.range.start_cursor:get_next()
stop_cursor = self.range.stop_cursor:get_previous()
2025-01-19 17:04:20 -08:00
end
end
end
start_cursor:set_current()
vim.cmd(string.format(':normal! v'))
stop_cursor:set_current()
end
2024-12-30 20:31:50 -08:00
return Param