diff --git a/src/proto.h b/src/proto.h index 3a917a4091cff5b5c71353f3f2fbee9a05763157..66fb9eac318db3c9815b81d57d054c4cabf1db7c 100644 --- a/src/proto.h +++ b/src/proto.h @@ -707,6 +707,8 @@ void edit_draw(filestruct *fileptr, const char *converted, int line, size_t from_col); int update_line(filestruct *fileptr, size_t index); bool need_horizontal_scroll(const size_t old_column, const size_t new_column); +int go_back_chunks(int nrows, filestruct **line, size_t *leftedge); +int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge); void edit_scroll(scroll_dir direction, int nrows); void edit_redraw(filestruct *old_current); void edit_refresh(void); diff --git a/src/winio.c b/src/winio.c index 8f99fa8eb1d7449ce47e6e6b01d8fdd84a73c902..522bdae908d7534e9699ed6d1181c66964b402fa 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2753,6 +2753,88 @@ void compute_maxlines(void) maxlines = editwinrows; } +/* Try to move up nrows softwrapped chunks from the given line and the + * given column (leftedge). After moving, leftedge will be set to the + * starting column of the current chunk. Return the number of chunks we + * couldn't move up, which will be zero if we completely succeeded. */ +int go_back_chunks(int nrows, filestruct **line, size_t *leftedge) +{ + int i; + + /* Don't move more chunks than the window can hold. */ + if (nrows > editwinrows - 1) + nrows = (editwinrows < 2) ? 1 : editwinrows - 1; + +#ifndef NANO_TINY + if (ISSET(SOFTWRAP)) { + size_t current_chunk = (*leftedge) / editwincols; + + for (i = nrows; i > 0; i--) { + if (current_chunk > 0) { + current_chunk--; + continue; + } + + if (*line == openfile->fileage) + break; + + *line = (*line)->prev; + current_chunk = strlenpt((*line)->data) / editwincols; + } + + /* Only change leftedge when we actually could move. */ + if (i < nrows) + *leftedge = current_chunk * editwincols; + } else +#endif + for (i = nrows; i > 0 && (*line)->prev != NULL; i--) + *line = (*line)->prev; + + return i; +} + +/* Try to move down nrows softwrapped chunks from the given line and the + * given column (leftedge). After moving, leftedge will be set to the + * starting column of the current chunk. Return the number of chunks we + * couldn't move down, which will be zero if we completely succeeded. */ +int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge) +{ + int i; + + /* Don't move more chunks than the window can hold. */ + if (nrows > editwinrows - 1) + nrows = (editwinrows < 2) ? 1 : editwinrows - 1; + +#ifndef NANO_TINY + if (ISSET(SOFTWRAP)) { + size_t current_chunk = (*leftedge) / editwincols; + size_t last_chunk = strlenpt((*line)->data) / editwincols; + + for (i = nrows; i > 0; i--) { + if (current_chunk < last_chunk) { + current_chunk++; + continue; + } + + if (*line == openfile->filebot) + break; + + *line = (*line)->next; + current_chunk = 0; + last_chunk = strlenpt((*line)->data) / editwincols; + } + + /* Only change leftedge when we actually could move. */ + if (i < nrows) + *leftedge = current_chunk * editwincols; + } else +#endif + for (i = nrows; i > 0 && (*line)->next != NULL; i--) + *line = (*line)->next; + + return i; +} + /* Scroll the edit window in the given direction and the given number of rows, * and draw new lines on the blank lines left after the scrolling. We change * edittop, and assume that current and current_x are up to date. */