diff --git a/src/move.c b/src/move.c index b785d8d6..d2578f02 100644 --- a/src/move.c +++ b/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; } diff --git a/src/search.c b/src/search.c index 1163d3d2..5a1f8b36 100644 --- a/src/search.c +++ b/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 && diff --git a/src/winio.c b/src/winio.c index a3ee113b..ebf06fb2 100644 --- a/src/winio.c +++ b/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