mirror of
git://git.sv.gnu.org/nano.git
synced 2024-11-25 22:29:42 +03:00
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.
This commit is contained in:
parent
35f6a1767a
commit
e375995d98
@ -270,7 +270,7 @@ void do_uncut_text(void)
|
|||||||
add_undo(PASTE);
|
add_undo(PASTE);
|
||||||
|
|
||||||
if (ISSET(SOFTWRAP))
|
if (ISSET(SOFTWRAP))
|
||||||
was_leftedge = (xplustabs() / editwincols) * editwincols;
|
was_leftedge = get_chunk_leftedge(openfile->current, xplustabs());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Add a copy of the text in the cutbuffer to the current buffer
|
/* 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);
|
add_undo(INSERT);
|
||||||
|
|
||||||
if (ISSET(SOFTWRAP))
|
if (ISSET(SOFTWRAP))
|
||||||
was_leftedge = (xplustabs() / editwincols) * editwincols;
|
was_leftedge = get_chunk_leftedge(openfile->current, xplustabs());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create an empty buffer. */
|
/* 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)
|
if (realspan > openfile->placewewant)
|
||||||
realspan = openfile->placewewant;
|
realspan = openfile->placewewant;
|
||||||
|
|
||||||
*leftedge = (realspan / editwincols) * editwincols;
|
*leftedge = get_chunk_leftedge(openfile->current, realspan);
|
||||||
*target_column = openfile->placewewant % editwincols;
|
*target_column = openfile->placewewant % editwincols;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
@ -352,9 +352,11 @@ void do_home(bool be_clever)
|
|||||||
bool moved = FALSE;
|
bool moved = FALSE;
|
||||||
size_t leftedge_x = 0;
|
size_t leftedge_x = 0;
|
||||||
|
|
||||||
if (ISSET(SOFTWRAP))
|
if (ISSET(SOFTWRAP)) {
|
||||||
leftedge_x = actual_x(openfile->current->data,
|
size_t leftedge = get_chunk_leftedge(openfile->current, was_column);
|
||||||
(was_column / editwincols) * editwincols);
|
|
||||||
|
leftedge_x = actual_x(openfile->current->data, leftedge);
|
||||||
|
}
|
||||||
|
|
||||||
if (ISSET(SMART_HOME) && be_clever) {
|
if (ISSET(SMART_HOME) && be_clever) {
|
||||||
size_t indent_x = indent_length(openfile->current->data);
|
size_t indent_x = indent_length(openfile->current->data);
|
||||||
@ -417,9 +419,9 @@ void do_end(bool be_clever)
|
|||||||
|
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
if (ISSET(SOFTWRAP)) {
|
if (ISSET(SOFTWRAP)) {
|
||||||
|
size_t leftedge = get_chunk_leftedge(openfile->current, was_column);
|
||||||
size_t rightedge_x = actual_x(openfile->current->data,
|
size_t rightedge_x = actual_x(openfile->current->data,
|
||||||
((was_column / editwincols) * editwincols) +
|
leftedge + (editwincols - 1));
|
||||||
(editwincols - 1));
|
|
||||||
|
|
||||||
/* If already at the right edge of the screen, move fully to
|
/* If already at the right edge of the screen, move fully to
|
||||||
* the end of the line. Otherwise, move to the right edge. */
|
* the end of the line. Otherwise, move to the right edge. */
|
||||||
@ -562,8 +564,8 @@ void do_left(void)
|
|||||||
{
|
{
|
||||||
size_t was_column = xplustabs();
|
size_t was_column = xplustabs();
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
size_t was_chunk = (was_column / editwincols);
|
|
||||||
filestruct *was_current = openfile->current;
|
filestruct *was_current = openfile->current;
|
||||||
|
size_t was_chunk = get_chunk_row(was_current, was_column);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (openfile->current_x > 0)
|
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. */
|
* we're now above the first line of the edit window, so scroll up. */
|
||||||
if (ISSET(SOFTWRAP) && openfile->current_y == 0 &&
|
if (ISSET(SOFTWRAP) && openfile->current_y == 0 &&
|
||||||
openfile->current == was_current &&
|
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);
|
edit_scroll(UPWARD, ISSET(SMOOTH_SCROLL) ? 1 : editwinrows / 2 + 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -598,8 +601,8 @@ void do_right(void)
|
|||||||
{
|
{
|
||||||
size_t was_column = xplustabs();
|
size_t was_column = xplustabs();
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
size_t was_chunk = (was_column / editwincols);
|
|
||||||
filestruct *was_current = openfile->current;
|
filestruct *was_current = openfile->current;
|
||||||
|
size_t was_chunk = get_chunk_row(was_current, was_column);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (openfile->current->data[openfile->current_x] != '\0')
|
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. */
|
* we're now below the first line of the edit window, so scroll down. */
|
||||||
if (ISSET(SOFTWRAP) && openfile->current_y == editwinrows - 1 &&
|
if (ISSET(SOFTWRAP) && openfile->current_y == editwinrows - 1 &&
|
||||||
openfile->current == was_current &&
|
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);
|
edit_scroll(DOWNWARD, ISSET(SMOOTH_SCROLL) ? 1 : editwinrows / 2 + 1);
|
||||||
return;
|
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. */
|
/* Whether the click was on the row where the cursor is. */
|
||||||
|
|
||||||
if (ISSET(SOFTWRAP))
|
if (ISSET(SOFTWRAP))
|
||||||
leftedge = (xplustabs() / editwincols) * editwincols;
|
leftedge = get_chunk_leftedge(openfile->current, xplustabs());
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
leftedge = get_page_start(xplustabs());
|
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 (ISSET(SOFTWRAP)) {
|
||||||
if (openfile->current_y == editwinrows - 1)
|
if (openfile->current_y == editwinrows - 1)
|
||||||
original_row = xplustabs() / editwincols;
|
original_row = get_chunk_row(openfile->current, xplustabs());
|
||||||
orig_rows = strlenpt(openfile->current->data) / editwincols;
|
orig_rows = get_last_chunk_row(openfile->current);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
* 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. */
|
* the last line of the edit window, so we need a full refresh too. */
|
||||||
if (ISSET(SOFTWRAP) && refresh_needed == FALSE &&
|
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 &&
|
(openfile->current_y == editwinrows - 1 &&
|
||||||
xplustabs() / editwincols != original_row)))
|
get_chunk_row(openfile->current, xplustabs()) != original_row)))
|
||||||
refresh_needed = TRUE;
|
refresh_needed = TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -666,6 +666,10 @@ void edit_scroll(scroll_dir direction, int nrows);
|
|||||||
size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
||||||
bool *end_of_line);
|
bool *end_of_line);
|
||||||
size_t get_chunk(filestruct *line, size_t column, size_t *leftedge);
|
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);
|
void ensure_firstcolumn_is_aligned(void);
|
||||||
#endif
|
#endif
|
||||||
void edit_redraw(filestruct *old_current);
|
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
|
#ifndef NANO_TINY
|
||||||
if (ISSET(SOFTWRAP)) {
|
if (ISSET(SOFTWRAP)) {
|
||||||
filestruct *line = openfile->current;
|
filestruct *line = openfile->current;
|
||||||
size_t leftedge = (xplustabs() / editwincols) * editwincols;
|
size_t leftedge = get_chunk_leftedge(openfile->current, xplustabs());
|
||||||
|
|
||||||
rows_from_tail = (editwinrows / 2) -
|
rows_from_tail = (editwinrows / 2) -
|
||||||
go_forward_chunks(editwinrows / 2, &line, &leftedge);
|
go_forward_chunks(editwinrows / 2, &line, &leftedge);
|
||||||
|
@ -112,7 +112,7 @@ void do_deletion(undo_type action)
|
|||||||
update_undo(action);
|
update_undo(action);
|
||||||
|
|
||||||
if (ISSET(SOFTWRAP))
|
if (ISSET(SOFTWRAP))
|
||||||
orig_rows = strlenpt(openfile->current->data) / editwincols;
|
orig_rows = get_last_chunk_row(openfile->current);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Move the remainder of the line "in", over the current character. */
|
/* 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
|
/* If the number of screen rows that a softwrapped line occupies
|
||||||
* has changed, we need a full refresh. */
|
* has changed, we need a full refresh. */
|
||||||
if (ISSET(SOFTWRAP) && refresh_needed == FALSE &&
|
if (ISSET(SOFTWRAP) && refresh_needed == FALSE &&
|
||||||
strlenpt(openfile->current->data) / editwincols != orig_rows)
|
get_last_chunk_row(openfile->current) != orig_rows)
|
||||||
refresh_needed = TRUE;
|
refresh_needed = TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
60
src/winio.c
60
src/winio.c
@ -2295,16 +2295,16 @@ void place_the_cursor(bool forreal)
|
|||||||
if (ISSET(SOFTWRAP)) {
|
if (ISSET(SOFTWRAP)) {
|
||||||
filestruct *line = openfile->edittop;
|
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. */
|
/* Calculate how many rows the lines from edittop to current use. */
|
||||||
while (line != NULL && line != openfile->current) {
|
while (line != NULL && line != openfile->current) {
|
||||||
row += strlenpt(line->data) / editwincols + 1;
|
row += get_last_chunk_row(line) + 1;
|
||||||
line = line->next;
|
line = line->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the number of wraps in the current line before the cursor. */
|
/* 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;
|
col = xpt % editwincols;
|
||||||
|
|
||||||
/* If the cursor ought to be in column zero, nudge it there. */
|
/* 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)
|
if (fileptr == openfile->edittop)
|
||||||
from_col = openfile->firstcolumn;
|
from_col = openfile->firstcolumn;
|
||||||
else
|
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. */
|
/* Find out on which screen row the target line should be shown. */
|
||||||
while (line != fileptr && line != NULL) {
|
while (line != fileptr && line != NULL) {
|
||||||
row += (strlenpt(line->data) / editwincols) + 1;
|
row += get_last_chunk_row(line) + 1;
|
||||||
line = line->next;
|
line = line->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2813,7 +2813,7 @@ int go_back_chunks(int nrows, filestruct **line, size_t *leftedge)
|
|||||||
|
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
if (ISSET(SOFTWRAP)) {
|
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. */
|
/* Recede through the requested number of chunks. */
|
||||||
for (i = nrows; i > 0; i--) {
|
for (i = nrows; i > 0; i--) {
|
||||||
@ -2826,7 +2826,7 @@ int go_back_chunks(int nrows, filestruct **line, size_t *leftedge)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
*line = (*line)->prev;
|
*line = (*line)->prev;
|
||||||
current_chunk = strlenpt((*line)->data) / editwincols;
|
current_chunk = get_last_chunk_row(*line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only change leftedge when we actually could move. */
|
/* 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
|
#ifndef NANO_TINY
|
||||||
if (ISSET(SOFTWRAP)) {
|
if (ISSET(SOFTWRAP)) {
|
||||||
size_t current_chunk = (*leftedge) / editwincols;
|
size_t current_chunk = get_chunk_row(*line, *leftedge);
|
||||||
size_t last_chunk = strlenpt((*line)->data) / editwincols;
|
size_t last_chunk = get_last_chunk_row(*line);
|
||||||
|
|
||||||
/* Advance through the requested number of chunks. */
|
/* Advance through the requested number of chunks. */
|
||||||
for (i = nrows; i > 0; i--) {
|
for (i = nrows; i > 0; i--) {
|
||||||
@ -2869,7 +2869,7 @@ int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge)
|
|||||||
|
|
||||||
*line = (*line)->next;
|
*line = (*line)->next;
|
||||||
current_chunk = 0;
|
current_chunk = 0;
|
||||||
last_chunk = strlenpt((*line)->data) / editwincols;
|
last_chunk = get_last_chunk_row(*line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only change leftedge when we actually could move. */
|
/* 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
|
#ifndef NANO_TINY
|
||||||
if (ISSET(SOFTWRAP)) {
|
if (ISSET(SOFTWRAP)) {
|
||||||
filestruct *line = openfile->current;
|
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);
|
int rows_left = go_back_chunks(editwinrows - 1, &line, &leftedge);
|
||||||
|
|
||||||
return (rows_left > 0 || line->lineno < was_lineno ||
|
return (rows_left > 0 || line->lineno < was_lineno ||
|
||||||
@ -2957,11 +2957,11 @@ void edit_scroll(scroll_dir direction, int nrows)
|
|||||||
|
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
/* Compensate for the earlier chunks of a softwrapped line. */
|
/* 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. */
|
/* Don't compensate for the chunks that are offscreen. */
|
||||||
if (line == openfile->edittop)
|
if (line == openfile->edittop)
|
||||||
nrows -= openfile->firstcolumn / editwincols;
|
nrows -= get_chunk_row(line, openfile->firstcolumn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Draw new content on the blank rows inside the scrolled region
|
/* 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
|
/* 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
|
* 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. */
|
* 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 &&
|
return (go_forward_chunks(editwinrows - 1, &line, &leftedge) == 0 &&
|
||||||
(line->lineno < openfile->current->lineno ||
|
(line->lineno < openfile->current->lineno ||
|
||||||
(line->lineno == openfile->current->lineno &&
|
(line->lineno == openfile->current->lineno &&
|
||||||
leftedge < (xplustabs() / editwincols) * editwincols)));
|
leftedge < get_chunk_leftedge(openfile->current,
|
||||||
|
xplustabs()))));
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
return (openfile->current->lineno >=
|
return (openfile->current->lineno >=
|
||||||
@ -3201,7 +3230,8 @@ void adjust_viewport(update_type manner)
|
|||||||
openfile->edittop = openfile->current;
|
openfile->edittop = openfile->current;
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
if (ISSET(SOFTWRAP))
|
if (ISSET(SOFTWRAP))
|
||||||
openfile->firstcolumn = (xplustabs() / editwincols) * editwincols;
|
openfile->firstcolumn = get_chunk_leftedge(openfile->current,
|
||||||
|
xplustabs());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Move edittop back goal rows, starting at current[current_x]. */
|
/* Move edittop back goal rows, starting at current[current_x]. */
|
||||||
|
Loading…
Reference in New Issue
Block a user