Modify line number arithmetic to no longer assume linear increments.
When adding folding lines, the lines drawn on screen are no longer guaranteed to increment one by one. There could be a large skip when handling folded segments. So instances where the codebase assumed 'openfile->current->lineno - edittop->lineno' would yield the position on screen of the current line needed to be modified. Similar problems existed in many places so a function 'get_row_from_edittop' handles finding the current position of a line in relation to 'edittop'. Signed-off-by: rexy712 <rexy712@protonmail.com>
This commit is contained in:
parent
a299827554
commit
90dac326c1
42
src/move.c
42
src/move.c
@ -235,19 +235,29 @@ void to_para_end(void)
|
||||
void to_prev_block(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
linestruct *line_step = get_prev_visible_line(openfile->current);
|
||||
bool is_text = FALSE, seen_text = FALSE;
|
||||
|
||||
/* Skip backward until first blank line after some nonblank line(s). */
|
||||
while (openfile->current->prev != NULL && (!seen_text || is_text)) {
|
||||
openfile->current = openfile->current->prev;
|
||||
while (line_step != NULL && (!seen_text || is_text)) {
|
||||
openfile->current = line_step;
|
||||
line_step = get_prev_visible_line(line_step);
|
||||
#ifdef ENABLE_FOLDING
|
||||
/* Skip over the visibly drawn line of the folded segment */
|
||||
if (openfile->current->folded)
|
||||
continue;
|
||||
#endif
|
||||
is_text = !white_string(openfile->current->data);
|
||||
seen_text = seen_text || is_text;
|
||||
}
|
||||
|
||||
/* Step forward one line again if we passed text but this line is blank. */
|
||||
if (seen_text && openfile->current->next != NULL &&
|
||||
white_string(openfile->current->data))
|
||||
openfile->current = openfile->current->next;
|
||||
line_step = get_next_visible_line(openfile->current);
|
||||
if (seen_text && line_step != NULL &&
|
||||
white_string(openfile->current->data)) {
|
||||
openfile->current = line_step;
|
||||
line_step = get_next_visible_line(line_step);
|
||||
}
|
||||
|
||||
openfile->current_x = 0;
|
||||
edit_redraw(was_current, CENTERING);
|
||||
@ -257,12 +267,19 @@ void to_prev_block(void)
|
||||
void to_next_block(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
linestruct *line_step = get_next_visible_line(openfile->current);
|
||||
bool is_white = white_string(openfile->current->data);
|
||||
bool seen_white = is_white;
|
||||
|
||||
/* Skip forward until first nonblank line after some blank line(s). */
|
||||
while (openfile->current->next != NULL && (!seen_white || is_white)) {
|
||||
openfile->current = openfile->current->next;
|
||||
while (line_step != NULL && (!seen_white || is_white)) {
|
||||
openfile->current = line_step;
|
||||
line_step = get_next_visible_line(line_step);
|
||||
#ifdef ENABLE_FOLDING
|
||||
/* Skip over the visibly drawn line of the folded segment */
|
||||
if (openfile->current->folded)
|
||||
continue;
|
||||
#endif
|
||||
is_white = white_string(openfile->current->data);
|
||||
seen_white = seen_white || is_white;
|
||||
}
|
||||
@ -659,7 +676,7 @@ void do_left(void)
|
||||
openfile->current_x);
|
||||
#endif
|
||||
} else if (openfile->current != openfile->filetop) {
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current = get_prev_visible_line(openfile->current);
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
}
|
||||
|
||||
@ -671,6 +688,13 @@ void do_right(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
#ifdef ENABLE_FOLDING
|
||||
if (openfile->current->folded) {
|
||||
openfile->current = get_next_visible_line(openfile->current);
|
||||
if (openfile->current == NULL)
|
||||
openfile->current = was_current;
|
||||
} else
|
||||
#endif
|
||||
if (openfile->current->data[openfile->current_x] != '\0') {
|
||||
openfile->current_x = step_right(openfile->current->data,
|
||||
openfile->current_x);
|
||||
@ -681,7 +705,7 @@ void do_right(void)
|
||||
openfile->current_x);
|
||||
#endif
|
||||
} else if (openfile->current != openfile->filebot) {
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current = get_next_visible_line(openfile->current);
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
|
||||
|
||||
11
src/search.c
11
src/search.c
@ -811,10 +811,19 @@ void goto_line_and_column(ssize_t line, ssize_t column, bool retain_answer,
|
||||
line = 1;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
#ifdef ENABLE_FOLDING
|
||||
linestruct *edit_bottom = openfile->edittop;
|
||||
for (int i = 0; edit_bottom != openfile->filebot && i < editwinrows; ++i)
|
||||
edit_bottom = get_next_visible_line(edit_bottom);
|
||||
if (line > edit_bottom->lineno ||
|
||||
(ISSET(SOFTWRAP) && line > openfile->current->lineno))
|
||||
recook |= perturbed;
|
||||
#else
|
||||
if (line > openfile->edittop->lineno + editwinrows ||
|
||||
(ISSET(SOFTWRAP) && line > openfile->current->lineno))
|
||||
recook |= perturbed;
|
||||
#endif
|
||||
#endif /* ENABLE_FOLDING */
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* Iterate to the requested line. */
|
||||
for (openfile->current = openfile->filetop; line > 1 &&
|
||||
|
||||
83
src/winio.c
83
src/winio.c
@ -2980,8 +2980,13 @@ int update_softwrapped_line(linestruct *line)
|
||||
|
||||
/* Find out on which screen row the target line should be shown. */
|
||||
while (someline != line && someline != NULL) {
|
||||
row += 1 + extra_chunks_in(someline);
|
||||
someline = someline->next;
|
||||
#ifdef ENABLE_FOLDING
|
||||
if (someline->folded)
|
||||
++row;
|
||||
else
|
||||
#endif
|
||||
row += 1 + extra_chunks_in(someline);
|
||||
someline = get_next_visible_line(someline);
|
||||
}
|
||||
|
||||
/* If the first chunk is offscreen, don't even try to display it. */
|
||||
@ -3055,7 +3060,7 @@ int go_back_chunks(int nrows, linestruct **line, size_t *leftedge)
|
||||
break;
|
||||
|
||||
i -= chunk;
|
||||
*line = (*line)->prev;
|
||||
*line = get_prev_visible_line(*line);
|
||||
*leftedge = HIGHEST_POSITIVE;
|
||||
}
|
||||
|
||||
@ -3063,8 +3068,13 @@ int go_back_chunks(int nrows, linestruct **line, size_t *leftedge)
|
||||
*leftedge = leftedge_for(*leftedge, *line);
|
||||
} else
|
||||
#endif
|
||||
for (i = nrows; i > 0 && (*line)->prev != NULL; i--)
|
||||
*line = (*line)->prev;
|
||||
{
|
||||
linestruct *prev = get_prev_visible_line(*line);
|
||||
for (i = nrows; i > 0 && prev != NULL; i--) {
|
||||
*line = prev;
|
||||
prev = get_prev_visible_line(prev);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
@ -3105,8 +3115,13 @@ int go_forward_chunks(int nrows, linestruct **line, size_t *leftedge)
|
||||
*leftedge = current_leftedge;
|
||||
} else
|
||||
#endif
|
||||
for (i = nrows; i > 0 && (*line)->next != NULL; i--)
|
||||
*line = (*line)->next;
|
||||
{
|
||||
linestruct *next = get_next_visible_line(*line);
|
||||
for (i = nrows; i > 0 && next != NULL; i--) {
|
||||
*line = next;
|
||||
next = get_next_visible_line(*line);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
@ -3133,20 +3148,47 @@ bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge)
|
||||
/* Draw a scroll bar on the righthand side of the screen. */
|
||||
void draw_scrollbar(void)
|
||||
{
|
||||
int fromline = openfile->edittop->lineno - 1;
|
||||
int totallines = openfile->filebot->lineno;
|
||||
int coveredlines = editwinrows;
|
||||
int fromline = openfile->edittop->lineno - 1;
|
||||
int coveredlines = 0;
|
||||
linestruct *line = openfile->edittop;
|
||||
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
linestruct *line = openfile->edittop;
|
||||
int extras = extra_chunks_in(line) - chunk_for(openfile->firstcolumn, line);
|
||||
|
||||
while (line->lineno + extras < fromline + editwinrows && line->next) {
|
||||
line = line->next;
|
||||
extras += extra_chunks_in(line);
|
||||
int i = 0;
|
||||
#ifdef ENABLE_FOLDING
|
||||
if (line->folded)
|
||||
coveredlines += get_folded_segment_length(line);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
i = extra_chunks_in(line) - chunk_for(openfile->firstcolumn, line);
|
||||
coveredlines = i;
|
||||
}
|
||||
|
||||
coveredlines = line->lineno - fromline;
|
||||
for (; i < editwinrows && line->next != NULL; ++i) {
|
||||
line = get_next_visible_line(line);
|
||||
#ifdef ENABLE_FOLDING
|
||||
if (line->folded)
|
||||
coveredlines += get_folded_segment_length(line);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
i += extra_chunks_in(line);
|
||||
++coveredlines;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef ENABLE_FOLDING
|
||||
for (int i = 0; i < editwinrows && line->next != NULL; ++i) {
|
||||
if (line->folded)
|
||||
coveredlines += get_folded_segment_length(line);
|
||||
else
|
||||
++coveredlines;
|
||||
line = get_next_visible_line(line);
|
||||
}
|
||||
#else
|
||||
coveredlines = editwinrows;
|
||||
#endif /* ENABLE_FOLDING */
|
||||
}
|
||||
|
||||
int lowest = (fromline * editwinrows) / totallines;
|
||||
@ -3214,7 +3256,7 @@ void edit_scroll(bool direction)
|
||||
while (nrows > 0 && line != NULL) {
|
||||
nrows -= update_line(line, (line == openfile->current) ?
|
||||
openfile->current_x : 0);
|
||||
line = line->next;
|
||||
line = get_next_visible_line(line);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3444,8 +3486,11 @@ void edit_redraw(linestruct *old_current, update_type manner)
|
||||
while (line != openfile->current) {
|
||||
update_line(line, 0);
|
||||
|
||||
line = (line->lineno > openfile->current->lineno) ?
|
||||
line->prev : line->next;
|
||||
if (line->lineno > openfile->current->lineno) {
|
||||
line = get_prev_visible_line(line);
|
||||
} else {
|
||||
line = get_next_visible_line(line);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user