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)
|
|
|
|
local param_cell_cursor = {cursor = cursor}
|
|
|
|
return setmetatable(param_cell_cursor, 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 08:49:53 -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-18 19:11:04 -08:00
|
|
|
|
2025-01-01 18:51:30 -08:00
|
|
|
return self.cursor
|
|
|
|
end
|
|
|
|
|
|
|
|
function ParamCursorCell:get_start_row()
|
|
|
|
return self.cursor.row
|
|
|
|
end
|
|
|
|
|
|
|
|
function ParamCursorCell:get_stop_row()
|
|
|
|
return self.cursor.row
|
|
|
|
end
|
|
|
|
|
|
|
|
function ParamCursorCell:is_empty()
|
|
|
|
return not self.cursor:get_value():match('%S')
|
|
|
|
end
|
|
|
|
|
|
|
|
local ParamRangeCell = {}
|
|
|
|
ParamRangeCell.__index = ParamRangeCell
|
|
|
|
|
|
|
|
function ParamRangeCell.new(range)
|
|
|
|
local param_cell_range = {range = range}
|
|
|
|
return setmetatable(param_cell_range, ParamRangeCell)
|
|
|
|
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
|
|
|
|
|
|
|
|
function ParamRangeCell:hit_search(trace, depth)
|
2025-01-18 19:11:04 -08:00
|
|
|
local frame = trace[depth]
|
|
|
|
assert(frame.type == 'range_cell')
|
|
|
|
|
|
|
|
return self.range:hit_search(trace, depth + 1)
|
2025-01-01 18:51:30 -08:00
|
|
|
end
|
|
|
|
|
|
|
|
function ParamRangeCell:get_start_row()
|
|
|
|
return self.range.start_cursor.row
|
|
|
|
end
|
2024-12-30 20:31:50 -08:00
|
|
|
|
2025-01-01 18:51:30 -08:00
|
|
|
function ParamRangeCell:get_stop_row()
|
|
|
|
return self.range.stop_cursor.row
|
|
|
|
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 08:49:53 -08:00
|
|
|
local index_begin = self:find_index_begin()
|
|
|
|
local index_end = self:find_index_end()
|
|
|
|
|
|
|
|
for i = 1, index_begin - 1, 1 do
|
|
|
|
local cell = self.cells[i]
|
|
|
|
local trace = cell:hit_test(cursor)
|
|
|
|
if trace then
|
|
|
|
cursor = cursor:get_next()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
for i = #self.cells, index_end + 1, -1 do
|
|
|
|
local cell = self.cells[i]
|
2025-01-01 18:51:30 -08:00
|
|
|
local trace = cell:hit_test(cursor)
|
2024-12-30 20:31:50 -08:00
|
|
|
if trace 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 08:49:53 -08:00
|
|
|
cell_index = i - index_begin + 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-18 20:07:08 -08:00
|
|
|
local index_clamped = frame.cell_index + self:find_index_begin() - 1
|
|
|
|
assert(index_clamped <= #self.cells)
|
|
|
|
|
|
|
|
return self.cells[index_clamped]:hit_search(trace, depth + 1)
|
2024-12-30 20:31:50 -08:00
|
|
|
end
|
|
|
|
|
|
|
|
function Param:write(builder, wrapped)
|
|
|
|
for i = self:find_index_begin(), self:find_index_end() 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-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
|
|
|
|
|
|
|
|
function Param:get_start_row()
|
|
|
|
if #self.cells > 0 then
|
|
|
|
return self.cells[1]:get_start_row()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Param:get_stop_row()
|
|
|
|
if #self.cells > 0 then
|
|
|
|
return self.cells[#self.cells]:get_stop_row()
|
2024-12-31 10:05:01 -08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-12-30 20:31:50 -08:00
|
|
|
function Param:find_index_begin()
|
|
|
|
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
|
|
|
|
|
|
|
|
function Param:find_index_end()
|
|
|
|
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-01 18:51:30 -08:00
|
|
|
function Param:is_wrapped()
|
|
|
|
local previous_param = self:get_previous()
|
|
|
|
if previous_param then
|
|
|
|
return previous_param:get_stop_row() ~= self:get_start_row()
|
|
|
|
else
|
|
|
|
return self.range.start_cursor.row ~= self:get_start_row()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-12-30 20:31:50 -08:00
|
|
|
function Param:is_empty()
|
|
|
|
return self:find_index_begin() == nil
|
|
|
|
end
|
|
|
|
|
|
|
|
return Param
|