Skip to content

Commit

Permalink
replace viewport_y with viewport_mark->bline->line_index
Browse files Browse the repository at this point in the history
way back in the beginning, there was `viewport_y`. then in commit
ad84c0f, `viewport_bline` was added as a perf shortcut for accessing
the bline at `viewport_y`. in commit 2273cde, `viewport_mark`
replaced `viewport_bline` to prevent use-after-free errors. and today
we remove `viewport_y` entirely as it's redundant, and was causing a
viewport bug described below.

open a buffer with output from `seq 1 <N>` where N is greater than
your terminal's line count. split the buffer and move the cursor to
eof in the split. switch back to the original buffer. now start
deleting lines from the top of the buffer. you'll notice the split
will start rendering incorrectly around eof. this was due to
`viewport_y` falling out of sync with `viewport_mark`.

currently, we don't have a way to write viewport tests as tests run
in headless mode. in the future we could do something similar to the
termbox2 tests.
  • Loading branch information
adsr committed Apr 13, 2024
1 parent d180016 commit 4813b79
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 11 deletions.
18 changes: 11 additions & 7 deletions bview.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,8 @@ int bview_set_viewport_y(bview_t *self, bint_t y, int do_rectify) {
} else if (y >= self->buffer->line_count) {
y = self->buffer->line_count - 1;
}
self->viewport_y = y;
mark_move_to(self->viewport_mark, y, 0);
if (do_rectify) bview_rectify_viewport(self);
mark_move_to(self->viewport_mark, self->viewport_y, 0);
return MLE_OK;
}

Expand Down Expand Up @@ -370,17 +369,20 @@ int bview_max_viewport_y(bview_t *self) {
// Rectify the viewport
int bview_rectify_viewport(bview_t *self) {
mark_t *mark;
bint_t viewport_y;

mark = self->active_cursor->mark;
viewport_y = self->viewport_mark->bline->line_index;

// Rectify each dimension of the viewport
MLBUF_BLINE_ENSURE_CHARS(mark->bline);
_bview_rectify_viewport_dim(self, mark->bline, MLE_MARK_COL_TO_VCOL(mark), self->viewport_scope_x, self->rect_buffer.w, &self->viewport_x_vcol);
bline_get_col_from_vcol(mark->bline, self->viewport_x_vcol, &(self->viewport_x));

if (_bview_rectify_viewport_dim(self, mark->bline, mark->bline->line_index, self->viewport_scope_y, self->rect_buffer.h, &self->viewport_y)) {
if (_bview_rectify_viewport_dim(self, mark->bline, mark->bline->line_index, self->viewport_scope_y, self->rect_buffer.h, &viewport_y)) {
// TODO viewport_y_vrow (soft-wrapped lines, code folding, etc)
// Adjust viewport_mark
mark_move_to(self->viewport_mark, self->viewport_y, 0);
mark_move_to(self->viewport_mark, viewport_y, 0);
}

return MLE_OK;
Expand Down Expand Up @@ -960,6 +962,7 @@ static void _bview_draw_edit(bview_t *self, int x, int y, int w, int h) {
int fg_attr;
int bg_attr;
bline_t *bline;
bint_t viewport_y;

// Handle split
if (self->split_child) {
Expand Down Expand Up @@ -1008,15 +1011,16 @@ static void _bview_draw_edit(bview_t *self, int x, int y, int w, int h) {

// Render lines and margins
bline = self->viewport_mark->bline;
viewport_y = bline->line_index;
for (rect_y = 0; rect_y < self->rect_buffer.h; rect_y++) {
if (self->viewport_y + rect_y < 0 || self->viewport_y + rect_y >= self->buffer->line_count || !bline) { // "|| !bline" See TODOs below
if (viewport_y + rect_y < 0 || viewport_y + rect_y >= self->buffer->line_count) {
// Draw pre/post blank
tb_printf_rect(self->rect_lines, 0, rect_y, 0, 0, "%*c", self->linenum_width, '~');
tb_printf_rect(self->rect_margin_left, 0, rect_y, 0, 0, "%c", ' ');
tb_printf_rect(self->rect_margin_right, 0, rect_y, 0, 0, "%c", ' ');
tb_printf_rect(self->rect_buffer, 0, rect_y, 0, 0, "%-*.*s", self->rect_buffer.w, self->rect_buffer.w, " ");
} else {
// Draw bline at self->rect_buffer self->viewport_y + rect_y
// Draw bline at self->rect_buffer self->viewport_mark + rect_y
_bview_draw_bline(self, bline, rect_y, &bline, &rect_y);
bline = bline->next;
}
Expand Down Expand Up @@ -1217,7 +1221,7 @@ int bview_screen_to_bline_col(bview_t *self, int x, int y, bview_t **ret_bview,
&& y >= self->rect_buffer.y
&& y < self->rect_buffer.y + self->rect_buffer.h
) {
line_index = self->viewport_y + (y - self->rect_buffer.y);
line_index = self->viewport_mark->bline->line_index + (y - self->rect_buffer.y);
buffer_get_bline_w_hint(self->buffer, line_index, self->viewport_mark->bline, ret_bline);
if (*ret_bline) {
vcol = _bview_get_viewport_x(self, *ret_bline) + (x - self->rect_buffer.x);
Expand Down
2 changes: 1 addition & 1 deletion cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ int cursor_replace(cursor_t *cursor, int interactive, char *opt_regex, char *opt
search_mark_end = buffer_add_mark(cursor->bview->buffer, NULL, 0);
mark_join(search_mark, cursor->mark);
mark_join(orig_mark, cursor->mark);
orig_viewport_y = cursor->bview->viewport_y;
orig_viewport_y = cursor->bview->viewport_mark->bline->line_index;
orig_mark->lefty = 1; // lefty==1 avoids moving when text is inserted at mark
lo_mark->lefty = 1;
if (cursor->is_anchored) {
Expand Down
4 changes: 2 additions & 2 deletions editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -849,12 +849,12 @@ static int _editor_prompt_isearch_prev(cmd_context_t *ctx) {

// Invoked when user hits up in a prompt_isearch
static int _editor_prompt_isearch_viewport_up(cmd_context_t *ctx) {
return bview_set_viewport_y(ctx->editor->active_edit, ctx->editor->active_edit->viewport_y - 5, 0);
return bview_set_viewport_y(ctx->editor->active_edit, ctx->editor->active_edit->viewport_mark->bline->line_index - 5, 0);
}

// Invoked when user hits up in a prompt_isearch
static int _editor_prompt_isearch_viewport_down(cmd_context_t *ctx) {
return bview_set_viewport_y(ctx->editor->active_edit, ctx->editor->active_edit->viewport_y + 5, 0);
return bview_set_viewport_y(ctx->editor->active_edit, ctx->editor->active_edit->viewport_mark->bline->line_index + 5, 0);
}

// Drops a cursor on each isearch match
Expand Down
1 change: 0 additions & 1 deletion mle.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ struct bview_s {
buffer_t *buffer;
bint_t viewport_x;
bint_t viewport_x_vcol;
bint_t viewport_y;
mark_t *viewport_mark;
int viewport_scope_x;
int viewport_scope_y;
Expand Down

0 comments on commit 4813b79

Please sign in to comment.