commit e375995d98bbb6313b16220e7ecd34ac1a54e3c4
parent 35f6a1767af484da950250d01849b2de128fe75a
Author: David Lawrence Ramsey <pooka109@gmail.com>
Date: Sun, 19 Feb 2017 11:51:50 -0600
softwrap: add new functions for chunks of varying width
get_chunk_row() replaces the formula "column / editwincols".
get_chunk_leftedge() replaces "(column / editwincols) * editwincols".
get_last_chunk_row() replaces "strlenpt() / editwincols".
get_last_chunk_leftedge() replaces "(strlenpt() / editwincols) * editwincols".
This prepares us for any changes in those formulas, and for more such
functions later.
Diffstat:
8 files changed, 73 insertions(+), 35 deletions(-)
diff --git a/src/cut.c b/src/cut.c
@@ -270,7 +270,7 @@ void do_uncut_text(void)
add_undo(PASTE);
if (ISSET(SOFTWRAP))
- was_leftedge = (xplustabs() / editwincols) * editwincols;
+ was_leftedge = get_chunk_leftedge(openfile->current, xplustabs());
#endif
/* Add a copy of the text in the cutbuffer to the current buffer
diff --git a/src/files.c b/src/files.c
@@ -777,7 +777,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable,
add_undo(INSERT);
if (ISSET(SOFTWRAP))
- was_leftedge = (xplustabs() / editwincols) * editwincols;
+ was_leftedge = get_chunk_leftedge(openfile->current, xplustabs());
#endif
/* Create an empty buffer. */
diff --git a/src/move.c b/src/move.c
@@ -58,7 +58,7 @@ void get_edge_and_target(size_t *leftedge, size_t *target_column)
if (realspan > openfile->placewewant)
realspan = openfile->placewewant;
- *leftedge = (realspan / editwincols) * editwincols;
+ *leftedge = get_chunk_leftedge(openfile->current, realspan);
*target_column = openfile->placewewant % editwincols;
} else
#endif
@@ -352,9 +352,11 @@ void do_home(bool be_clever)
bool moved = FALSE;
size_t leftedge_x = 0;
- if (ISSET(SOFTWRAP))
- leftedge_x = actual_x(openfile->current->data,
- (was_column / editwincols) * editwincols);
+ if (ISSET(SOFTWRAP)) {
+ size_t leftedge = get_chunk_leftedge(openfile->current, was_column);
+
+ leftedge_x = actual_x(openfile->current->data, leftedge);
+ }
if (ISSET(SMART_HOME) && be_clever) {
size_t indent_x = indent_length(openfile->current->data);
@@ -417,9 +419,9 @@ void do_end(bool be_clever)
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
+ size_t leftedge = get_chunk_leftedge(openfile->current, was_column);
size_t rightedge_x = actual_x(openfile->current->data,
- ((was_column / editwincols) * editwincols) +
- (editwincols - 1));
+ leftedge + (editwincols - 1));
/* If already at the right edge of the screen, move fully to
* the end of the line. Otherwise, move to the right edge. */
@@ -562,8 +564,8 @@ void do_left(void)
{
size_t was_column = xplustabs();
#ifndef NANO_TINY
- size_t was_chunk = (was_column / editwincols);
filestruct *was_current = openfile->current;
+ size_t was_chunk = get_chunk_row(was_current, was_column);
#endif
if (openfile->current_x > 0)
@@ -582,7 +584,8 @@ void do_left(void)
* we're now above the first line of the edit window, so scroll up. */
if (ISSET(SOFTWRAP) && openfile->current_y == 0 &&
openfile->current == was_current &&
- openfile->placewewant / editwincols != was_chunk) {
+ get_chunk_row(openfile->current,
+ openfile->placewewant) != was_chunk) {
edit_scroll(UPWARD, ISSET(SMOOTH_SCROLL) ? 1 : editwinrows / 2 + 1);
return;
}
@@ -598,8 +601,8 @@ void do_right(void)
{
size_t was_column = xplustabs();
#ifndef NANO_TINY
- size_t was_chunk = (was_column / editwincols);
filestruct *was_current = openfile->current;
+ size_t was_chunk = get_chunk_row(was_current, was_column);
#endif
if (openfile->current->data[openfile->current_x] != '\0')
@@ -618,7 +621,8 @@ void do_right(void)
* we're now below the first line of the edit window, so scroll down. */
if (ISSET(SOFTWRAP) && openfile->current_y == editwinrows - 1 &&
openfile->current == was_current &&
- openfile->placewewant / editwincols != was_chunk) {
+ get_chunk_row(openfile->current,
+ openfile->placewewant) != was_chunk) {
edit_scroll(DOWNWARD, ISSET(SMOOTH_SCROLL) ? 1 : editwinrows / 2 + 1);
return;
}
diff --git a/src/nano.c b/src/nano.c
@@ -1759,7 +1759,7 @@ int do_mouse(void)
/* Whether the click was on the row where the cursor is. */
if (ISSET(SOFTWRAP))
- leftedge = (xplustabs() / editwincols) * editwincols;
+ leftedge = get_chunk_leftedge(openfile->current, xplustabs());
else
#endif
leftedge = get_page_start(xplustabs());
@@ -1809,8 +1809,8 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
if (ISSET(SOFTWRAP)) {
if (openfile->current_y == editwinrows - 1)
- original_row = xplustabs() / editwincols;
- orig_rows = strlenpt(openfile->current->data) / editwincols;
+ original_row = get_chunk_row(openfile->current, xplustabs());
+ orig_rows = get_last_chunk_row(openfile->current);
}
#endif
@@ -1875,9 +1875,9 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
* of the edit window, and we moved one screen row, we're now below
* the last line of the edit window, so we need a full refresh too. */
if (ISSET(SOFTWRAP) && refresh_needed == FALSE &&
- (strlenpt(openfile->current->data) / editwincols != orig_rows ||
+ (get_last_chunk_row(openfile->current) != orig_rows ||
(openfile->current_y == editwinrows - 1 &&
- xplustabs() / editwincols != original_row)))
+ get_chunk_row(openfile->current, xplustabs()) != original_row)))
refresh_needed = TRUE;
#endif
diff --git a/src/proto.h b/src/proto.h
@@ -666,6 +666,10 @@ void edit_scroll(scroll_dir direction, int nrows);
size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
bool *end_of_line);
size_t get_chunk(filestruct *line, size_t column, size_t *leftedge);
+size_t get_chunk_row(filestruct *line, size_t column);
+size_t get_chunk_leftedge(filestruct *line, size_t column);
+size_t get_last_chunk_row(filestruct *line);
+size_t get_last_chunk_leftedge(filestruct *line);
void ensure_firstcolumn_is_aligned(void);
#endif
void edit_redraw(filestruct *old_current);
diff --git a/src/search.c b/src/search.c
@@ -903,7 +903,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
filestruct *line = openfile->current;
- size_t leftedge = (xplustabs() / editwincols) * editwincols;
+ size_t leftedge = get_chunk_leftedge(openfile->current, xplustabs());
rows_from_tail = (editwinrows / 2) -
go_forward_chunks(editwinrows / 2, &line, &leftedge);
diff --git a/src/text.c b/src/text.c
@@ -112,7 +112,7 @@ void do_deletion(undo_type action)
update_undo(action);
if (ISSET(SOFTWRAP))
- orig_rows = strlenpt(openfile->current->data) / editwincols;
+ orig_rows = get_last_chunk_row(openfile->current);
#endif
/* Move the remainder of the line "in", over the current character. */
@@ -181,7 +181,7 @@ void do_deletion(undo_type action)
/* If the number of screen rows that a softwrapped line occupies
* has changed, we need a full refresh. */
if (ISSET(SOFTWRAP) && refresh_needed == FALSE &&
- strlenpt(openfile->current->data) / editwincols != orig_rows)
+ get_last_chunk_row(openfile->current) != orig_rows)
refresh_needed = TRUE;
#endif
diff --git a/src/winio.c b/src/winio.c
@@ -2295,16 +2295,16 @@ void place_the_cursor(bool forreal)
if (ISSET(SOFTWRAP)) {
filestruct *line = openfile->edittop;
- row -= (openfile->firstcolumn / editwincols);
+ row -= get_chunk_row(openfile->edittop, openfile->firstcolumn);
/* Calculate how many rows the lines from edittop to current use. */
while (line != NULL && line != openfile->current) {
- row += strlenpt(line->data) / editwincols + 1;
+ row += get_last_chunk_row(line) + 1;
line = line->next;
}
/* Add the number of wraps in the current line before the cursor. */
- row += xpt / editwincols;
+ row += get_chunk_row(openfile->current, xpt);
col = xpt % editwincols;
/* If the cursor ought to be in column zero, nudge it there. */
@@ -2753,11 +2753,11 @@ int update_softwrapped_line(filestruct *fileptr)
if (fileptr == openfile->edittop)
from_col = openfile->firstcolumn;
else
- row -= (openfile->firstcolumn / editwincols);
+ row -= get_chunk_row(openfile->edittop, openfile->firstcolumn);
/* Find out on which screen row the target line should be shown. */
while (line != fileptr && line != NULL) {
- row += (strlenpt(line->data) / editwincols) + 1;
+ row += get_last_chunk_row(line) + 1;
line = line->next;
}
@@ -2813,7 +2813,7 @@ int go_back_chunks(int nrows, filestruct **line, size_t *leftedge)
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
- size_t current_chunk = (*leftedge) / editwincols;
+ size_t current_chunk = get_chunk_row(*line, *leftedge);
/* Recede through the requested number of chunks. */
for (i = nrows; i > 0; i--) {
@@ -2826,7 +2826,7 @@ int go_back_chunks(int nrows, filestruct **line, size_t *leftedge)
break;
*line = (*line)->prev;
- current_chunk = strlenpt((*line)->data) / editwincols;
+ current_chunk = get_last_chunk_row(*line);
}
/* Only change leftedge when we actually could move. */
@@ -2854,8 +2854,8 @@ int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge)
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
- size_t current_chunk = (*leftedge) / editwincols;
- size_t last_chunk = strlenpt((*line)->data) / editwincols;
+ size_t current_chunk = get_chunk_row(*line, *leftedge);
+ size_t last_chunk = get_last_chunk_row(*line);
/* Advance through the requested number of chunks. */
for (i = nrows; i > 0; i--) {
@@ -2869,7 +2869,7 @@ int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge)
*line = (*line)->next;
current_chunk = 0;
- last_chunk = strlenpt((*line)->data) / editwincols;
+ last_chunk = get_last_chunk_row(*line);
}
/* Only change leftedge when we actually could move. */
@@ -2891,7 +2891,7 @@ bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge)
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
filestruct *line = openfile->current;
- size_t leftedge = (xplustabs() / editwincols) * editwincols;
+ size_t leftedge = get_chunk_leftedge(openfile->current, xplustabs());
int rows_left = go_back_chunks(editwinrows - 1, &line, &leftedge);
return (rows_left > 0 || line->lineno < was_lineno ||
@@ -2957,11 +2957,11 @@ void edit_scroll(scroll_dir direction, int nrows)
#ifndef NANO_TINY
/* Compensate for the earlier chunks of a softwrapped line. */
- nrows += leftedge / editwincols;
+ nrows += get_chunk_row(line, leftedge);
/* Don't compensate for the chunks that are offscreen. */
if (line == openfile->edittop)
- nrows -= openfile->firstcolumn / editwincols;
+ nrows -= get_chunk_row(line, openfile->firstcolumn);
#endif
/* Draw new content on the blank rows inside the scrolled region
@@ -3039,6 +3039,34 @@ size_t get_chunk(filestruct *line, size_t column, size_t *leftedge)
}
}
+/* Return the row of the softwrapped chunk of the given line that column is on,
+ * relative to the first row (zero-based). */
+size_t get_chunk_row(filestruct *line, size_t column)
+{
+ return strnlenpt(line->data, column) / editwincols;
+}
+
+/* Return the leftmost column of the softwrapped chunk of the given line that
+ * column is on. */
+size_t get_chunk_leftedge(filestruct *line, size_t column)
+{
+ return (strnlenpt(line->data, column) / editwincols) * editwincols;
+}
+
+/* Return the row of the last softwrapped chunk of the given line, relative to
+ * the first row (zero-based). */
+size_t get_last_chunk_row(filestruct *line)
+{
+ return get_chunk_row(line, (size_t)-1);
+}
+
+/* Return the leftmost column of the last softwrapped chunk of the given
+ * line. */
+size_t get_last_chunk_leftedge(filestruct *line)
+{
+ return get_chunk_leftedge(line, (size_t)-1);
+}
+
/* Ensure that firstcolumn is at the starting column of the softwrapped chunk
* it's on. We need to do this when the number of columns of the edit window
* has changed, because then the width of softwrapped chunks has changed. */
@@ -3082,7 +3110,8 @@ bool current_is_below_screen(void)
return (go_forward_chunks(editwinrows - 1, &line, &leftedge) == 0 &&
(line->lineno < openfile->current->lineno ||
(line->lineno == openfile->current->lineno &&
- leftedge < (xplustabs() / editwincols) * editwincols)));
+ leftedge < get_chunk_leftedge(openfile->current,
+ xplustabs()))));
} else
#endif
return (openfile->current->lineno >=
@@ -3201,7 +3230,8 @@ void adjust_viewport(update_type manner)
openfile->edittop = openfile->current;
#ifndef NANO_TINY
if (ISSET(SOFTWRAP))
- openfile->firstcolumn = (xplustabs() / editwincols) * editwincols;
+ openfile->firstcolumn = get_chunk_leftedge(openfile->current,
+ xplustabs());
#endif
/* Move edittop back goal rows, starting at current[current_x]. */