nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit 456d66b90498f5fe3af9d38f078928a249bd9a68
parent da62ef8a43be69b0625bfb4216c8edd549f3e9a4
Author: David Lawrence Ramsey <pooka109@gmail.com>
Date:   Fri, 30 Dec 2016 00:34:13 -0600

softwrap: add two chunk-iterator functions

These functions, go_back_chunks() and go_forward_chunks(), take a number
of softwrapped chunks (screen rows) to move, a pointer to a buffer, and
a location (specifically, a starting column of a softwrapped chunk).  If
they move successfully, they will update the buffer pointer and location
to point to the beginning of the softwrapped chunk they moved to.

Since non-softwrap mode is effectively just a subset of softwrap mode
in which every line takes up one chunk, these functions also work in
non-softwrap mode.  In this case, their starting column will always be
zero, as it would be in softwrap mode on a line that takes up one chunk.

Nothing uses these functions yet, but that is forthcoming.

Diffstat:
Msrc/proto.h | 2++
Msrc/winio.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+), 0 deletions(-)

diff --git 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 @@ -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. */