softwrap: improve Home's behavior with softwrapped lines

Make do_home() more useful in softwrap mode: let it move to the beginning
of the current chunk instead of to the beginning of the whole line; only
when already at the beginning of a chunk, let it move to the beginning of
the line.  This is called "dynamic home'.

The above rules are ignored when --smarthome is in effect and the cursor
is somewhere in the leading whitespace of a line -- then the cursor is
moved to the first non-whitespace character of the line.
master
David Lawrence Ramsey 2017-01-20 00:04:44 -06:00 committed by Benno Schulenberg
parent d8189703b1
commit bd2d0863d6
1 changed files with 43 additions and 11 deletions

View File

@ -346,30 +346,62 @@ void ensure_line_is_visible(void)
#endif
}
/* Move to the beginning of the current line. If the SMART_HOME flag is
* set, move to the first non-whitespace character of the current line
* if we aren't already there, or to the beginning of the current line
* if we are. */
/* Move to the beginning of the current line (or softwrapped chunk).
*
* Try to do a smart home if it's possible and the SMART_HOME flag is set, and
* then try to do a dynamic home if it's possible and we're in softwrap
* mode. */
void do_home(void)
{
size_t was_column = xplustabs();
filestruct *was_current = openfile->current;
bool moved_off_chunk = TRUE;
#ifndef NANO_TINY
bool moved = FALSE;
size_t leftedge_x = 0;
if (ISSET(SOFTWRAP))
leftedge_x = actual_x(openfile->current->data,
(was_column / editwincols) * editwincols);
if (ISSET(SMART_HOME)) {
size_t current_x_save = openfile->current_x;
size_t indent_x = indent_length(openfile->current->data);
openfile->current_x = indent_length(openfile->current->data);
if (openfile->current_x == current_x_save ||
openfile->current->data[openfile->current_x] == '\0')
if (openfile->current->data[indent_x] != '\0') {
/* If we're exactly on the indent, move fully home. Otherwise,
* when not softwrapping or not after the first nonblank chunk,
* move to the first nonblank character. */
if (openfile->current_x == indent_x) {
openfile->current_x = 0;
} else
moved = TRUE;
} else if (!ISSET(SOFTWRAP) || leftedge_x <= indent_x) {
openfile->current_x = indent_x;
moved = TRUE;
}
}
}
if (!moved && ISSET(SOFTWRAP)) {
/* If already at the left edge of the screen, move fully home.
* Otherwise, move to the left edge. */
if (openfile->current_x == leftedge_x)
openfile->current_x = 0;
else {
openfile->current_x = leftedge_x;
moved_off_chunk = FALSE;
}
} else if (!moved)
#endif
openfile->current_x = 0;
openfile->placewewant = xplustabs();
if (line_needs_update(was_column, openfile->placewewant))
/* If we changed chunk, we might be offscreen. Otherwise, update
* current if the mark is on or we changed "page". */
if (ISSET(SOFTWRAP) && moved_off_chunk) {
focusing = FALSE;
edit_redraw(was_current);
} else if (line_needs_update(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
}