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.master
parent
35f6a1767a
commit
e375995d98
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
24
src/move.c
24
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;
|
||||
}
|
||||
|
|
10
src/nano.c
10
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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
60
src/winio.c
60
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]. */
|
||||
|
|
Loading…
Reference in New Issue