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
parent
d8189703b1
commit
bd2d0863d6
56
src/move.c
56
src/move.c
|
@ -346,30 +346,62 @@ void ensure_line_is_visible(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move to the beginning of the current line. If the SMART_HOME flag is
|
/* Move to the beginning of the current line (or softwrapped chunk).
|
||||||
* 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
|
* Try to do a smart home if it's possible and the SMART_HOME flag is set, and
|
||||||
* if we are. */
|
* then try to do a dynamic home if it's possible and we're in softwrap
|
||||||
|
* mode. */
|
||||||
void do_home(void)
|
void do_home(void)
|
||||||
{
|
{
|
||||||
size_t was_column = xplustabs();
|
size_t was_column = xplustabs();
|
||||||
|
filestruct *was_current = openfile->current;
|
||||||
|
bool moved_off_chunk = TRUE;
|
||||||
#ifndef NANO_TINY
|
#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)) {
|
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->data[indent_x] != '\0') {
|
||||||
|
/* If we're exactly on the indent, move fully home. Otherwise,
|
||||||
if (openfile->current_x == current_x_save ||
|
* when not softwrapping or not after the first nonblank chunk,
|
||||||
openfile->current->data[openfile->current_x] == '\0')
|
* move to the first nonblank character. */
|
||||||
|
if (openfile->current_x == indent_x) {
|
||||||
openfile->current_x = 0;
|
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
|
#endif
|
||||||
openfile->current_x = 0;
|
openfile->current_x = 0;
|
||||||
|
|
||||||
openfile->placewewant = xplustabs();
|
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);
|
update_line(openfile->current, openfile->current_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue