new feature: an option to make the 'nextword' function stop at word ends

When 'afterends' is set and Ctrl+Right or Shift+Ctrl+Right is pressed,
nano will stop at the ends of words instead of their beginnings.

Signed-off-by: Mark-Weston <markweston@cock.li>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
master
Mark-Weston 2018-04-30 23:10:27 +03:00 committed by Benno Schulenberg
parent 4046dfca63
commit 858663444e
12 changed files with 67 additions and 12 deletions

View File

@ -250,6 +250,9 @@ Disable the hard-wrapping of long lines. This option conflicts with
.BR \-x ", " \-\-nohelp .BR \-x ", " \-\-nohelp
Don't show the two help lines at the bottom of the screen. Don't show the two help lines at the bottom of the screen.
.TP .TP
.BR \-y ", " \-\-afterends
Make Ctrl+Right stop at word ends instead of beginnings.
.TP
.BR \-z ", " \-\-suspend .BR \-z ", " \-\-suspend
Enable the suspend ability. Enable the suspend ability.
.TP .TP

View File

@ -392,6 +392,10 @@ is located at the very bottom of the editor.
Note: When accessing the help system, Expert Mode is temporarily Note: When accessing the help system, Expert Mode is temporarily
disabled to display the help-system navigation keys. disabled to display the help-system navigation keys.
@item -y
@itemx --afterends
Make Ctrl+Right stop at word ends instead of beginnings.
@item -z @item -z
@itemx --suspend @itemx --suspend
Enable the ability to suspend @command{nano} using the system's suspend Enable the ability to suspend @command{nano} using the system's suspend
@ -689,6 +693,9 @@ The supported settings in a nanorc file are:
@table @code @table @code
@item set afterends
Make Ctrl+Right stop at word ends instead of beginnings.
@item set allow_insecure_backup @item set allow_insecure_backup
When backing up files, allow the backup to succeed even if its When backing up files, allow the backup to succeed even if its
permissions can't be (re)set due to special OS considerations. permissions can't be (re)set due to special OS considerations.

View File

@ -53,6 +53,9 @@ match \fB"\fP, \fB'\fP, \fB)\fP, \fB>\fP, \fB]\fP, and \fB}\fP.
The supported commands and arguments are: The supported commands and arguments are:
.TP 3 .TP 3
.B set afterends
Make Ctrl+Right stop at word ends instead of beginnings.
.TP
.B set allow_insecure_backup .B set allow_insecure_backup
When backing up files, allow the backup to succeed even if its permissions 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 can't be (re)set due to special OS considerations. You should

View File

@ -15,6 +15,10 @@
## its end. For example, for the "brackets" option, ""')>]}" will match ## its end. For example, for the "brackets" option, ""')>]}" will match
## ", ', ), >, ], and }. ## ", ', ), >, ], and }.
## Make the 'nextword' function (Ctrl+Right) stop at word ends
## instead of at beginnings.
# set afterends
## When soft line wrapping is enabled, make it wrap lines at blanks ## When soft line wrapping is enabled, make it wrap lines at blanks
## (tabs and spaces) instead of always at the edge of the screen. ## (tabs and spaces) instead of always at the edge of the screen.
# set atblanks # set atblanks

View File

@ -314,15 +314,17 @@ void do_prev_word(bool allow_punct, bool update_screen)
edit_redraw(was_current, FLOWING); edit_redraw(was_current, FLOWING);
} }
/* Move to the next word. If allow_punct is TRUE, treat punctuation /* Move to the next word. If after_ends is TRUE, stop at the ends of words
* instead of their beginnings. If allow_punct is TRUE, treat punctuation
* as part of a word. When requested, update the screen afterwards. * as part of a word. When requested, update the screen afterwards.
* Return TRUE if we started on a word, and FALSE otherwise. */ * Return TRUE if we started on a word, and FALSE otherwise. */
bool do_next_word(bool allow_punct, bool update_screen) bool do_next_word(bool after_ends, bool allow_punct, bool update_screen)
{ {
filestruct *was_current = openfile->current; filestruct *was_current = openfile->current;
bool started_on_word = is_word_mbchar(openfile->current->data + bool started_on_word = is_word_mbchar(openfile->current->data +
openfile->current_x, allow_punct); openfile->current_x, allow_punct);
bool seen_space = !started_on_word; bool seen_space = !started_on_word;
bool seen_word = started_on_word;
/* Move forward until we reach the start of a word. */ /* Move forward until we reach the start of a word. */
while (TRUE) { while (TRUE) {
@ -340,6 +342,18 @@ bool do_next_word(bool allow_punct, bool update_screen)
openfile->current_x); openfile->current_x);
} }
#ifndef NANO_TINY
if (after_ends) {
/* If this is a word character, continue; else it's a separator,
* and if we've already seen a word, then it's a word end. */
if (is_word_mbchar(openfile->current->data + openfile->current_x,
allow_punct))
seen_word = TRUE;
else if (seen_word)
break;
} else
#endif
{
/* If this is not a word character, then it's a separator; else /* If this is not a word character, then it's a separator; else
* if we've already seen a separator, then it's a word start. */ * if we've already seen a separator, then it's a word start. */
if (!is_word_mbchar(openfile->current->data + openfile->current_x, if (!is_word_mbchar(openfile->current->data + openfile->current_x,
@ -347,6 +361,7 @@ bool do_next_word(bool allow_punct, bool update_screen)
seen_space = TRUE; seen_space = TRUE;
else if (seen_space) else if (seen_space)
break; break;
}
} }
if (update_screen) if (update_screen)
@ -363,11 +378,12 @@ void do_prev_word_void(void)
do_prev_word(ISSET(WORD_BOUNDS), TRUE); do_prev_word(ISSET(WORD_BOUNDS), TRUE);
} }
/* Move to the next word in the file, treating punctuation as part of a word /* Move to the next word in the file. If the AFTER_ENDS flag is set, stop
* if the WORD_BOUNDS flag is set, and update the screen afterwards. */ * at word ends instead of beginnings. If the WORD_BOUNDS flag is set, treat
* punctuation as part of a word. Update the screen afterwards. */
void do_next_word_void(void) void do_next_word_void(void)
{ {
do_next_word(ISSET(WORD_BOUNDS), TRUE); do_next_word(ISSET(AFTER_ENDS), ISSET(WORD_BOUNDS), TRUE);
} }
/* Move to the beginning of the current line (or softwrapped chunk). /* Move to the beginning of the current line (or softwrapped chunk).

View File

@ -888,6 +888,9 @@ void usage(void)
print_opt("-w", "--nowrap", N_("Don't hard-wrap long lines")); print_opt("-w", "--nowrap", N_("Don't hard-wrap long lines"));
#endif #endif
print_opt("-x", "--nohelp", N_("Don't show the two help lines")); print_opt("-x", "--nohelp", N_("Don't show the two help lines"));
#ifndef NANO_TINY
print_opt("-y", "--afterends", N_("Make Ctrl+Right stop at word ends"));
#endif
if (!ISSET(RESTRICTED)) if (!ISSET(RESTRICTED))
print_opt("-z", "--suspend", N_("Enable suspension")); print_opt("-z", "--suspend", N_("Enable suspension"));
#ifndef NANO_TINY #ifndef NANO_TINY
@ -2003,6 +2006,7 @@ int main(int argc, char **argv)
{"autoindent", 0, NULL, 'i'}, {"autoindent", 0, NULL, 'i'},
{"cutfromcursor", 0, NULL, 'k'}, {"cutfromcursor", 0, NULL, 'k'},
{"unix", 0, NULL, 'u'}, {"unix", 0, NULL, 'u'},
{"afterends", 0, NULL, 'y'},
{"softwrap", 0, NULL, '$'}, {"softwrap", 0, NULL, '$'},
#endif #endif
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
@ -2061,7 +2065,7 @@ int main(int argc, char **argv)
while ((optchr = while ((optchr =
getopt_long(argc, argv, getopt_long(argc, argv,
"ABC:DEFGHIKLMNOPQ:RST:UVWX:Y:abcdefghijklmno:pqr:s:tuvwxz$", "ABC:DEFGHIKLMNOPQ:RST:UVWX:Y:abcdefghijklmno:pqr:s:tuvwxyz$",
long_options, NULL)) != -1) { long_options, NULL)) != -1) {
switch (optchr) { switch (optchr) {
case 'b': case 'b':
@ -2256,6 +2260,11 @@ int main(int argc, char **argv)
case 'x': case 'x':
SET(NO_HELP); SET(NO_HELP);
break; break;
#ifndef NANO_TINY
case 'y':
SET(AFTER_ENDS);
break;
#endif
case 'z': case 'z':
SET(SUSPEND); SET(SUSPEND);
break; break;

View File

@ -543,7 +543,8 @@ enum
SHOW_CURSOR, SHOW_CURSOR,
LINE_NUMBERS, LINE_NUMBERS,
NO_PAUSES, NO_PAUSES,
AT_BLANKS AT_BLANKS,
AFTER_ENDS
}; };
/* Flags for the menus in which a given function should be present. */ /* Flags for the menus in which a given function should be present. */

View File

@ -292,17 +292,28 @@ void do_statusbar_cut_text(void)
void do_statusbar_next_word(void) void do_statusbar_next_word(void)
{ {
bool seen_space = !is_word_mbchar(answer + statusbar_x, FALSE); bool seen_space = !is_word_mbchar(answer + statusbar_x, FALSE);
bool seen_word = !seen_space;
/* Move forward until we reach the start of a word. */ /* Move forward until we reach either the end or the start of a word,
* depending on whether the AFTER_ENDS flag is set or not. */
while (answer[statusbar_x] != '\0') { while (answer[statusbar_x] != '\0') {
statusbar_x = move_mbright(answer, statusbar_x); statusbar_x = move_mbright(answer, statusbar_x);
if (ISSET(AFTER_ENDS)) {
/* If this is a word character, continue; else it's a separator,
* and if we've already seen a word, then it's a word end. */
if (is_word_mbchar(answer + statusbar_x, FALSE))
seen_word = TRUE;
else if (seen_word)
break;
} else {
/* If this is not a word character, then it's a separator; else /* If this is not a word character, then it's a separator; else
* if we've already seen a separator, then it's a word start. */ * if we've already seen a separator, then it's a word start. */
if (!is_word_mbchar(answer + statusbar_x, FALSE)) if (!is_word_mbchar(answer + statusbar_x, FALSE))
seen_space = TRUE; seen_space = TRUE;
else if (seen_space) else if (seen_space)
break; break;
}
} }
update_the_statusbar(); update_the_statusbar();

View File

@ -380,7 +380,7 @@ void do_para_end_void(void);
void do_prev_block(void); void do_prev_block(void);
void do_next_block(void); void do_next_block(void);
void do_prev_word(bool allow_punct, bool update_screen); void do_prev_word(bool allow_punct, bool update_screen);
bool do_next_word(bool allow_punct, bool update_screen); bool do_next_word(bool after_ends, bool allow_punct, bool update_screen);
void do_prev_word_void(void); void do_prev_word_void(void);
void do_next_word_void(void); void do_next_word_void(void);
void do_home(void); void do_home(void);

View File

@ -88,6 +88,7 @@ static const rcoption rcopts[] = {
{"tempfile", TEMP_FILE}, {"tempfile", TEMP_FILE},
{"view", VIEW_MODE}, {"view", VIEW_MODE},
#ifndef NANO_TINY #ifndef NANO_TINY
{"afterends", AFTER_ENDS},
{"allow_insecure_backup", INSECURE_BACKUP}, {"allow_insecure_backup", INSECURE_BACKUP},
{"atblanks", AT_BLANKS}, {"atblanks", AT_BLANKS},
{"autoindent", AUTOINDENT}, {"autoindent", AUTOINDENT},

View File

@ -209,7 +209,7 @@ void do_cutword(bool backward)
if (backward) if (backward)
do_prev_word(ISSET(WORD_BOUNDS), FALSE); do_prev_word(ISSET(WORD_BOUNDS), FALSE);
else else
do_next_word(ISSET(WORD_BOUNDS), FALSE); do_next_word(FALSE, ISSET(WORD_BOUNDS), FALSE);
/* Set the mark at the start of that word. */ /* Set the mark at the start of that word. */
openfile->mark = openfile->current; openfile->mark = openfile->current;
@ -3459,7 +3459,7 @@ void do_wordlinechar_count(void)
* count whenever we're on a word just before moving. */ * count whenever we're on a word just before moving. */
while (openfile->current != openfile->filebot || while (openfile->current != openfile->filebot ||
openfile->current->data[openfile->current_x] != '\0') { openfile->current->data[openfile->current_x] != '\0') {
if (do_next_word(TRUE, FALSE)) if (do_next_word(FALSE, TRUE, FALSE))
words++; words++;
} }

View File

@ -7,7 +7,7 @@ comment "#"
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|i?color|extendsyntax).*$" icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|i?color|extendsyntax).*$"
# Keywords # Keywords
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cutfromcursor|fill[[:space:]]+-?[[:digit:]]+|historylog|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|trimblanks|unix|view|wordbounds)\>" icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cutfromcursor|fill[[:space:]]+-?[[:digit:]]+|historylog|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|trimblanks|unix|view|wordbounds)\>"
icolor yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>" icolor yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|titlecolor|whitespace|wordchars)[[:space:]]+" icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|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:]]*$)" 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:]]*$)"