diff --git a/grid.c b/grid.c index 5a0b5c7e..4a3995a0 100644 --- a/grid.c +++ b/grid.c @@ -15,6 +15,34 @@ #define TIME_REFLOW 0 +/* + * “sb” (scrollback relative) coordinates + * + * The scrollback relative row number 0 is the *first*, and *oldest* + * row in the scrollback history (and thus the *first* row to be + * scrolled out). Thus, a higher number means further *down* in the + * scrollback, with the *highest* number being at the bottom of the + * screen, where new input appears. + */ +int +grid_row_abs_to_sb(const struct grid *grid, int screen_rows, int abs_row) +{ + const int scrollback_start = grid->offset + screen_rows; + int rebased_row = abs_row - scrollback_start + grid->num_rows; + + rebased_row &= grid->num_rows - 1; + return rebased_row; +} + +int grid_row_sb_to_abs(const struct grid *grid, int screen_rows, int sb_rel_row) +{ + const int scrollback_start = grid->offset + screen_rows; + int abs_row = sb_rel_row + scrollback_start; + + abs_row &= grid->num_rows - 1; + return abs_row; +} + static void ensure_row_has_extra_data(struct row *row) { diff --git a/grid.h b/grid.h index 7819db4d..22bd76bb 100644 --- a/grid.h +++ b/grid.h @@ -21,6 +21,10 @@ void grid_resize_and_reflow( size_t tracking_points_count, struct coord *const _tracking_points[static tracking_points_count]); +/* Convert row numbers between scrollback-relative and absolute coordinates */ +int grid_row_abs_to_sb(const struct grid *grid, int screen_rows, int abs_row); +int grid_row_sb_to_abs(const struct grid *grid, int screen_rows, int sb_rel_row); + static inline int grid_row_absolute(const struct grid *grid, int row_no) { @@ -33,6 +37,7 @@ grid_row_absolute_in_view(const struct grid *grid, int row_no) return (grid->view + row_no) & (grid->num_rows - 1); } + static inline struct row * _grid_row_maybe_alloc(struct grid *grid, int row_no, bool alloc_if_null) {