1
This commit is contained in:
Alex Yatskov 2025-01-19 21:08:25 -08:00
parent 4acd690d9e
commit c489fd3202
4 changed files with 90 additions and 93 deletions

View File

@ -1,30 +1,28 @@
ParamCursorCell = require('argonaut.param_cursor_cell') ParamCursorCell = require('argonaut.param_cursor_cell')
ParamRangeCell = require('argonaut.param_range_cell') ParamRangeCell = require('argonaut.param_range_cell')
local Param = {} local Param = {type = 'param'}
Param.__index = Param Param.__index = Param
function Param.new(range, index, cells) function Param.new(range, index, cells)
local param = {range = range, index = index, cells = cells or {}} local param = {
range = range,
index = index,
cells = cells or {},
}
return setmetatable(param, Param) return setmetatable(param, Param)
end end
function Param.new_cursor_cell(cursor) function Param:write(builder, wrapped)
return ParamCursorCell.new(cursor) for i = self:get_start_index(), self:get_stop_index() do
self.cells[i]:write(builder, wrapped)
end end
function Param.new_range_cell(range)
return ParamRangeCell.new(range)
end
function Param:append(cell)
table.insert(self.cells, cell)
end end
function Param:hit_test(cursor) function Param:hit_test(cursor)
-- skip cursor over spaces on the left
local start_index = self:get_start_index() local start_index = self:get_start_index()
local stop_index = self:get_stop_index()
for i = 1, start_index - 1, 1 do for i = 1, start_index - 1, 1 do
local cell = self.cells[i] local cell = self.cells[i]
if cell:hit_test(cursor) then if cell:hit_test(cursor) then
@ -32,6 +30,8 @@ function Param:hit_test(cursor)
end end
end end
-- skip cursor over spaces on the right
local stop_index = self:get_stop_index()
for i = #self.cells, stop_index + 1, -1 do for i = #self.cells, stop_index + 1, -1 do
local cell = self.cells[i] local cell = self.cells[i]
if cell:hit_test(cursor) then if cell:hit_test(cursor) then
@ -43,7 +43,7 @@ function Param:hit_test(cursor)
local trace = cell:hit_test(cursor) local trace = cell:hit_test(cursor)
if trace then if trace then
table.insert(trace, 1, { table.insert(trace, 1, {
type = 'param', type = self.type,
cell_count = #self.cells, cell_count = #self.cells,
cell_index = i - start_index + 1, cell_index = i - start_index + 1,
}) })
@ -55,21 +55,31 @@ end
function Param:hit_search(trace, depth) function Param:hit_search(trace, depth)
local frame = trace[depth] local frame = trace[depth]
assert(frame.type == 'param') assert(frame.type == self.type)
if depth == #trace then if depth == #trace then
return self return self
else else
local index_clamped = frame.cell_index + self:get_start_index() - 1 local unpadded_index = frame.cell_index + self:get_start_index() - 1
assert(index_clamped <= #self.cells) assert(unpadded_index <= #self.cells)
return self.cells[index_clamped]:hit_search(trace, depth + 1) return self.cells[unpadded_index]:hit_search(trace, depth + 1)
end end
end end
function Param:write(builder, wrapped) function Param:is_empty()
for i = self:get_start_index(), self:get_stop_index() do return self:get_start_index() == nil
self.cells[i]:write(builder, wrapped)
end end
function Param:is_contiguous()
for i = self:get_start_index(), self:get_stop_index() - 1 do
local cell = self.cells[i]
local next_cell = self.cells[i + 1]
if cell:get_stop_cursor().row ~= next_cell:get_start_cursor().row then
return false
end
end
return true
end end
function Param:is_before_cursor(cursor) function Param:is_before_cursor(cursor)
@ -84,18 +94,6 @@ function Param:is_after_cursor(cursor)
end end
end end
function Param:get_previous()
if self.index > 1 then
return self.range.params[self.index - 1]
end
end
function Param:get_next()
if self.index < #self.range.params then
return self.range.params[self.index + 1]
end
end
function Param:get_start_cursor() function Param:get_start_cursor()
if #self.cells > 0 then if #self.cells > 0 then
return self.cells[1]:get_start_cursor() return self.cells[1]:get_start_cursor()
@ -108,6 +106,18 @@ function Param:get_stop_cursor()
end end
end end
function Param:get_previous()
if self.index > 1 then
return self.range.params[self.index - 1]
end
end
function Param:get_next()
if self.index < #self.range.params then
return self.range.params[self.index + 1]
end
end
function Param:get_start_index() function Param:get_start_index()
for i = 1, #self.cells do for i = 1, #self.cells do
if not self.cells[i]:is_empty() then if not self.cells[i]:is_empty() then
@ -124,34 +134,6 @@ function Param:get_stop_index()
end end
end end
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]
if cell:get_stop_cursor().row ~= next_cell:get_start_cursor().row then
return false
end
end
return true
end
function Param:is_wrapped()
local previous_param = self:get_previous()
if previous_param then
return previous_param:get_stop_cursor().row ~= self:get_start_cursor().row
else
return self.range.start_cursor.row ~= self:get_start_cursor().row
end
end
function Param:is_empty()
return self:get_start_index() == nil
end
function Param:select(inner) function Param:select(inner)
if #self.cells == 0 then if #self.cells == 0 then
return return
@ -190,4 +172,16 @@ function Param:select(inner)
stop_cursor:set_current() stop_cursor:set_current()
end end
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(cell)
table.insert(self.cells, cell)
end
return Param return Param

View File

@ -1,4 +1,4 @@
local ParamCursorCell = {} local ParamCursorCell = {type = 'param_cursor_cell'}
ParamCursorCell.__index = ParamCursorCell ParamCursorCell.__index = ParamCursorCell
function ParamCursorCell.new(cursor) function ParamCursorCell.new(cursor)
@ -6,25 +6,29 @@ function ParamCursorCell.new(cursor)
return setmetatable(cell, ParamCursorCell) return setmetatable(cell, ParamCursorCell)
end end
function ParamCursorCell:write(builder) function ParamCursorCell:write(builder, _)
builder:write(self.cursor:get_value()) builder:write(self.cursor:get_value())
end end
function ParamCursorCell:hit_test(cursor) function ParamCursorCell:hit_test(cursor)
if self.cursor == cursor then if self.cursor == cursor then
return {{char = self.cursor:get_value(), type = 'cursor_cell'}} return {{char = self.cursor:get_value(), type = self.type}}
end end
end end
function ParamCursorCell:hit_search(trace, depth) function ParamCursorCell:hit_search(trace, depth)
local frame = trace[depth] local frame = trace[depth]
assert(frame.type == 'cursor_cell') assert(frame.type == self.type)
assert(frame.char == self.cursor:get_value()) assert(frame.char == self.cursor:get_value())
assert(depth == #trace) assert(depth == #trace)
return self return self
end end
function ParamCursorCell:is_empty()
return not self.cursor:get_value():match('%S')
end
function ParamCursorCell:is_before_cursor(cursor) function ParamCursorCell:is_before_cursor(cursor)
return self.cursor < cursor return self.cursor < cursor
end end
@ -41,8 +45,4 @@ function ParamCursorCell:get_stop_cursor()
return self.cursor return self.cursor
end end
function ParamCursorCell:is_empty()
return not self.cursor:get_value():match('%S')
end
return ParamCursorCell return ParamCursorCell

View File

@ -1,4 +1,4 @@
local ParamRangeCell = {} local ParamRangeCell = {type = 'param_range_cell'}
ParamRangeCell.__index = ParamRangeCell ParamRangeCell.__index = ParamRangeCell
function ParamRangeCell.new(range) function ParamRangeCell.new(range)
@ -13,11 +13,26 @@ end
function ParamRangeCell:hit_test(cursor) function ParamRangeCell:hit_test(cursor)
local trace = self.range:hit_test(cursor) local trace = self.range:hit_test(cursor)
if trace then if trace then
table.insert(trace, 1, {type = 'range_cell'}) table.insert(trace, 1, {type = self.type})
return trace return trace
end end
end end
function ParamRangeCell:hit_search(trace, depth)
local frame = trace[depth]
assert(frame.type == self.type)
if depth == #trace then
return self
else
return self.range:hit_search(trace, depth + 1)
end
end
function ParamRangeCell:is_empty()
return false
end
function ParamRangeCell:is_before_cursor(cursor) function ParamRangeCell:is_before_cursor(cursor)
return self.range.start_cursor < cursor return self.range.start_cursor < cursor
end end
@ -26,17 +41,6 @@ function ParamRangeCell:is_after_cursor(cursor)
return self.range.stop_cursor > cursor return self.range.stop_cursor > cursor
end end
function ParamRangeCell:hit_search(trace, depth)
local frame = trace[depth]
assert(frame.type == 'range_cell')
if depth == #trace then
return self
else
return self.range:hit_search(trace, depth + 1)
end
end
function ParamRangeCell:get_start_cursor() function ParamRangeCell:get_start_cursor()
return self.range.start_cursor return self.range.start_cursor
end end
@ -45,8 +49,4 @@ function ParamRangeCell:get_stop_cursor()
return self.range.stop_cursor return self.range.stop_cursor
end end
function ParamRangeCell:is_empty()
return false
end
return ParamRangeCell return ParamRangeCell

View File

@ -3,7 +3,7 @@ local Options = require('argonaut.options')
local Pairing = require('argonaut.pairing') local Pairing = require('argonaut.pairing')
local Param = require('argonaut.param') local Param = require('argonaut.param')
local Range = {} local Range = {type = 'range'}
Range.__index = Range Range.__index = Range
local function find_closest_pair(pairing) local function find_closest_pair(pairing)
@ -102,7 +102,7 @@ function Range:parse()
param = Param.new(self, param_index) param = Param.new(self, param_index)
param_index = param_index + 1 param_index = param_index + 1
end end
param:append(cell) param:append_cell(cell)
end end
local append_param = function() local append_param = function()
@ -143,7 +143,7 @@ function Range:hit_test(cursor)
end end
local frame = { local frame = {
type = 'range', type = self.type,
pairing = self.pairing.open .. self.pairing.close, pairing = self.pairing.open .. self.pairing.close,
param_count = #self.params, param_count = #self.params,
param_index = 0, param_index = 0,
@ -178,7 +178,7 @@ end
function Range:hit_search(trace, depth) function Range:hit_search(trace, depth)
local frame = trace[depth] local frame = trace[depth]
assert(frame.type == 'range') assert(frame.type == self.type)
assert(frame.pairing == self.pairing.open .. self.pairing.close) assert(frame.pairing == self.pairing.open .. self.pairing.close)
assert(frame.param_count == #self.params) assert(frame.param_count == #self.params)
assert(frame.param_index <= #self.params) assert(frame.param_index <= #self.params)
@ -267,7 +267,7 @@ function Range:write(builder, wrapped)
end end
function Range:contains_cursor(cursor) function Range:contains_cursor(cursor)
return cursor >= self.start_cursor and cursor <= self.stop_cursor return cursor > self.start_cursor and cursor < self.stop_cursor
end end
function Range:is_contiguous() function Range:is_contiguous()
@ -281,10 +281,13 @@ function Range:is_contiguous()
end end
function Range:is_wrapped() function Range:is_wrapped()
local previous_cursor = self.start_cursor
for _, param in ipairs(self.params) do for _, param in ipairs(self.params) do
if param:is_wrapped() then local cursor = param:get_start_cursor()
if cursor.row ~= previous_cursor.row then
return true return true
end end
previous_cursor = cursor
end end
return false return false