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:
M | src/proto.h | | | 2 | ++ |
M | src/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. */