From 456d66b90498f5fe3af9d38f078928a249bd9a68 Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Fri, 30 Dec 2016 00:34:13 -0600 Subject: [PATCH] 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. --- src/proto.h | 2 ++ src/winio.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/proto.h b/src/proto.h index 3a917a40..66fb9eac 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 8f99fa8e..522bdae9 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. */