diff --git a/lua/argonaut/init.lua b/lua/argonaut/init.lua index 7b59e8a..eff2deb 100644 --- a/lua/argonaut/init.lua +++ b/lua/argonaut/init.lua @@ -34,7 +34,7 @@ local function reflow() local new_range = Range.find_at_cursor(range.start_cursor) assert(new_range) - new_range:hit_search(trace, 1):set_current() + new_range:hit_search(trace, 1).cursor:set_current() return true end @@ -42,7 +42,9 @@ end local function inspect() local range = Range.find_closest() if range then - local trace = range:hit_test(Cursor.get_current()) + local trace = range:hit_test( + Cursor.get_current() + ) assert(trace) dump(trace) end diff --git a/lua/argonaut/param.lua b/lua/argonaut/param.lua index b84b030..a463dca 100644 --- a/lua/argonaut/param.lua +++ b/lua/argonaut/param.lua @@ -23,8 +23,17 @@ function ParamCursorCell:hit_search(trace, depth) local frame = trace[depth] assert(frame.type == 'cursor_cell') assert(frame.char == self.cursor:get_value()) + assert(depth == #trace) - return self.cursor + return self +end + +function ParamCursorCell:is_before_cursor(cursor) + return self.cursor < cursor +end + +function ParamCursorCell:is_after_cursor(cursor) + return self.cursor > cursor end function ParamCursorCell:get_start_row() @@ -59,11 +68,23 @@ function ParamRangeCell:hit_test(cursor) end end +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 + function ParamRangeCell:hit_search(trace, depth) local frame = trace[depth] assert(frame.type == 'range_cell') - return self.range:hit_search(trace, depth + 1) + if depth == #trace then + return self + else + return self.range:hit_search(trace, depth + 1) + end end function ParamRangeCell:get_start_row() @@ -136,10 +157,13 @@ function Param:hit_search(trace, depth) local frame = trace[depth] assert(frame.type == 'param') - 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) + if depth == #trace then + return self + else + 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) + end end function Param:write(builder, wrapped) @@ -148,6 +172,18 @@ function Param:write(builder, wrapped) end end +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 + function Param:get_previous() if self.index > 1 then return self.range.params[self.index - 1] diff --git a/lua/argonaut/range.lua b/lua/argonaut/range.lua index 65732ad..5ae12bd 100644 --- a/lua/argonaut/range.lua +++ b/lua/argonaut/range.lua @@ -120,6 +120,23 @@ function Range:hit_test(cursor) param_index = 0, } + if cursor == self.start_cursor and self.params[1]:is_after_cursor(cursor) then + cursor = cursor:get_next() + elseif cursor == self.stop_cursor and self.params[#self.params]:is_before_cursor(cursor) then + cursor = cursor:get_previous() + end + + for i = 2, #self.params do + local current_param = self.params[i] + local previous_param = self.params[i - 1] + if previous_param:is_before_cursor(cursor) and current_param:is_after_cursor(cursor) then + if not previous_param:hit_test(cursor) and not current_param:hit_test(cursor) then + cursor = cursor:get_previous() + break + end + end + end + for i, param in pairs(self.params) do local trace = param:hit_test(cursor) if trace then @@ -128,8 +145,6 @@ function Range:hit_test(cursor) return trace end end - - return {frame} end end @@ -140,8 +155,8 @@ function Range:hit_search(trace, depth) assert(frame.param_count == #self.params) assert(frame.param_index <= #self.params) - if frame.param_index == 0 then - return self.start_cursor + if depth == #trace then + return self else return self.params[frame.param_index]:hit_search(trace, depth + 1) end