new feature: allow lines to be softwrapped at whitespace
Extend get_softwrap_breakpoint() to break softwrapped lines on whitespace when a flag is set. This flag is controlled by the new rcfile option "atblanks". The '>' characters marking two-column characters at the edge of the screen are disabled when it's on. If get_softwrap_breakpoint() can't find whitespace in screen range, it will break the line on the screen edge. (In this case, a blank can be on the last column of the screen, but text can't, so that a blank on the last column doesn't become invisible and possibly break the display.) This fulfills https://savannah.gnu.org/bugs/index.php?49959. Requested-by: Nicholas Boel <axxisd@gmail.com>master
parent
aa04ad4f83
commit
bb4d0d548a
|
@ -657,6 +657,10 @@ When backing up files, allow the backup to succeed even if its
|
|||
permissions can't be (re)set due to special OS considerations.
|
||||
You should NOT enable this option unless you are sure you need it.
|
||||
|
||||
@item set atblanks
|
||||
When soft line wrapping is enabled, make it wrap lines at blank characters
|
||||
(tabs and spaces) instead of always at the edge of the screen.
|
||||
|
||||
@item set autoindent
|
||||
Use auto-indentation.
|
||||
|
||||
|
|
|
@ -57,6 +57,10 @@ When backing up files, allow the backup to succeed even if its permissions
|
|||
can't be (re)set due to special OS considerations. You should
|
||||
NOT enable this option unless you are sure you need it.
|
||||
.TP
|
||||
.B set atblanks
|
||||
When soft line wrapping is enabled, make it wrap lines at blank characters
|
||||
(tabs and spaces) instead of always at the edge of the screen.
|
||||
.TP
|
||||
.B set autoindent
|
||||
Use auto-indentation.
|
||||
.TP
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
## versions of nano installed (e.g. your home directory is on NFS).
|
||||
# set quiet
|
||||
|
||||
## When soft line wrapping is enabled, make it wrap lines at blanks
|
||||
## (tabs and spaces) instead of always at the edge of the screen.
|
||||
# set atblanks
|
||||
|
||||
## Use auto-indentation.
|
||||
# set autoindent
|
||||
|
||||
|
|
|
@ -521,7 +521,8 @@ enum
|
|||
JUSTIFY_TRIM,
|
||||
SHOW_CURSOR,
|
||||
LINE_NUMBERS,
|
||||
NO_PAUSES
|
||||
NO_PAUSES,
|
||||
AT_BLANKS
|
||||
};
|
||||
|
||||
/* Flags for the menus in which a given function should be present. */
|
||||
|
|
|
@ -90,6 +90,7 @@ static const rcoption rcopts[] = {
|
|||
{"view", VIEW_MODE},
|
||||
#ifndef NANO_TINY
|
||||
{"allow_insecure_backup", INSECURE_BACKUP},
|
||||
{"atblanks", AT_BLANKS},
|
||||
{"autoindent", AUTOINDENT},
|
||||
{"backup", BACKUP_FILE},
|
||||
{"backupdir", 0},
|
||||
|
|
36
src/winio.c
36
src/winio.c
|
@ -2782,8 +2782,9 @@ int update_softwrapped_line(filestruct *fileptr)
|
|||
break;
|
||||
|
||||
/* If the line is softwrapped before its last column, add a ">" just
|
||||
* after its softwrap breakpoint. */
|
||||
if (to_col - from_col < editwincols)
|
||||
* after its softwrap breakpoint, unless we're softwrapping at blanks
|
||||
* and not in the middle of a word. */
|
||||
if (!ISSET(AT_BLANKS) && to_col - from_col < editwincols)
|
||||
mvwaddch(edit, row - 1, to_col - from_col, '>');
|
||||
|
||||
from_col = to_col;
|
||||
|
@ -2993,12 +2994,20 @@ 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 index = 0;
|
||||
/* Current index in text. */
|
||||
size_t column = 0;
|
||||
/* Current column position in text. */
|
||||
size_t prev_column = 0;
|
||||
/* Previous column position in text. */
|
||||
size_t goal_column;
|
||||
/* Column of the last character where we can break the text. */
|
||||
bool found_blank = FALSE;
|
||||
/* Did we find at least one blank? */
|
||||
size_t lastblank_index = 0;
|
||||
/* Current index of the last blank in text. */
|
||||
size_t lastblank_column = 0;
|
||||
/* Current column position of the last blank in text. */
|
||||
int char_len = 0;
|
||||
/* Length of current character, in bytes. */
|
||||
|
||||
|
@ -3007,13 +3016,26 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
|||
while (*text != '\0' && column < leftedge)
|
||||
text += parse_mbchar(text, NULL, &column);
|
||||
|
||||
/* Use a full screen row for text. */
|
||||
/* Use a full screen row for text, or, if we're softwrapping at blanks, use
|
||||
* a full screen row less one column for text and reserve the last column
|
||||
* for blanks. The latter case is to ensure that we have enough room for
|
||||
* blanks exactly on the last column of the screen. */
|
||||
if (ISSET(AT_BLANKS) && editwincols > 2)
|
||||
goal_column = column + (editwincols - 1);
|
||||
else
|
||||
goal_column = column + editwincols;
|
||||
|
||||
while (*text != '\0' && column <= goal_column) {
|
||||
if (ISSET(AT_BLANKS) && editwincols > 2 && is_blank_mbchar(text)) {
|
||||
found_blank = TRUE;
|
||||
lastblank_index = index;
|
||||
lastblank_column = column;
|
||||
}
|
||||
|
||||
prev_column = column;
|
||||
char_len = parse_mbchar(text, NULL, &column);
|
||||
text += char_len;
|
||||
index += char_len;
|
||||
}
|
||||
|
||||
/* If the text displays within goal_column, we've reached the end of the
|
||||
|
@ -3023,6 +3045,14 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
|||
return column;
|
||||
}
|
||||
|
||||
/* If we're softwrapping at blanks and we found at least one blank, move
|
||||
* the pointer back to the last blank, step beyond it, and we're done. */
|
||||
if (found_blank) {
|
||||
text = text - index + lastblank_index;
|
||||
parse_mbchar(text, NULL, &lastblank_column);
|
||||
return lastblank_column;
|
||||
}
|
||||
|
||||
/* Otherwise, return the column of the last character before goal_column,
|
||||
* since we can't break the text anywhere else. */
|
||||
return (editwincols > 2) ? prev_column : column - 1;
|
||||
|
|
|
@ -7,7 +7,7 @@ comment "#"
|
|||
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|comment|magic|linter|i?color|extendsyntax).*$"
|
||||
|
||||
# Keywords
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cut|fill[[:space:]]+-?[[:digit:]]+|historylog|justifytrim|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize[[:space:]]+[1-9][0-9]*|tabstospaces|tempfile|unix|view|wordbounds)\>"
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cut|fill[[:space:]]+-?[[:digit:]]+|historylog|justifytrim|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize[[:space:]]+[1-9][0-9]*|tabstospaces|tempfile|unix|view|wordbounds)\>"
|
||||
icolor yellow "^[[:space:]]*set[[:space:]]+((function|key|number|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
||||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|speller|statuscolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+[[:alpha:]]+[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
|
|
Loading…
Reference in New Issue