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.
master
David Lawrence Ramsey 2016-12-30 00:34:13 -06:00 committed by Benno Schulenberg
parent da62ef8a43
commit 456d66b904
2 changed files with 84 additions and 0 deletions

View File

@ -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);

View File

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