diff --git a/lua/argonaut/param.lua b/lua/argonaut/param.lua index 53e3b31..d3aa0b2 100644 --- a/lua/argonaut/param.lua +++ b/lua/argonaut/param.lua @@ -1,30 +1,28 @@ ParamCursorCell = require('argonaut.param_cursor_cell') ParamRangeCell = require('argonaut.param_range_cell') -local Param = {} +local Param = {type = 'param'} Param.__index = Param 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) 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) - table.insert(self.cells, cell) +function Param:write(builder, wrapped) + for i = self:get_start_index(), self:get_stop_index() do + self.cells[i]:write(builder, wrapped) + end end function Param:hit_test(cursor) + -- skip cursor over spaces on the left local start_index = self:get_start_index() - local stop_index = self:get_stop_index() - for i = 1, start_index - 1, 1 do local cell = self.cells[i] if cell:hit_test(cursor) then @@ -32,6 +30,8 @@ function Param:hit_test(cursor) 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 local cell = self.cells[i] if cell:hit_test(cursor) then @@ -43,7 +43,7 @@ function Param:hit_test(cursor) local trace = cell:hit_test(cursor) if trace then table.insert(trace, 1, { - type = 'param', + type = self.type, cell_count = #self.cells, cell_index = i - start_index + 1, }) @@ -55,21 +55,31 @@ end function Param:hit_search(trace, depth) local frame = trace[depth] - assert(frame.type == 'param') + assert(frame.type == self.type) if depth == #trace then return self else - local index_clamped = frame.cell_index + self:get_start_index() - 1 - assert(index_clamped <= #self.cells) - return self.cells[index_clamped]:hit_search(trace, depth + 1) + local unpadded_index = frame.cell_index + self:get_start_index() - 1 + assert(unpadded_index <= #self.cells) + return self.cells[unpadded_index]:hit_search(trace, depth + 1) end end -function Param:write(builder, wrapped) - for i = self:get_start_index(), self:get_stop_index() do - self.cells[i]:write(builder, wrapped) +function Param:is_empty() + return self:get_start_index() == nil +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 function Param:is_before_cursor(cursor) @@ -84,18 +94,6 @@ function Param:is_after_cursor(cursor) 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() if #self.cells > 0 then return self.cells[1]:get_start_cursor() @@ -108,6 +106,18 @@ function Param:get_stop_cursor() 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() for i = 1, #self.cells do if not self.cells[i]:is_empty() then @@ -124,34 +134,6 @@ function Param:get_stop_index() 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) if #self.cells == 0 then return @@ -190,4 +172,16 @@ function Param:select(inner) stop_cursor:set_current() 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 diff --git a/lua/argonaut/param_cursor_cell.lua b/lua/argonaut/param_cursor_cell.lua index 7fc9c3b..532288b 100644 --- a/lua/argonaut/param_cursor_cell.lua +++ b/lua/argonaut/param_cursor_cell.lua @@ -1,4 +1,4 @@ -local ParamCursorCell = {} +local ParamCursorCell = {type = 'param_cursor_cell'} ParamCursorCell.__index = ParamCursorCell function ParamCursorCell.new(cursor) @@ -6,25 +6,29 @@ function ParamCursorCell.new(cursor) return setmetatable(cell, ParamCursorCell) end -function ParamCursorCell:write(builder) +function ParamCursorCell:write(builder, _) builder:write(self.cursor:get_value()) end function ParamCursorCell:hit_test(cursor) 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 function ParamCursorCell:hit_search(trace, depth) local frame = trace[depth] - assert(frame.type == 'cursor_cell') + assert(frame.type == self.type) assert(frame.char == self.cursor:get_value()) assert(depth == #trace) return self end +function ParamCursorCell:is_empty() + return not self.cursor:get_value():match('%S') +end + function ParamCursorCell:is_before_cursor(cursor) return self.cursor < cursor end @@ -41,8 +45,4 @@ function ParamCursorCell:get_stop_cursor() return self.cursor end -function ParamCursorCell:is_empty() - return not self.cursor:get_value():match('%S') -end - return ParamCursorCell diff --git a/lua/argonaut/param_range_cell.lua b/lua/argonaut/param_range_cell.lua index 2481294..01d8fe0 100644 --- a/lua/argonaut/param_range_cell.lua +++ b/lua/argonaut/param_range_cell.lua @@ -1,4 +1,4 @@ -local ParamRangeCell = {} +local ParamRangeCell = {type = 'param_range_cell'} ParamRangeCell.__index = ParamRangeCell function ParamRangeCell.new(range) @@ -13,11 +13,26 @@ end function ParamRangeCell:hit_test(cursor) local trace = self.range:hit_test(cursor) if trace then - table.insert(trace, 1, {type = 'range_cell'}) + table.insert(trace, 1, {type = self.type}) return trace 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) return self.range.start_cursor < cursor end @@ -26,17 +41,6 @@ function ParamRangeCell:is_after_cursor(cursor) return self.range.stop_cursor > cursor 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() return self.range.start_cursor end @@ -45,8 +49,4 @@ function ParamRangeCell:get_stop_cursor() return self.range.stop_cursor end -function ParamRangeCell:is_empty() - return false -end - return ParamRangeCell diff --git a/lua/argonaut/range.lua b/lua/argonaut/range.lua index 11f2b96..aef5f2e 100644 --- a/lua/argonaut/range.lua +++ b/lua/argonaut/range.lua @@ -3,7 +3,7 @@ local Options = require('argonaut.options') local Pairing = require('argonaut.pairing') local Param = require('argonaut.param') -local Range = {} +local Range = {type = 'range'} Range.__index = Range local function find_closest_pair(pairing) @@ -102,7 +102,7 @@ function Range:parse() param = Param.new(self, param_index) param_index = param_index + 1 end - param:append(cell) + param:append_cell(cell) end local append_param = function() @@ -143,7 +143,7 @@ function Range:hit_test(cursor) end local frame = { - type = 'range', + type = self.type, pairing = self.pairing.open .. self.pairing.close, param_count = #self.params, param_index = 0, @@ -178,7 +178,7 @@ end function Range:hit_search(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.param_count == #self.params) assert(frame.param_index <= #self.params) @@ -267,7 +267,7 @@ function Range:write(builder, wrapped) end 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 function Range:is_contiguous() @@ -281,10 +281,13 @@ function Range:is_contiguous() end function Range:is_wrapped() + local previous_cursor = self.start_cursor 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 end + previous_cursor = cursor end return false