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
parent
4046dfca63
commit
858663444e
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
26
src/move.c
26
src/move.c
|
@ -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).
|
||||||
|
|
11
src/nano.c
11
src/nano.c
|
@ -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;
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
13
src/prompt.c
13
src/prompt.c
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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},
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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:]]*$)"
|
||||||
|
|
Loading…
Reference in New Issue