diff --git a/src/cut.c b/src/cut.c index 5b70570b..be1791ff 100644 --- 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 index 0cf338ae..6383ca57 100644 --- 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 index f8cddc12..69181b45 100644 --- 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 index 9b08c8f1..5b1a160e 100644 --- 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 index d6837c49..4e66b8e3 100644 --- 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 index 8b7b2502..6d178200 100644 --- 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 index 6a0cc528..3bb76c08 100644 --- 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 index deb25be3..df571583 100644 --- 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]. */