Merge changes in master

This commit is contained in:
rexy712 2022-08-24 13:03:13 -07:00
commit 02249f1655
68 changed files with 10801 additions and 10449 deletions

View File

@ -1,3 +1,36 @@
Changes between v6.3 and v6.4:
------------------------------
Benno Schulenberg (24):
bump version numbers and add a news item for the 6.4 release
display: remember text and column positions when softwrapping a line
docs: concisely describe how the linter behaves
docs: remove the two notices about the changed defaults
docs: rename README.GIT to README.hacking, so it's clearer what is meant
docs: stop mentioning the obsoleted keywords that were removed
files: designate the root directory with a simple "/", not with "//"
formatter: instead of leaving curses, use full_refresh() to wipe messages
gnulib: update to its current upstream state
help: reshuffle two shortcuts so that more help-line items are paired
options: stop accepting -z, as --suspendable has been dropped too
rcfile: remove five obsolete or deprecated keywords
syntax: default: do not colorize a square or angle bracket after a URL
syntax: perl: add missing keywords, and reduce the length of some lines
syntax: python: mention an alternative linter in a comment
tweaks: add a missing word to a news item
tweaks: add a translator hint
tweaks: improve a comment, and reshuffle two functions plus some lines
tweaks: put each regex on separate line, to better show many keywords
tweaks: rename a variable, to not be the same as a function name
tweaks: rename two variables, to not contain the name of another
tweaks: reshuffle a description and rewrap another
tweaks: reshuffle a few lines, to group things better
version: condense the copyright message, to not dominate the output
LIU Hao (1):
build: ignore errors from `git describe`
Changes between v6.2 and v6.3: Changes between v6.2 and v6.3:
------------------------------ ------------------------------

13
NEWS
View File

@ -1,5 +1,10 @@
2022.08.02 - GNU nano 6.4 "Regentag Dunkelbunt Hundertwasser"
• The file browser does not crash when moving up to the root folder.
• Softwrapping very long lines is done more efficiently.
• Invoking the formatter does not blink the screen.
2022.04.28 - GNU nano 6.3 "Wat zullen we drinken? Wat een dorst!" 2022.04.28 - GNU nano 6.3 "Wat zullen we drinken? Wat een dorst!"
• For multiline regexes, text is now colored as soon a start match • For multiline regexes, text is now colored as soon as a start match
is found, also when there is no end match at all. is found, also when there is no end match at all.
• The colorizing of any line is stopped after two thousand bytes, • The colorizing of any line is stopped after two thousand bytes,
to avoid frustrating delays. to avoid frustrating delays.
@ -931,13 +936,13 @@
the command line will now override any related .nanorc the command line will now override any related .nanorc
entries. Speak now or forever hold your bugs! entries. Speak now or forever hold your bugs!
2009.11.15 - GNU nano 2.1.99pre1 "take a bow" is out there, man, it's 2009.11.15 - GNU nano 2.1.99pre1 "take a bow" is out there, man,
out there all right. This release contains mainly it's out there all right. This release contains mainly
bugfixes, underscoring that we are preparing for the bugfixes, underscoring that we are preparing for the
next stable series release. Included are many fixes next stable series release. Included are many fixes
for the new soft wrapping code, compiler warning tweaks, for the new soft wrapping code, compiler warning tweaks,
and the modification time warning no longer triggers and the modification time warning no longer triggers
when saving a file as a new name. Also include are when saving a file with a new name. Also included are
some fixes for various nanorc options, and there are some fixes for various nanorc options, and there are
surely more bugs to find before we call the code base surely more bugs to find before we call the code base
stable, so please keep those reports coming! stable, so please keep those reports coming!

2
README
View File

@ -15,7 +15,7 @@ Appearance
In rough ASCII graphics, this is what nano's screen looks like: In rough ASCII graphics, this is what nano's screen looks like:
____________________________________________________________________ ____________________________________________________________________
| GNU nano 6.3 filename Modified | | GNU nano 6.4 filename Modified |
-------------------------------------------------------------------- --------------------------------------------------------------------
| This is the text window, displaying the contents of a 'buffer', | | This is the text window, displaying the contents of a 'buffer', |
| the contents of the file you are editing. | | the contents of the file you are editing. |

View File

@ -2,7 +2,7 @@
# Generate configure & friends for GIT users. # Generate configure & friends for GIT users.
gnulib_url="git://git.sv.gnu.org/gnulib.git" gnulib_url="git://git.sv.gnu.org/gnulib.git"
gnulib_hash="34a93be8aa8a15f5959a1b671ad1285a5d552f4b" gnulib_hash="f00af4baf2c7416c5d7c4674c072ef2a51e40668"
modules=" modules="
futimens futimens

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see https://www.gnu.org/licenses/. # along with this program. If not, see https://www.gnu.org/licenses/.
AC_INIT([GNU nano], [6.3], [nano-devel@gnu.org], [nano]) AC_INIT([GNU nano], [6.4], [nano-devel@gnu.org], [nano])
AC_CONFIG_SRCDIR([src/nano.c]) AC_CONFIG_SRCDIR([src/nano.c])
AC_CANONICAL_HOST AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([1.14]) AM_INIT_AUTOMAKE([1.14])

View File

@ -92,7 +92,7 @@
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3> <h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
<blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program &quot;establishes a full duplex terminal connection to a remote host&quot;, and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote> <blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program &quot;establishes a full duplex terminal connection to a remote host&quot;, and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote>
<h3><a name="1.4"></a>1.4. What is the current version of nano?</h3> <h3><a name="1.4"></a>1.4. What is the current version of nano?</h3>
<blockquote><p>The current version of nano <i>should</i> be <b>6.3</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote> <blockquote><p>The current version of nano <i>should</i> be <b>6.4</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
<h3><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h3> <h3><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h3>
<blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/latest/nano.1.html">here</a>.</p></blockquote> <blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/latest/nano.1.html">here</a>.</p></blockquote>
<hr width="100%"> <hr width="100%">

View File

@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see .\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>. .\" <https://www.gnu.org/licenses/>.
.\" .\"
.TH NANO 1 "version 6.3" "April 2022" .TH NANO 1 "version 6.4" "August 2022"
.SH NAME .SH NAME
nano \- Nano's ANOther editor, inspired by Pico nano \- Nano's ANOther editor, inspired by Pico
@ -317,6 +317,10 @@ Don't show the two help lines at the bottom of the screen.
.BR \-y ", " \-\-afterends .BR \-y ", " \-\-afterends
Make Ctrl+Right and Ctrl+Delete stop at word ends instead of beginnings. Make Ctrl+Right and Ctrl+Delete stop at word ends instead of beginnings.
.TP .TP
.BR \-! ", " \-\-magic
When neither the file's name nor its first line give a clue,
try using libmagic to determine the applicable syntax.
.TP
.BR \-% ", " \-\-stateflags .BR \-% ", " \-\-stateflags
Use the top-right corner of the screen for showing some state flags: Use the top-right corner of the screen for showing some state flags:
\fBI\fR when auto-indenting, \fBM\fR when the mark is on, \fBL\fR when \fBI\fR when auto-indenting, \fBM\fR when the mark is on, \fBL\fR when
@ -349,10 +353,6 @@ The status bar appears only when there is a significant message,
and disappears after 1.5 seconds or upon the next keystroke. and disappears after 1.5 seconds or upon the next keystroke.
With \fBM\-Z\fR the title bar plus status bar can be toggled. With \fBM\-Z\fR the title bar plus status bar can be toggled.
With \fBM\-X\fR the help lines. With \fBM\-X\fR the help lines.
.TP
.BR \-! ", " \-\-magic
When neither the file's name nor its first line give a clue,
try using libmagic to determine the applicable syntax.
.SH TOGGLES .SH TOGGLES
Several of the above options can be switched on and off also while Several of the above options can be switched on and off also while

View File

@ -13,8 +13,8 @@ The complete manual for the GNU nano text editor.
@smallbook @smallbook
@set EDITION 0.6 @set EDITION 0.6
@set VERSION 6.3 @set VERSION 6.4
@set UPDATED April 2022 @set UPDATED August 2022
@dircategory Editors @dircategory Editors
@direntry @direntry
@ -29,7 +29,7 @@ The complete manual for the GNU nano text editor.
@title GNU @command{nano} @title GNU @command{nano}
@subtitle a small and friendly text editor @subtitle a small and friendly text editor
@subtitle version 6.3 @subtitle version 6.4
@author Chris Allegretta @author Chris Allegretta
@ -76,7 +76,7 @@ For suggesting improvements: @email{nano-devel@@gnu.org}
@node Top @node Top
@top @top
This manual documents GNU @command{nano}, version 6.3. This manual documents GNU @command{nano}, version 6.4.
@menu @menu
* Introduction:: * Introduction::
@ -672,6 +672,11 @@ disabled to display the help-system navigation keys.
Make @kbd{Ctrl+Right} and @kbd{Ctrl+Delete} stop at word ends Make @kbd{Ctrl+Right} and @kbd{Ctrl+Delete} stop at word ends
instead of beginnings. instead of beginnings.
@item -!
@itemx --magic
When neither the file's name nor its first line give a clue,
try using libmagic to determine the applicable syntax.
@item -% @item -%
@itemx --stateflags @itemx --stateflags
Use the top-right corner of the screen for showing some state flags: Use the top-right corner of the screen for showing some state flags:
@ -708,11 +713,6 @@ and disappears after 1.5 seconds or upon the next keystroke.
With @kbd{M-Z} the title bar plus status bar can be toggled. With @kbd{M-Z} the title bar plus status bar can be toggled.
With @kbd{M-X} the help lines. With @kbd{M-X} the help lines.
@item -!
@itemx --magic
When neither the file's name nor its first line give a clue,
try using libmagic to determine the applicable syntax.
@end table @end table
Option @code{-z} (@code{--suspendable}) has been removed. Option @code{-z} (@code{--suspendable}) has been removed.
@ -1238,9 +1238,6 @@ on the system and will be silently ignored otherwise.)
@item formatter @var{program} [@var{argument} @dots{}] @item formatter @var{program} [@var{argument} @dots{}]
Run the given @var{program} on the full contents of the current buffer. Run the given @var{program} on the full contents of the current buffer.
(The current buffer is written out to a temporary file, the program is
run on it, and then the temporary file is read back in, replacing the
contents of the buffer.)
@item linter @var{program} [@var{argument} @dots{}] @item linter @var{program} [@var{argument} @dots{}]
Use the given @var{program} to do a syntax check on the current buffer. Use the given @var{program} to do a syntax check on the current buffer.
@ -1339,9 +1336,9 @@ Rebinds @code{key} to @code{function} in the context of @code{menu}
@item bind key "string" menu @item bind key "string" menu
Makes @code{key} produce @code{string} in the context of @code{menu} Makes @code{key} produce @code{string} in the context of @code{menu}
(or in all menus where the key exists when @code{all} is used). (or in all menus where the key exists when @code{all} is used).
The @code{string} can consist of text or commands or a mix of them. Besides literal text, the @code{string} may contain function names
(To enter a command into the @code{string}, precede its keystroke between braces. These functions will be invoked when the key is typed.
with @kbd{M-V}.) To include a literal opening brace, use @code{@{@{@}}.
@item unbind key menu @item unbind key menu
Unbinds @code{key} from @code{menu} Unbinds @code{key} from @code{menu}
@ -1479,15 +1476,23 @@ or GNU @command{spell}, or the one defined by @option{--speller} or
@item formatter @item formatter
Invokes a full-buffer-processing program (if the active syntax defines one). Invokes a full-buffer-processing program (if the active syntax defines one).
(The current buffer is written out to a temporary file, the program
is run on it, and then the temporary file is read back in, replacing
the contents of the buffer.)
@item linter @item linter
Invokes a syntax-checking program (if the active syntax defines one). Invokes a syntax-checking program (if the active syntax defines one).
If this program produces lines of the form "filename:linenum:charnum:
some message", then the cursor will be put at the indicated position
in the mentioned file while showing "some message" on the status bar.
You can move from message to message with @kbd{PgUp} and @kbd{PgDn},
and leave linting mode with @kbd{^C} or @kbd{Enter}.
@item justify @item justify
Justifies the current paragraph (or the marked region). Justifies the current paragraph (or the marked region).
A paragraph is a group of contiguous lines A paragraph is a group of contiguous lines that, apart from possibly
that, apart from possibly the first line, all have the same indentation. The the first line, all have the same indentation. The beginning of a
beginning of a paragraph is detected by either this lone line with a differing paragraph is detected by either this lone line with a differing
indentation or by a preceding blank line. indentation or by a preceding blank line.
@item fulljustify @item fulljustify

View File

@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see .\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>. .\" <https://www.gnu.org/licenses/>.
.\" .\"
.TH NANORC 5 "version 6.3" "April 2022" .TH NANORC 5 "version 6.4" "August 2022"
.SH NAME .SH NAME
nanorc \- GNU nano's configuration file nanorc \- GNU nano's configuration file
@ -461,9 +461,6 @@ system and will be silently ignored otherwise.)
.TP .TP
.BI formatter " program " \fR[ "argument " \fR...] .BI formatter " program " \fR[ "argument " \fR...]
Run the given \fIprogram\fR on the full contents of the current buffer. Run the given \fIprogram\fR on the full contents of the current buffer.
(The current buffer is written out to a temporary file, the program is
run on it, and then the temporary file is read back in, replacing the
contents of the buffer.)
.TP .TP
.BI linter " program " \fR[ "argument " \fR...] .BI linter " program " \fR[ "argument " \fR...]
Use the given \fIprogram\fR to run a syntax check on the current buffer. Use the given \fIprogram\fR to run a syntax check on the current buffer.
@ -554,9 +551,9 @@ Rebinds the given \fIkey\fP to the given \fIfunction\fP in the given \fImenu\fP
.BI bind " key " """" string """" " menu" .BI bind " key " """" string """" " menu"
Makes the given \fIkey\fR produce the given \fIstring\fR in the given Makes the given \fIkey\fR produce the given \fIstring\fR in the given
\fImenu\fR (or in all menus where the key exists when \fBall\fR is used). \fImenu\fR (or in all menus where the key exists when \fBall\fR is used).
The \fIstring\fR can consist of text or commands or a mix of them. Besides literal text, the \fIstring\fR may contain function names
(To enter a command into the \fIstring\fR, precede its keystroke between braces. These functions will be invoked when the key is typed.
with \fBM\-V\fR.) To include a literal opening brace, use \fB{{}\fR.
.TP .TP
.BI unbind " key menu" .BI unbind " key menu"
Unbinds the given \fIkey\fP from the given \fImenu\fP (or from all Unbinds the given \fIkey\fP from the given \fImenu\fP (or from all
@ -688,15 +685,23 @@ Invokes a spell-checking program, either the default \fBhunspell\fR(1) or GNU
.TP .TP
.B formatter .B formatter
Invokes a full-buffer-processing program (if the active syntax defines one). Invokes a full-buffer-processing program (if the active syntax defines one).
(The current buffer is written out to a temporary file, the program
is run on it, and then the temporary file is read back in, replacing
the contents of the buffer.)
.TP .TP
.B linter .B linter
Invokes a syntax-checking program (if the active syntax defines one). Invokes a syntax-checking program (if the active syntax defines one).
If this program produces lines of the form "filename:linenum:charnum:
some message", then the cursor will be put at the indicated position
in the mentioned file while showing "some message" on the status bar.
You can move from message to message with <PgUp> and <PgDn>,
and leave linting mode with \fB^C\fR or <Enter>.
.TP .TP
.B justify .B justify
Justifies the current paragraph (or the marked region). Justifies the current paragraph (or the marked region).
A paragraph is a group of contiguous lines A paragraph is a group of contiguous lines that, apart from possibly
that, apart from possibly the first line, all have the same indentation. The the first line, all have the same indentation. The beginning of a
beginning of a paragraph is detected by either this lone line with a differing paragraph is detected by either this lone line with a differing
indentation or by a preceding blank line. indentation or by a preceding blank line.
.TP .TP
.B fulljustify .B fulljustify

View File

@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see .\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>. .\" <https://www.gnu.org/licenses/>.
.\" .\"
.TH RNANO 1 "version 6.3" "April 2022" .TH RNANO 1 "version 6.4" "August 2022"
.SH NAME .SH NAME
rnano \- a restricted nano rnano \- a restricted nano

View File

@ -284,14 +284,13 @@
# unbind M-T main # unbind M-T main
## (Those functions are still accessible through ^T^J and ^T^V.) ## (Those functions are still accessible through ^T^J and ^T^V.)
## For quickly uppercasing or lowercasing the word under the cursor. ## For quickly uppercasing or lowercasing the word under or after the cursor.
## (These effectively do a Ctrl+Right followed by a Shift+Ctrl+Left, ## (These effectively select a word and pipe it through a sed command.)
## and then pipe the selected text through a sed command.) #bind Sh-M-U "{nextword}{mark}{prevword}{execute}|sed 's/.*/\U&/'{enter}" main
# bind Sh-M-U "Oc|sed 's/.*/\U&/' " main #bind Sh-M-L "{nextword}{mark}{prevword}{execute}|sed 's/.*/\L&/'{enter}" main
# bind Sh-M-L "Oc|sed 's/.*/\L&/' " main
## For copying a marked region to the system clipboard: ## For copying a marked region to the system clipboard:
# bind Sh-M-T "|xsel -ib u" main # bind Sh-M-T "{execute}|xsel -ib{enter}{undo}" main
## If you would like nano to have keybindings that are more "usual", ## If you would like nano to have keybindings that are more "usual",
## such as ^O for Open, ^F for Find, ^H for Help, and ^Q for Quit, ## such as ^O for Open, ^F for Find, ^H for Help, and ^Q for Quit,

555
po/bg.po

File diff suppressed because it is too large Load Diff

515
po/ca.po

File diff suppressed because it is too large Load Diff

513
po/cs.po

File diff suppressed because it is too large Load Diff

505
po/da.po

File diff suppressed because it is too large Load Diff

509
po/de.po

File diff suppressed because it is too large Load Diff

507
po/eo.po

File diff suppressed because it is too large Load Diff

507
po/es.po

File diff suppressed because it is too large Load Diff

511
po/eu.po

File diff suppressed because it is too large Load Diff

575
po/fi.po

File diff suppressed because it is too large Load Diff

511
po/fr.po

File diff suppressed because it is too large Load Diff

521
po/ga.po

File diff suppressed because it is too large Load Diff

517
po/gl.po

File diff suppressed because it is too large Load Diff

519
po/hr.po

File diff suppressed because it is too large Load Diff

559
po/hu.po

File diff suppressed because it is too large Load Diff

505
po/id.po

File diff suppressed because it is too large Load Diff

633
po/is.po

File diff suppressed because it is too large Load Diff

559
po/it.po

File diff suppressed because it is too large Load Diff

503
po/ja.po

File diff suppressed because it is too large Load Diff

509
po/ko.po

File diff suppressed because it is too large Load Diff

561
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

508
po/nb.po

File diff suppressed because it is too large Load Diff

507
po/nl.po

File diff suppressed because it is too large Load Diff

505
po/pl.po

File diff suppressed because it is too large Load Diff

507
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

519
po/ro.po

File diff suppressed because it is too large Load Diff

513
po/ru.po

File diff suppressed because it is too large Load Diff

507
po/sk.po

File diff suppressed because it is too large Load Diff

560
po/sl.po

File diff suppressed because it is too large Load Diff

531
po/sq.po

File diff suppressed because it is too large Load Diff

507
po/sr.po

File diff suppressed because it is too large Load Diff

505
po/sv.po

File diff suppressed because it is too large Load Diff

503
po/tr.po

File diff suppressed because it is too large Load Diff

515
po/uk.po

File diff suppressed because it is too large Load Diff

515
po/vi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
VERSION="6.3" VERSION="6.4"
./configure -C --enable-tiny && make && ./configure -C && ./configure -C --enable-tiny && make && ./configure -C &&

View File

@ -461,7 +461,7 @@ char *browse(char *path)
titlebar(path); titlebar(path);
while (TRUE) { while (TRUE) {
functionptrtype func; functionptrtype function;
int kbinput; int kbinput;
lastmessage = VACUUM; lastmessage = VACUUM;
@ -505,73 +505,70 @@ char *browse(char *path)
} }
#endif /* ENABLE_MOUSE */ #endif /* ENABLE_MOUSE */
#ifndef NANO_TINY #ifndef NANO_TINY
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) { while (bracketed_paste)
kbinput = get_kbinput(midwin, BLIND);
if (kbinput == BRACKETED_PASTE_MARKER) {
beep(); beep();
continue; continue;
} }
#endif #endif
func = interpret(&kbinput); function = interpret(kbinput);
if (func == full_refresh) { if (function == full_refresh || function == do_help) {
full_refresh(); function();
#ifndef NANO_TINY #ifndef NANO_TINY
/* Simulate a terminal resize to force a directory reread. */ /* Simulate a terminal resize to force a directory reread,
* or because the terminal dimensions might have changed. */
kbinput = KEY_WINCH; kbinput = KEY_WINCH;
#endif } else if (function == do_toggle && get_shortcut(kbinput)->toggle == NO_HELP) {
} else if (func == do_help) {
do_help();
#ifndef NANO_TINY
/* The terminal dimensions might have changed, so act as if. */
kbinput = KEY_WINCH;
} else if (func == do_toggle) {
TOGGLE(NO_HELP); TOGGLE(NO_HELP);
window_init(); window_init();
kbinput = KEY_WINCH; kbinput = KEY_WINCH;
#endif #endif
} else if (func == do_search_backward) { } else if (function == do_search_backward) {
search_filename(BACKWARD); search_filename(BACKWARD);
} else if (func == do_search_forward) { } else if (function == do_search_forward) {
search_filename(FORWARD); search_filename(FORWARD);
} else if (func == do_findprevious) { } else if (function == do_findprevious) {
research_filename(BACKWARD); research_filename(BACKWARD);
} else if (func == do_findnext) { } else if (function == do_findnext) {
research_filename(FORWARD); research_filename(FORWARD);
} else if (func == do_left) { } else if (function == do_left) {
if (selected > 0) if (selected > 0)
selected--; selected--;
} else if (func == do_right) { } else if (function == do_right) {
if (selected < list_length - 1) if (selected < list_length - 1)
selected++; selected++;
} else if (func == to_prev_word) { } else if (function == to_prev_word) {
selected -= (selected % piles); selected -= (selected % piles);
} else if (func == to_next_word) { } else if (function == to_next_word) {
selected += piles - 1 - (selected % piles); selected += piles - 1 - (selected % piles);
if (selected >= list_length) if (selected >= list_length)
selected = list_length - 1; selected = list_length - 1;
} else if (func == do_up) { } else if (function == do_up) {
if (selected >= piles) if (selected >= piles)
selected -= piles; selected -= piles;
} else if (func == do_down) { } else if (function == do_down) {
if (selected + piles <= list_length - 1) if (selected + piles <= list_length - 1)
selected += piles; selected += piles;
} else if (func == to_prev_block) { } else if (function == to_prev_block) {
selected = ((selected / (usable_rows * piles)) * usable_rows * piles) + selected = ((selected / (usable_rows * piles)) * usable_rows * piles) +
selected % piles; selected % piles;
} else if (func == to_next_block) { } else if (function == to_next_block) {
selected = ((selected / (usable_rows * piles)) * usable_rows * piles) + selected = ((selected / (usable_rows * piles)) * usable_rows * piles) +
selected % piles + usable_rows * piles - piles; selected % piles + usable_rows * piles - piles;
if (selected >= list_length) if (selected >= list_length)
selected = (list_length / piles) * piles + selected % piles; selected = (list_length / piles) * piles + selected % piles;
if (selected >= list_length) if (selected >= list_length)
selected -= piles; selected -= piles;
} else if (func == do_page_up) { } else if (function == do_page_up) {
if (selected < piles) if (selected < piles)
selected = 0; selected = 0;
else if (selected < usable_rows * piles) else if (selected < usable_rows * piles)
selected = selected % piles; selected = selected % piles;
else else
selected -= usable_rows * piles; selected -= usable_rows * piles;
} else if (func == do_page_down) { } else if (function == do_page_down) {
if (selected + piles >= list_length - 1) if (selected + piles >= list_length - 1)
selected = list_length - 1; selected = list_length - 1;
else if (selected + usable_rows * piles >= list_length) else if (selected + usable_rows * piles >= list_length)
@ -579,11 +576,11 @@ char *browse(char *path)
list_length - piles; list_length - piles;
else else
selected += usable_rows * piles; selected += usable_rows * piles;
} else if (func == to_first_file) { } else if (function == to_first_file) {
selected = 0; selected = 0;
} else if (func == to_last_file) { } else if (function == to_last_file) {
selected = list_length - 1; selected = list_length - 1;
} else if (func == goto_dir) { } else if (function == goto_dir) {
/* Ask for the directory to go to. */ /* Ask for the directory to go to. */
if (do_prompt(MGOTODIR, "", NULL, if (do_prompt(MGOTODIR, "", NULL,
/* TRANSLATORS: This is a prompt. */ /* TRANSLATORS: This is a prompt. */
@ -622,7 +619,7 @@ char *browse(char *path)
/* Try opening and reading the specified directory. */ /* Try opening and reading the specified directory. */
goto read_directory_contents; goto read_directory_contents;
} else if (func == do_enter) { } else if (function == do_enter) {
struct stat st; struct stat st;
/* It isn't possible to move up from the root directory. */ /* It isn't possible to move up from the root directory. */
@ -662,14 +659,14 @@ char *browse(char *path)
path = mallocstrcpy(path, filelist[selected]); path = mallocstrcpy(path, filelist[selected]);
goto read_directory_contents; goto read_directory_contents;
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
} else if (func == (functionptrtype)implant) { } else if (function == (functionptrtype)implant) {
implant(first_sc_for(MBROWSER, func)->expansion); implant(first_sc_for(MBROWSER, function)->expansion);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
} else if (kbinput == KEY_WINCH) { } else if (kbinput == KEY_WINCH) {
; /* Gets handled below. */ ; /* Gets handled below. */
#endif #endif
} else if (func == do_exit) { } else if (function == do_exit) {
break; break;
} else } else
unbound_key(kbinput); unbound_key(kbinput);
@ -720,8 +717,8 @@ char *browse_in(const char *inpath)
} }
#ifdef ENABLE_OPERATINGDIR #ifdef ENABLE_OPERATINGDIR
/* If the resulting path isn't in the operating directory, use /* If the resulting path isn't in the operating directory,
* the operating directory instead. */ * use the operating directory instead. */
if (outside_of_confinement(path, FALSE)) if (outside_of_confinement(path, FALSE))
path = mallocstrcpy(path, operating_dir); path = mallocstrcpy(path, operating_dir);
#endif #endif

View File

@ -101,6 +101,13 @@ void do_deletion(undo_type action)
/* We're at the end-of-file: nothing to do. */ /* We're at the end-of-file: nothing to do. */
return; return;
#ifdef ENABLE_COLOR
if (!refresh_needed)
check_the_multis(openfile->current);
#endif
if (!refresh_needed)
update_line(openfile->current, openfile->current_x);
/* Adjust the file size, and remember it for a possible redo. */ /* Adjust the file size, and remember it for a possible redo. */
openfile->totsize--; openfile->totsize--;
#ifndef NANO_TINY #ifndef NANO_TINY

View File

@ -214,6 +214,18 @@
#define SHIFT_DELETE 0x45D #define SHIFT_DELETE 0x45D
#define SHIFT_TAB 0x45F #define SHIFT_TAB 0x45F
/* A special keycode for when a string bind has been partially implanted. */
#define MORE_PLANTS 0x4EA
/* A special keycode for when a string bind has an unpaired opening brace. */
#define MISSING_BRACE 0x4EB
/* A special keycode for when a function in a string bind needs execution. */
#define PLANTED_COMMAND 0x4EC
/* A special keycode for when a function name in a string bind is invalid. */
#define NO_SUCH_FUNCTION 0x4EF
/* A special keycode for when <Tab> is pressed while the mark is on. */ /* A special keycode for when <Tab> is pressed while the mark is on. */
#define INDENT_KEY 0x4F1 #define INDENT_KEY 0x4F1
@ -328,7 +340,6 @@ enum {
CASE_SENSITIVE, CASE_SENSITIVE,
CONSTANT_SHOW, CONSTANT_SHOW,
NO_HELP, NO_HELP,
SUSPENDABLE,
NO_WRAP, NO_WRAP,
AUTOINDENT, AUTOINDENT,
VIEW_MODE, VIEW_MODE,
@ -656,8 +667,6 @@ typedef struct funcstruct {
/* Whether there should be a blank line after the help text /* Whether there should be a blank line after the help text
* for this function. */ * for this function. */
#endif #endif
bool viewok;
/* Is this function allowed when in view mode? */
int menus; int menus;
/* In what menus this function applies. */ /* In what menus this function applies. */
struct funcstruct *next; struct funcstruct *next;

View File

@ -574,12 +574,13 @@ void redecorate_after_switch(void)
/* Prevent a possible Shift selection from getting cancelled. */ /* Prevent a possible Shift selection from getting cancelled. */
shift_held = TRUE; shift_held = TRUE;
/* If the switched-to buffer gave an error during opening, show the message
* once; otherwise, indicate on the status bar which file we switched to. */
if (openfile->errormessage) { if (openfile->errormessage) {
statusline(ALERT, openfile->errormessage); statusline(ALERT, openfile->errormessage);
free(openfile->errormessage); free(openfile->errormessage);
openfile->errormessage = NULL; openfile->errormessage = NULL;
} else } else
/* Indicate on the status bar where we switched to. */
mention_name_and_linecount(); mention_name_and_linecount();
} }
@ -1213,7 +1214,7 @@ void insert_a_file_or(bool execute)
ssize_t was_current_lineno = openfile->current->lineno; ssize_t was_current_lineno = openfile->current->lineno;
size_t was_current_x = openfile->current_x; size_t was_current_x = openfile->current_x;
#if !defined(NANO_TINY) || defined(ENABLE_BROWSER) || defined(ENABLE_MULTIBUFFER) #if !defined(NANO_TINY) || defined(ENABLE_BROWSER) || defined(ENABLE_MULTIBUFFER)
functionptrtype func = func_from_key(&response); functionptrtype function = func_from_key(response);
#endif #endif
given = mallocstrcpy(given, answer); given = mallocstrcpy(given, answer);
@ -1221,7 +1222,7 @@ void insert_a_file_or(bool execute)
break; break;
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (func == flip_newbuffer) { if (function == flip_newbuffer) {
/* Allow toggling only when not in view mode. */ /* Allow toggling only when not in view mode. */
if (!ISSET(VIEW_MODE)) if (!ISSET(VIEW_MODE))
TOGGLE(MULTIBUFFER); TOGGLE(MULTIBUFFER);
@ -1231,22 +1232,22 @@ void insert_a_file_or(bool execute)
} }
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
if (func == flip_convert) { if (function == flip_convert) {
TOGGLE(NO_CONVERT); TOGGLE(NO_CONVERT);
continue; continue;
} }
if (func == flip_execute) { if (function == flip_execute) {
execute = !execute; execute = !execute;
continue; continue;
} }
if (func == flip_pipe) { if (function == flip_pipe) {
add_or_remove_pipe_symbol_from_answer(); add_or_remove_pipe_symbol_from_answer();
given = mallocstrcpy(given, answer); given = mallocstrcpy(given, answer);
continue; continue;
} }
#endif #endif
#ifdef ENABLE_BROWSER #ifdef ENABLE_BROWSER
if (func == to_files) { if (function == to_files) {
char *chosen = browse_in(answer); char *chosen = browse_in(answer);
/* If no file was chosen, go back to the prompt. */ /* If no file was chosen, go back to the prompt. */
@ -2094,7 +2095,7 @@ int write_it_out(bool exiting, bool withprompt)
#endif #endif
while (TRUE) { while (TRUE) {
functionptrtype func; functionptrtype function;
const char *msg; const char *msg;
int response = 0; int response = 0;
int choice = NO; int choice = NO;
@ -2141,10 +2142,10 @@ int write_it_out(bool exiting, bool withprompt)
return 0; return 0;
} }
func = func_from_key(&response); function = func_from_key(response);
/* Upon request, abandon the buffer. */ /* Upon request, abandon the buffer. */
if (func == discard_buffer) { if (function == discard_buffer) {
free(given); free(given);
return 2; return 2;
} }
@ -2152,7 +2153,7 @@ int write_it_out(bool exiting, bool withprompt)
given = mallocstrcpy(given, answer); given = mallocstrcpy(given, answer);
#ifdef ENABLE_BROWSER #ifdef ENABLE_BROWSER
if (func == to_files) { if (function == to_files) {
char *chosen = browse_in(answer); char *chosen = browse_in(answer);
if (chosen == NULL) if (chosen == NULL)
@ -2163,17 +2164,17 @@ int write_it_out(bool exiting, bool withprompt)
} else } else
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
if (func == dos_format) { if (function == dos_format) {
openfile->fmt = (openfile->fmt == DOS_FILE) ? NIX_FILE : DOS_FILE; openfile->fmt = (openfile->fmt == DOS_FILE) ? NIX_FILE : DOS_FILE;
continue; continue;
} else if (func == mac_format) { } else if (function == mac_format) {
openfile->fmt = (openfile->fmt == MAC_FILE) ? NIX_FILE : MAC_FILE; openfile->fmt = (openfile->fmt == MAC_FILE) ? NIX_FILE : MAC_FILE;
continue; continue;
} else if (func == back_it_up) { } else if (function == back_it_up) {
TOGGLE(MAKE_BACKUP); TOGGLE(MAKE_BACKUP);
continue; continue;
} else if (func == prepend_it || func == append_it) { } else if (function == prepend_it || function == append_it) {
if (func == prepend_it) if (function == prepend_it)
method = (method == PREPEND) ? OVERWRITE : PREPEND; method = (method == PREPEND) ? OVERWRITE : PREPEND;
else else
method = (method == APPEND) ? OVERWRITE : APPEND; method = (method == APPEND) ? OVERWRITE : APPEND;
@ -2182,7 +2183,7 @@ int write_it_out(bool exiting, bool withprompt)
continue; continue;
} else } else
#endif #endif
if (func == do_help) if (function == do_help)
continue; continue;
#ifdef ENABLE_EXTRA #ifdef ENABLE_EXTRA
@ -2401,13 +2402,13 @@ int diralphasort(const void *va, const void *vb)
/* Return TRUE when the given path is a directory. */ /* Return TRUE when the given path is a directory. */
bool is_dir(const char *path) bool is_dir(const char *path)
{ {
char *realpath = real_dir_from_tilde(path); char *thepath = real_dir_from_tilde(path);
struct stat fileinfo; struct stat fileinfo;
bool retval; bool retval;
retval = (stat(realpath, &fileinfo) != -1 && S_ISDIR(fileinfo.st_mode)); retval = (stat(thepath, &fileinfo) != -1 && S_ISDIR(fileinfo.st_mode));
free(realpath); free(thepath);
return retval; return retval;
} }

View File

@ -266,6 +266,9 @@ char *startup_problem = NULL;
#endif #endif
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
char *custom_nanorc = NULL; char *custom_nanorc = NULL;
char *commandname = NULL;
keystruct *planted_shortcut = NULL;
#endif #endif
bool spotlighted = FALSE; bool spotlighted = FALSE;
@ -280,11 +283,6 @@ size_t light_to_col = 0;
#define NOVIEW FALSE #define NOVIEW FALSE
#define BLANKAFTER TRUE /* A blank line after this one. */ #define BLANKAFTER TRUE /* A blank line after this one. */
#define TOGETHER FALSE #define TOGETHER FALSE
#ifdef ENABLE_MULTIBUFFER
#define CAN_OPEN_OTHER_BUFFER TRUE
#else
#define CAN_OPEN_OTHER_BUFFER FALSE
#endif
/* Empty functions, for the most part corresponding to toggles. */ /* Empty functions, for the most part corresponding to toggles. */
void case_sens_void(void) {;} void case_sens_void(void) {;}
@ -319,8 +317,8 @@ void discard_buffer(void) {;}
void do_cancel(void) {;} void do_cancel(void) {;}
/* Add a function to the linked list of functions. */ /* Add a function to the linked list of functions. */
void add_to_funcs(void (*func)(void), int menus, const char *desc, void add_to_funcs(void (*function)(void), int menus, const char *desc,
const char *help, bool blank_after, bool viewok) const char *help, bool blank_after)
{ {
funcstruct *f = nmalloc(sizeof(funcstruct)); funcstruct *f = nmalloc(sizeof(funcstruct));
@ -331,10 +329,9 @@ void add_to_funcs(void (*func)(void), int menus, const char *desc,
tailfunc = f; tailfunc = f;
f->next = NULL; f->next = NULL;
f->func = func; f->func = function;
f->menus = menus; f->menus = menus;
f->desc = desc; f->desc = desc;
f->viewok = viewok;
#ifdef ENABLE_HELP #ifdef ENABLE_HELP
f->help = help; f->help = help;
f->blank_after = blank_after; f->blank_after = blank_after;
@ -388,7 +385,7 @@ int keycode_from_string(const char *keystring)
/* Add a key combo to the linked list of shortcuts. */ /* Add a key combo to the linked list of shortcuts. */
void add_to_sclist(int menus, const char *scstring, const int keycode, void add_to_sclist(int menus, const char *scstring, const int keycode,
void (*func)(void), int toggle) void (*function)(void), int toggle)
{ {
static keystruct *tailsc; static keystruct *tailsc;
#ifndef NANO_TINY #ifndef NANO_TINY
@ -405,7 +402,7 @@ void add_to_sclist(int menus, const char *scstring, const int keycode,
/* Fill in the data. */ /* Fill in the data. */
sc->menus = menus; sc->menus = menus;
sc->func = func; sc->func = function;
#ifndef NANO_TINY #ifndef NANO_TINY
sc->toggle = toggle; sc->toggle = toggle;
/* When not the same toggle as the previous one, increment the ID. */ /* When not the same toggle as the previous one, increment the ID. */
@ -419,11 +416,11 @@ void add_to_sclist(int menus, const char *scstring, const int keycode,
} }
/* Return the first shortcut in the list of shortcuts that /* Return the first shortcut in the list of shortcuts that
* matches the given func in the given menu. */ * matches the given function in the given menu. */
const keystruct *first_sc_for(int menu, void (*func)(void)) const keystruct *first_sc_for(int menu, void (*function)(void))
{ {
for (keystruct *sc = sclist; sc != NULL; sc = sc->next) for (keystruct *sc = sclist; sc != NULL; sc = sc->next)
if ((sc->menus & menu) && sc->func == func && sc->keystr[0]) if ((sc->menus & menu) && sc->func == function && sc->keystr[0])
return sc; return sc;
return NULL; return NULL;
@ -451,24 +448,28 @@ size_t shown_entries_for(int menu)
} }
/* Return the first shortcut in the current menu that matches the given input. */ /* Return the first shortcut in the current menu that matches the given input. */
const keystruct *get_shortcut(int *keycode) const keystruct *get_shortcut(const int keycode)
{ {
/* Plain characters and upper control codes cannot be shortcuts. */ /* Plain characters and upper control codes cannot be shortcuts. */
if (!meta_key && 0x20 <= *keycode && *keycode <= 0xFF) if (!meta_key && 0x20 <= keycode && keycode <= 0xFF)
return NULL; return NULL;
/* Lower control codes with Meta cannot be shortcuts either. */ /* Lower control codes with Meta cannot be shortcuts either. */
if (meta_key && *keycode < 0x20) if (meta_key && keycode < 0x20)
return NULL; return NULL;
#ifndef NANO_TINY #ifndef NANO_TINY
/* During a paste at a prompt, ignore all command keycodes. */ /* During a paste at a prompt, ignore all command keycodes. */
if (bracketed_paste && *keycode != BRACKETED_PASTE_MARKER) if (bracketed_paste && keycode != BRACKETED_PASTE_MARKER)
return NULL; return NULL;
#endif #endif
#ifdef ENABLE_NANORC
if (keycode == PLANTED_COMMAND)
return planted_shortcut;
#endif
for (keystruct *sc = sclist; sc != NULL; sc = sc->next) { for (keystruct *sc = sclist; sc != NULL; sc = sc->next) {
if ((sc->menus & currmenu) && *keycode == sc->keycode) if ((sc->menus & currmenu) && keycode == sc->keycode)
return sc; return sc;
} }
@ -476,7 +477,7 @@ const keystruct *get_shortcut(int *keycode)
} }
/* Return a pointer to the function that is bound to the given key. */ /* Return a pointer to the function that is bound to the given key. */
functionptrtype func_from_key(int *keycode) functionptrtype func_from_key(const int keycode)
{ {
const keystruct *sc = get_shortcut(keycode); const keystruct *sc = get_shortcut(keycode);
@ -487,15 +488,15 @@ functionptrtype func_from_key(int *keycode)
/* Return the function that is bound to the given key in the file browser or /* Return the function that is bound to the given key in the file browser or
* the help viewer. Accept also certain plain characters, for compatibility * the help viewer. Accept also certain plain characters, for compatibility
* with Pico or to mimic 'less' and similar text viewers. */ * with Pico or to mimic 'less' and similar text viewers. */
functionptrtype interpret(int *keycode) functionptrtype interpret(const int keycode)
{ {
if (!meta_key) { if (!meta_key) {
if (*keycode == 'N') if (keycode == 'N')
return do_findprevious; return do_findprevious;
if (*keycode == 'n') if (keycode == 'n')
return do_findnext; return do_findnext;
switch (tolower(*keycode)) { switch (tolower(keycode)) {
case 'b': case 'b':
case '-': case '-':
return do_page_up; return do_page_up;
@ -701,42 +702,42 @@ void shortcut_init(void)
#endif /* ENABLE_HELP */ #endif /* ENABLE_HELP */
#ifdef ENABLE_HELP #ifdef ENABLE_HELP
#define WITHORSANS(help) help #define WHENHELP(description) description
#else #else
#define WITHORSANS(help) "" #define WHENHELP(description) ""
#endif #endif
/* Start populating the different menus with functions. */ /* Start populating the different menus with functions. */
#ifdef ENABLE_HELP #ifdef ENABLE_HELP
add_to_funcs(do_help, (MMOST | MBROWSER) & ~MFINDINHELP, add_to_funcs(do_help, (MMOST | MBROWSER) & ~MFINDINHELP,
/* TRANSLATORS: Try to keep the next thirteen strings at most 10 characters. */ /* TRANSLATORS: Try to keep the next thirteen strings at most 10 characters. */
N_("Help"), WITHORSANS(help_gist), TOGETHER, VIEW); N_("Help"), WHENHELP(help_gist), TOGETHER);
#endif #endif
add_to_funcs(do_cancel, ((MMOST & ~MMAIN) | MYESNO), add_to_funcs(do_cancel, ((MMOST & ~MMAIN) | MYESNO),
N_("Cancel"), WITHORSANS(cancel_gist), BLANKAFTER, VIEW); N_("Cancel"), WHENHELP(cancel_gist), BLANKAFTER);
add_to_funcs(do_exit, MMAIN, add_to_funcs(do_exit, MMAIN,
exit_tag, WITHORSANS(exit_gist), TOGETHER, VIEW); exit_tag, WHENHELP(exit_gist), TOGETHER);
/* Remember the entry for Exit, to be able to replace it with Close. */ /* Remember the entry for Exit, to be able to replace it with Close. */
exitfunc = tailfunc; exitfunc = tailfunc;
#ifdef ENABLE_BROWSER #ifdef ENABLE_BROWSER
add_to_funcs(do_exit, MBROWSER, add_to_funcs(do_exit, MBROWSER,
close_tag, WITHORSANS(exitbrowser_gist), TOGETHER, VIEW); close_tag, WHENHELP(exitbrowser_gist), TOGETHER);
#endif #endif
#ifndef ENABLE_HELP #ifndef ENABLE_HELP
add_to_funcs(full_refresh, MMAIN|MREPLACE, "Refresh", "x", 0, VIEW); add_to_funcs(full_refresh, MMAIN|MREPLACE, "Refresh", "x", 0);
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(full_refresh, MINSERTFILE|MEXECUTE, "Refresh", "x", 0, VIEW); add_to_funcs(full_refresh, MINSERTFILE|MEXECUTE, "Refresh", "x", 0);
#endif #endif
add_to_funcs(flip_goto, MWHEREIS, "Go To Line", "x", 0, VIEW); add_to_funcs(flip_goto, MWHEREIS, "Go To Line", "x", 0);
add_to_funcs(flip_goto, MGOTOLINE, "Go To Text", "x", 0, VIEW); add_to_funcs(flip_goto, MGOTOLINE, "Go To Text", "x", 0);
#endif #endif
add_to_funcs(do_writeout, MMAIN, add_to_funcs(do_writeout, MMAIN,
N_("Write Out"), WITHORSANS(writeout_gist), TOGETHER, NOVIEW); N_("Write Out"), WHENHELP(writeout_gist), TOGETHER);
#ifdef ENABLE_JUSTIFY #ifdef ENABLE_JUSTIFY
/* In restricted mode, replace Insert with Justify, when possible; /* In restricted mode, replace Insert with Justify, when possible;
@ -744,365 +745,351 @@ void shortcut_init(void)
if (!ISSET(RESTRICTED)) if (!ISSET(RESTRICTED))
#endif #endif
add_to_funcs(do_insertfile, MMAIN, add_to_funcs(do_insertfile, MMAIN,
N_("Read File"), WITHORSANS(readfile_gist), BLANKAFTER, N_("Read File"), WHENHELP(readfile_gist), BLANKAFTER);
/* We allow inserting files in view mode if multibuffer mode
* is available, so that the user can view multiple files. */
CAN_OPEN_OTHER_BUFFER);
#ifdef ENABLE_JUSTIFY #ifdef ENABLE_JUSTIFY
else else
add_to_funcs(do_justify, MMAIN, add_to_funcs(do_justify, MMAIN,
N_("Justify"), WITHORSANS(justify_gist), BLANKAFTER, NOVIEW); N_("Justify"), WHENHELP(justify_gist), BLANKAFTER);
#endif #endif
#ifdef ENABLE_HELP #ifdef ENABLE_HELP
/* The description ("x") and blank_after (0) are irrelevant, /* The description ("x") and blank_after (0) are irrelevant,
* because the help viewer does not have a help text. */ * because the help viewer does not have a help text. */
add_to_funcs(full_refresh, MHELP, N_("Refresh"), "x", 0, VIEW); add_to_funcs(full_refresh, MHELP, N_("Refresh"), "x", 0);
add_to_funcs(do_exit, MHELP, close_tag, "x", 0, VIEW); add_to_funcs(do_exit, MHELP, close_tag, "x", 0);
#endif #endif
add_to_funcs(do_search_forward, MMAIN|MHELP, add_to_funcs(do_search_forward, MMAIN|MHELP,
N_("Where Is"), WITHORSANS(whereis_gist), TOGETHER, VIEW); N_("Where Is"), WHENHELP(whereis_gist), TOGETHER);
add_to_funcs(do_replace, MMAIN, add_to_funcs(do_replace, MMAIN,
N_("Replace"), WITHORSANS(replace_gist), TOGETHER, NOVIEW); N_("Replace"), WHENHELP(replace_gist), TOGETHER);
#ifdef NANO_TINY #ifdef NANO_TINY
add_to_funcs(do_search_backward, MHELP, add_to_funcs(do_search_backward, MHELP,
N_("Where Was"), WITHORSANS(wherewas_gist), TOGETHER, VIEW); N_("Where Was"), WHENHELP(wherewas_gist), TOGETHER);
add_to_funcs(do_findprevious, MMAIN|MHELP, add_to_funcs(do_findprevious, MMAIN|MHELP,
N_("Previous"), WITHORSANS(findprev_gist), TOGETHER, VIEW); N_("Previous"), WHENHELP(findprev_gist), TOGETHER);
add_to_funcs(do_findnext, MMAIN|MHELP, add_to_funcs(do_findnext, MMAIN|MHELP,
N_("Next"), WITHORSANS(findnext_gist), BLANKAFTER, VIEW); N_("Next"), WHENHELP(findnext_gist), BLANKAFTER);
#endif #endif
add_to_funcs(cut_text, MMAIN, add_to_funcs(cut_text, MMAIN,
N_("Cut"), WITHORSANS(cut_gist), TOGETHER, NOVIEW); N_("Cut"), WHENHELP(cut_gist), TOGETHER);
add_to_funcs(paste_text, MMAIN, add_to_funcs(paste_text, MMAIN,
N_("Paste"), WITHORSANS(paste_gist), BLANKAFTER, NOVIEW); N_("Paste"), WHENHELP(paste_gist), BLANKAFTER);
if (!ISSET(RESTRICTED)) { if (!ISSET(RESTRICTED)) {
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(do_execute, MMAIN, add_to_funcs(do_execute, MMAIN,
N_("Execute"), WITHORSANS(execute_gist), TOGETHER, NOVIEW); N_("Execute"), WHENHELP(execute_gist), TOGETHER);
#endif #endif
#ifdef ENABLE_JUSTIFY #ifdef ENABLE_JUSTIFY
add_to_funcs(do_justify, MMAIN, add_to_funcs(do_justify, MMAIN,
N_("Justify"), WITHORSANS(justify_gist), BLANKAFTER, NOVIEW); N_("Justify"), WHENHELP(justify_gist), BLANKAFTER);
#endif #endif
} }
add_to_funcs(report_cursor_position, MMAIN, add_to_funcs(report_cursor_position, MMAIN,
/* TRANSLATORS: This refers to the position of the cursor. */ /* TRANSLATORS: This refers to the position of the cursor. */
N_("Location"), WITHORSANS(cursorpos_gist), TOGETHER, VIEW); N_("Location"), WHENHELP(cursorpos_gist), TOGETHER);
#if defined(NANO_TINY) || defined(ENABLE_JUSTIFY) #if defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
/* Conditionally placing this one here or further on, to keep the /* Conditionally placing this one here or further on, to keep the
* help items nicely paired in most conditions. */ * help items nicely paired in most conditions. */
add_to_funcs(do_gotolinecolumn, MMAIN, add_to_funcs(do_gotolinecolumn, MMAIN,
N_("Go To Line"), WITHORSANS(gotoline_gist), BLANKAFTER, VIEW); N_("Go To Line"), WHENHELP(gotoline_gist), BLANKAFTER);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(do_undo, MMAIN, add_to_funcs(do_undo, MMAIN,
/* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */ /* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */
N_("Undo"), WITHORSANS(undo_gist), TOGETHER, NOVIEW); N_("Undo"), WHENHELP(undo_gist), TOGETHER);
add_to_funcs(do_redo, MMAIN, add_to_funcs(do_redo, MMAIN,
N_("Redo"), WITHORSANS(redo_gist), BLANKAFTER, NOVIEW); N_("Redo"), WHENHELP(redo_gist), BLANKAFTER);
add_to_funcs(do_mark, MMAIN, add_to_funcs(do_mark, MMAIN,
N_("Set Mark"), WITHORSANS(mark_gist), TOGETHER, VIEW); N_("Set Mark"), WHENHELP(mark_gist), TOGETHER);
add_to_funcs(copy_text, MMAIN, add_to_funcs(copy_text, MMAIN,
N_("Copy"), WITHORSANS(copy_gist), BLANKAFTER, VIEW); N_("Copy"), WHENHELP(copy_gist), BLANKAFTER);
#endif #endif
add_to_funcs(case_sens_void, MWHEREIS|MREPLACE, add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
N_("Case Sens"), WITHORSANS(case_gist), TOGETHER, VIEW); N_("Case Sens"), WHENHELP(case_gist), TOGETHER);
add_to_funcs(regexp_void, MWHEREIS|MREPLACE, add_to_funcs(regexp_void, MWHEREIS|MREPLACE,
N_("Reg.exp."), WITHORSANS(regexp_gist), TOGETHER, VIEW); N_("Reg.exp."), WHENHELP(regexp_gist), TOGETHER);
add_to_funcs(backwards_void, MWHEREIS|MREPLACE, add_to_funcs(backwards_void, MWHEREIS|MREPLACE,
N_("Backwards"), WITHORSANS(reverse_gist), BLANKAFTER, VIEW); N_("Backwards"), WHENHELP(reverse_gist), BLANKAFTER);
add_to_funcs(flip_replace, MWHEREIS, add_to_funcs(flip_replace, MWHEREIS,
N_("Replace"), WITHORSANS(replace_gist), BLANKAFTER, VIEW); N_("Replace"), WHENHELP(replace_gist), BLANKAFTER);
add_to_funcs(flip_replace, MREPLACE, add_to_funcs(flip_replace, MREPLACE,
N_("No Replace"), WITHORSANS(whereis_gist), BLANKAFTER, VIEW); N_("No Replace"), WHENHELP(whereis_gist), BLANKAFTER);
#ifdef ENABLE_HISTORIES #ifdef ENABLE_HISTORIES
add_to_funcs(get_older_item, MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, add_to_funcs(get_older_item, MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE,
N_("Older"), WITHORSANS(older_gist), TOGETHER, VIEW); N_("Older"), WHENHELP(older_gist), TOGETHER);
add_to_funcs(get_newer_item, MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, add_to_funcs(get_newer_item, MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE,
N_("Newer"), WITHORSANS(newer_gist), BLANKAFTER, VIEW); N_("Newer"), WHENHELP(newer_gist), BLANKAFTER);
#endif
#ifdef ENABLE_HELP
add_to_funcs(flip_goto, MWHEREIS,
N_("Go To Line"), WITHORSANS(gotoline_gist), BLANKAFTER, VIEW);
#endif #endif
#ifdef ENABLE_BROWSER #ifdef ENABLE_BROWSER
add_to_funcs(goto_dir, MBROWSER, add_to_funcs(goto_dir, MBROWSER,
/* TRANSLATORS: Try to keep the next four strings at most 10 characters. */ /* TRANSLATORS: Try to keep the next four strings at most 10 characters. */
N_("Go To Dir"), WITHORSANS(gotodir_gist), TOGETHER, VIEW); N_("Go To Dir"), WHENHELP(gotodir_gist), TOGETHER);
#ifdef ENABLE_HELP #ifdef ENABLE_HELP
add_to_funcs(full_refresh, MBROWSER, add_to_funcs(full_refresh, MBROWSER,
N_("Refresh"), WITHORSANS(browserrefresh_gist), BLANKAFTER, VIEW); N_("Refresh"), WHENHELP(browserrefresh_gist), BLANKAFTER);
#endif #endif
add_to_funcs(do_search_forward, MBROWSER, add_to_funcs(do_search_forward, MBROWSER,
N_("Where Is"), WITHORSANS(browserwhereis_gist), TOGETHER, VIEW); N_("Where Is"), WHENHELP(browserwhereis_gist), TOGETHER);
add_to_funcs(do_search_backward, MBROWSER, add_to_funcs(do_search_backward, MBROWSER,
N_("Where Was"), WITHORSANS(browserwherewas_gist), TOGETHER, VIEW); N_("Where Was"), WHENHELP(browserwherewas_gist), TOGETHER);
add_to_funcs(do_findprevious, MBROWSER, add_to_funcs(do_findprevious, MBROWSER,
N_("Previous"), WITHORSANS(findprev_gist), TOGETHER, VIEW); N_("Previous"), WHENHELP(findprev_gist), TOGETHER);
add_to_funcs(do_findnext, MBROWSER, add_to_funcs(do_findnext, MBROWSER,
N_("Next"), WITHORSANS(findnext_gist), BLANKAFTER, VIEW); N_("Next"), WHENHELP(findnext_gist), BLANKAFTER);
#endif #endif
#ifdef NANO_TINY #ifdef NANO_TINY
add_to_funcs(to_prev_word, MMAIN, add_to_funcs(to_prev_word, MMAIN,
"Prev Word", WITHORSANS(prevword_gist), TOGETHER, VIEW); "Prev Word", WHENHELP(prevword_gist), TOGETHER);
add_to_funcs(to_next_word, MMAIN, add_to_funcs(to_next_word, MMAIN,
"Next Word", WITHORSANS(nextword_gist), BLANKAFTER, VIEW); "Next Word", WHENHELP(nextword_gist), BLANKAFTER);
#else #else
add_to_funcs(do_find_bracket, MMAIN, add_to_funcs(do_find_bracket, MMAIN,
N_("To Bracket"), WITHORSANS(bracket_gist), BLANKAFTER, VIEW); N_("To Bracket"), WHENHELP(bracket_gist), BLANKAFTER);
add_to_funcs(do_search_backward, MMAIN|MHELP, add_to_funcs(do_search_backward, MMAIN|MHELP,
/* TRANSLATORS: This starts a backward search. */ /* TRANSLATORS: This starts a backward search. */
N_("Where Was"), WITHORSANS(wherewas_gist), TOGETHER, VIEW); N_("Where Was"), WHENHELP(wherewas_gist), TOGETHER);
add_to_funcs(do_findprevious, MMAIN|MHELP, add_to_funcs(do_findprevious, MMAIN|MHELP,
/* TRANSLATORS: This refers to searching the preceding occurrence. */ /* TRANSLATORS: This refers to searching the preceding occurrence. */
N_("Previous"), WITHORSANS(findprev_gist), TOGETHER, VIEW); N_("Previous"), WHENHELP(findprev_gist), TOGETHER);
add_to_funcs(do_findnext, MMAIN|MHELP, add_to_funcs(do_findnext, MMAIN|MHELP,
N_("Next"), WITHORSANS(findnext_gist), BLANKAFTER, VIEW); N_("Next"), WHENHELP(findnext_gist), BLANKAFTER);
#endif #endif
add_to_funcs(do_left, MMAIN, add_to_funcs(do_left, MMAIN,
/* TRANSLATORS: This means move the cursor one character back. */ /* TRANSLATORS: This means move the cursor one character back. */
N_("Back"), WITHORSANS(back_gist), TOGETHER, VIEW); N_("Back"), WHENHELP(back_gist), TOGETHER);
add_to_funcs(do_right, MMAIN, add_to_funcs(do_right, MMAIN,
N_("Forward"), WITHORSANS(forward_gist), TOGETHER, VIEW); N_("Forward"), WHENHELP(forward_gist), TOGETHER);
#ifdef ENABLE_BROWSER #ifdef ENABLE_BROWSER
add_to_funcs(do_left, MBROWSER, add_to_funcs(do_left, MBROWSER,
N_("Back"), WITHORSANS(backfile_gist), TOGETHER, VIEW); N_("Back"), WHENHELP(backfile_gist), TOGETHER);
add_to_funcs(do_right, MBROWSER, add_to_funcs(do_right, MBROWSER,
N_("Forward"), WITHORSANS(forwardfile_gist), TOGETHER, VIEW); N_("Forward"), WHENHELP(forwardfile_gist), TOGETHER);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(to_prev_word, MMAIN, add_to_funcs(to_prev_word, MMAIN,
/* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */ /* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */
N_("Prev Word"), WITHORSANS(prevword_gist), TOGETHER, VIEW); N_("Prev Word"), WHENHELP(prevword_gist), TOGETHER);
add_to_funcs(to_next_word, MMAIN, add_to_funcs(to_next_word, MMAIN,
N_("Next Word"), WITHORSANS(nextword_gist), TOGETHER, VIEW); N_("Next Word"), WHENHELP(nextword_gist), TOGETHER);
#endif #endif
add_to_funcs(do_home, MMAIN, add_to_funcs(do_home, MMAIN,
N_("Home"), WITHORSANS(home_gist), TOGETHER, VIEW); N_("Home"), WHENHELP(home_gist), TOGETHER);
add_to_funcs(do_end, MMAIN, add_to_funcs(do_end, MMAIN,
N_("End"), WITHORSANS(end_gist), BLANKAFTER, VIEW); N_("End"), WHENHELP(end_gist), BLANKAFTER);
add_to_funcs(do_up, MMAIN|MBROWSER|MHELP, add_to_funcs(do_up, MMAIN|MBROWSER|MHELP,
N_("Prev Line"), WITHORSANS(prevline_gist), TOGETHER, VIEW); N_("Prev Line"), WHENHELP(prevline_gist), TOGETHER);
add_to_funcs(do_down, MMAIN|MBROWSER|MHELP, add_to_funcs(do_down, MMAIN|MBROWSER|MHELP,
N_("Next Line"), WITHORSANS(nextline_gist), TOGETHER, VIEW); N_("Next Line"), WHENHELP(nextline_gist), TOGETHER);
#if !defined(NANO_TINY) || defined(ENABLE_HELP) #if !defined(NANO_TINY) || defined(ENABLE_HELP)
add_to_funcs(do_scroll_up, MMAIN, add_to_funcs(do_scroll_up, MMAIN,
N_("Scroll Up"), WITHORSANS(scrollup_gist), TOGETHER, VIEW); N_("Scroll Up"), WHENHELP(scrollup_gist), TOGETHER);
add_to_funcs(do_scroll_down, MMAIN, add_to_funcs(do_scroll_down, MMAIN,
N_("Scroll Down"), WITHORSANS(scrolldown_gist), BLANKAFTER, VIEW); N_("Scroll Down"), WHENHELP(scrolldown_gist), BLANKAFTER);
#endif #endif
add_to_funcs(to_prev_block, MMAIN, add_to_funcs(to_prev_block, MMAIN,
N_("Prev Block"), WITHORSANS(prevblock_gist), TOGETHER, VIEW); N_("Prev Block"), WHENHELP(prevblock_gist), TOGETHER);
add_to_funcs(to_next_block, MMAIN, add_to_funcs(to_next_block, MMAIN,
N_("Next Block"), WITHORSANS(nextblock_gist), TOGETHER, VIEW); N_("Next Block"), WHENHELP(nextblock_gist), TOGETHER);
#ifdef ENABLE_JUSTIFY #ifdef ENABLE_JUSTIFY
add_to_funcs(to_para_begin, MMAIN|MGOTOLINE, add_to_funcs(to_para_begin, MMAIN|MGOTOLINE,
/* TRANSLATORS: Try to keep these two strings at most 16 characters. */ /* TRANSLATORS: Try to keep these two strings at most 16 characters. */
N_("Begin of Paragr."), WITHORSANS(parabegin_gist), TOGETHER, VIEW); N_("Begin of Paragr."), WHENHELP(parabegin_gist), TOGETHER);
add_to_funcs(to_para_end, MMAIN|MGOTOLINE, add_to_funcs(to_para_end, MMAIN|MGOTOLINE,
N_("End of Paragraph"), WITHORSANS(paraend_gist), BLANKAFTER, VIEW); N_("End of Paragraph"), WHENHELP(paraend_gist), BLANKAFTER);
#endif #endif
add_to_funcs(do_page_up, MMAIN|MHELP, add_to_funcs(do_page_up, MMAIN|MHELP,
/* TRANSLATORS: Try to keep the next six strings at most 12 characters. */ /* TRANSLATORS: Try to keep the next six strings at most 12 characters. */
N_("Prev Page"), WITHORSANS(prevpage_gist), TOGETHER, VIEW); N_("Prev Page"), WHENHELP(prevpage_gist), TOGETHER);
add_to_funcs(do_page_down, MMAIN|MHELP, add_to_funcs(do_page_down, MMAIN|MHELP,
N_("Next Page"), WITHORSANS(nextpage_gist), TOGETHER, VIEW); N_("Next Page"), WHENHELP(nextpage_gist), TOGETHER);
add_to_funcs(to_first_line, MMAIN|MHELP|MGOTOLINE, add_to_funcs(to_first_line, MMAIN|MHELP|MGOTOLINE,
N_("First Line"), WITHORSANS(firstline_gist), TOGETHER, VIEW); N_("First Line"), WHENHELP(firstline_gist), TOGETHER);
add_to_funcs(to_last_line, MMAIN|MHELP|MGOTOLINE, add_to_funcs(to_last_line, MMAIN|MHELP|MGOTOLINE,
N_("Last Line"), WITHORSANS(lastline_gist), BLANKAFTER, VIEW); N_("Last Line"), WHENHELP(lastline_gist), BLANKAFTER);
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
add_to_funcs(switch_to_prev_buffer, MMAIN, add_to_funcs(switch_to_prev_buffer, MMAIN,
N_("Prev File"), WITHORSANS(prevfile_gist), TOGETHER, VIEW); N_("Prev File"), WHENHELP(prevfile_gist), TOGETHER);
add_to_funcs(switch_to_next_buffer, MMAIN, add_to_funcs(switch_to_next_buffer, MMAIN,
N_("Next File"), WITHORSANS(nextfile_gist), BLANKAFTER, VIEW); N_("Next File"), WHENHELP(nextfile_gist), BLANKAFTER);
#endif #endif
#if !defined(NANO_TINY) && !defined(ENABLE_JUSTIFY) #if !defined(NANO_TINY) && !defined(ENABLE_JUSTIFY)
add_to_funcs(do_gotolinecolumn, MMAIN, add_to_funcs(do_gotolinecolumn, MMAIN,
N_("Go To Line"), WITHORSANS(gotoline_gist), BLANKAFTER, VIEW); N_("Go To Line"), WHENHELP(gotoline_gist), BLANKAFTER);
#endif #endif
add_to_funcs(do_tab, MMAIN, add_to_funcs(do_tab, MMAIN,
/* TRANSLATORS: The next four strings are names of keyboard keys. */ /* TRANSLATORS: The next four strings are names of keyboard keys. */
N_("Tab"), WITHORSANS(tab_gist), TOGETHER, NOVIEW); N_("Tab"), WHENHELP(tab_gist), TOGETHER);
add_to_funcs(do_enter, MMAIN, add_to_funcs(do_enter, MMAIN,
N_("Enter"), WITHORSANS(enter_gist), BLANKAFTER, NOVIEW); N_("Enter"), WHENHELP(enter_gist), BLANKAFTER);
add_to_funcs(do_backspace, MMAIN, add_to_funcs(do_backspace, MMAIN,
N_("Backspace"), WITHORSANS(backspace_gist), TOGETHER, NOVIEW); N_("Backspace"), WHENHELP(backspace_gist), TOGETHER);
add_to_funcs(do_delete, MMAIN, add_to_funcs(do_delete, MMAIN,
N_("Delete"), WITHORSANS(delete_gist), N_("Delete"), WHENHELP(delete_gist), BLANKAFTER);
#ifndef NANO_TINY
TOGETHER,
#else
BLANKAFTER,
#endif
NOVIEW);
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(chop_previous_word, MMAIN, add_to_funcs(chop_previous_word, MMAIN,
/* TRANSLATORS: The next two strings refer to deleting words. */ /* TRANSLATORS: The next two strings refer to deleting words. */
N_("Chop Left"), WITHORSANS(chopwordleft_gist), TOGETHER, NOVIEW); N_("Chop Left"), WHENHELP(chopwordleft_gist), TOGETHER);
add_to_funcs(chop_next_word, MMAIN, add_to_funcs(chop_next_word, MMAIN,
N_("Chop Right"), WITHORSANS(chopwordright_gist), TOGETHER, NOVIEW); N_("Chop Right"), WHENHELP(chopwordright_gist), TOGETHER);
add_to_funcs(cut_till_eof, MMAIN, add_to_funcs(cut_till_eof, MMAIN,
N_("Cut Till End"), WITHORSANS(cuttilleof_gist), BLANKAFTER, NOVIEW); N_("Cut Till End"), WHENHELP(cuttilleof_gist), BLANKAFTER);
#endif #endif
#ifdef ENABLE_JUSTIFY #ifdef ENABLE_JUSTIFY
add_to_funcs(do_full_justify, MMAIN, add_to_funcs(do_full_justify, MMAIN,
N_("Full Justify"), WITHORSANS(fulljustify_gist), TOGETHER, NOVIEW); N_("Full Justify"), WHENHELP(fulljustify_gist), TOGETHER);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(count_lines_words_and_characters, MMAIN, add_to_funcs(count_lines_words_and_characters, MMAIN,
N_("Word Count"), WITHORSANS(wordcount_gist), TOGETHER, VIEW); N_("Word Count"), WHENHELP(wordcount_gist), TOGETHER);
#endif #endif
add_to_funcs(do_verbatim_input, MMAIN, add_to_funcs(do_verbatim_input, MMAIN,
N_("Verbatim"), WITHORSANS(verbatim_gist), BLANKAFTER, NOVIEW); N_("Verbatim"), WHENHELP(verbatim_gist), BLANKAFTER);
#ifndef NANO_TINY
add_to_funcs(do_suspend, MMAIN,
N_("Suspend"), WITHORSANS(suspend_gist), TOGETHER, VIEW);
#endif
#ifdef ENABLE_HELP
add_to_funcs(full_refresh, MMAIN,
N_("Refresh"), WITHORSANS(refresh_gist), BLANKAFTER, VIEW);
#endif
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(do_indent, MMAIN, add_to_funcs(do_indent, MMAIN,
N_("Indent"), WITHORSANS(indent_gist), TOGETHER, NOVIEW); N_("Indent"), WHENHELP(indent_gist), TOGETHER);
add_to_funcs(do_unindent, MMAIN, add_to_funcs(do_unindent, MMAIN,
N_("Unindent"), WITHORSANS(unindent_gist), BLANKAFTER, NOVIEW); N_("Unindent"), WHENHELP(unindent_gist), BLANKAFTER);
#endif #endif
#ifdef ENABLE_COMMENT #ifdef ENABLE_COMMENT
add_to_funcs(do_comment, MMAIN, add_to_funcs(do_comment, MMAIN,
N_("Comment Lines"), WITHORSANS(comment_gist), TOGETHER, NOVIEW); N_("Comment Lines"), WHENHELP(comment_gist), TOGETHER);
#endif #endif
#ifdef ENABLE_WORDCOMPLETION #ifdef ENABLE_WORDCOMPLETION
add_to_funcs(complete_a_word, MMAIN, add_to_funcs(complete_a_word, MMAIN,
N_("Complete"), WITHORSANS(completion_gist), BLANKAFTER, NOVIEW); N_("Complete"), WHENHELP(completion_gist), BLANKAFTER);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(record_macro, MMAIN, add_to_funcs(record_macro, MMAIN,
N_("Record"), WITHORSANS(recordmacro_gist), TOGETHER, VIEW); N_("Record"), WHENHELP(recordmacro_gist), TOGETHER);
add_to_funcs(run_macro, MMAIN, add_to_funcs(run_macro, MMAIN,
N_("Run Macro"), WITHORSANS(runmacro_gist), BLANKAFTER, VIEW); N_("Run Macro"), WHENHELP(runmacro_gist), BLANKAFTER);
#endif #endif
#ifdef ENABLE_FOLDING #ifdef ENABLE_FOLDING
add_to_funcs(do_fold_segment, MMAIN, N_("Fold"), add_to_funcs(do_fold_segment, MMAIN, N_("Fold"),
WITHORSANS(fold_gist), BLANKAFTER, VIEW); WHENHELP(fold_gist), BLANKAFTER);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(put_or_lift_anchor, MMAIN,
N_("Anchor"), WITHORSANS(anchor_gist), TOGETHER, VIEW);
add_to_funcs(to_prev_anchor, MMAIN,
N_("Up to anchor"), WITHORSANS(prevanchor_gist), TOGETHER, VIEW);
add_to_funcs(to_next_anchor, MMAIN,
N_("Down to anchor"), WITHORSANS(nextanchor_gist), BLANKAFTER, VIEW);
add_to_funcs(zap_text, MMAIN, add_to_funcs(zap_text, MMAIN,
/* TRANSLATORS: This refers to deleting a line or marked region. */ /* TRANSLATORS: This refers to deleting a line or marked region. */
N_("Zap"), WITHORSANS(zap_gist), BLANKAFTER, NOVIEW); N_("Zap"), WHENHELP(zap_gist), BLANKAFTER);
add_to_funcs(put_or_lift_anchor, MMAIN,
N_("Anchor"), WHENHELP(anchor_gist), TOGETHER);
add_to_funcs(to_prev_anchor, MMAIN,
N_("Up to anchor"), WHENHELP(prevanchor_gist), TOGETHER);
add_to_funcs(to_next_anchor, MMAIN,
N_("Down to anchor"), WHENHELP(nextanchor_gist), BLANKAFTER);
if (!ISSET(RESTRICTED)) { if (!ISSET(RESTRICTED)) {
#ifdef ENABLE_SPELLER #ifdef ENABLE_SPELLER
add_to_funcs(do_spell, MMAIN, add_to_funcs(do_spell, MMAIN,
N_("Spell Check"), WITHORSANS(spell_gist), TOGETHER, NOVIEW); N_("Spell Check"), WHENHELP(spell_gist), TOGETHER);
#endif #endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
add_to_funcs(do_linter, MMAIN, add_to_funcs(do_linter, MMAIN,
N_("Linter"), WITHORSANS(lint_gist), TOGETHER, NOVIEW); N_("Linter"), WHENHELP(lint_gist), TOGETHER);
add_to_funcs(do_formatter, MMAIN, add_to_funcs(do_formatter, MMAIN,
N_("Formatter"), WITHORSANS(formatter_gist), BLANKAFTER, NOVIEW); N_("Formatter"), WHENHELP(formatter_gist), BLANKAFTER);
#endif #endif
} }
#endif /* !NANO_TINY */ #endif /* !NANO_TINY */
#ifdef NANO_TINY #ifdef NANO_TINY
add_to_funcs(do_search_backward, MMAIN, add_to_funcs(do_search_backward, MMAIN,
N_("Where Was"), WITHORSANS(wherewas_gist), BLANKAFTER, VIEW); N_("Where Was"), WHENHELP(wherewas_gist), BLANKAFTER);
#else
add_to_funcs(do_suspend, MMAIN,
N_("Suspend"), WHENHELP(suspend_gist), TOGETHER);
#endif
#ifdef ENABLE_HELP
add_to_funcs(full_refresh, MMAIN,
N_("Refresh"), WHENHELP(refresh_gist), TOGETHER);
#endif #endif
#if !defined(NANO_TINY) || defined(ENABLE_HELP) #if !defined(NANO_TINY) || defined(ENABLE_HELP)
add_to_funcs(do_center, MMAIN, add_to_funcs(do_center, MMAIN,
N_("Center"), WITHORSANS(center_gist), BLANKAFTER, VIEW); N_("Center"), WHENHELP(center_gist), BLANKAFTER);
#endif #endif
add_to_funcs(do_savefile, MMAIN, add_to_funcs(do_savefile, MMAIN,
N_("Save"), WITHORSANS(savefile_gist), BLANKAFTER, NOVIEW); N_("Save"), WHENHELP(savefile_gist), BLANKAFTER);
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
/* Multiple buffers are only available when not in restricted mode. */ /* Include the new-buffer toggle only when it can actually be used. */
if (!ISSET(RESTRICTED)) if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE))
add_to_funcs(flip_newbuffer, MINSERTFILE|MEXECUTE, add_to_funcs(flip_newbuffer, MINSERTFILE|MEXECUTE,
N_("New Buffer"), WITHORSANS(newbuffer_gist), TOGETHER, NOVIEW); N_("New Buffer"), WHENHELP(newbuffer_gist), TOGETHER);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(flip_pipe, MEXECUTE, add_to_funcs(flip_pipe, MEXECUTE,
N_("Pipe Text"), WITHORSANS(pipe_gist), BLANKAFTER, NOVIEW); N_("Pipe Text"), WHENHELP(pipe_gist), BLANKAFTER);
#endif #endif
#ifdef ENABLE_SPELLER #ifdef ENABLE_SPELLER
add_to_funcs(do_spell, MEXECUTE, add_to_funcs(do_spell, MEXECUTE,
N_("Spell Check"), WITHORSANS(spell_gist), TOGETHER, NOVIEW); N_("Spell Check"), WHENHELP(spell_gist), TOGETHER);
#endif #endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
add_to_funcs(do_linter, MEXECUTE, add_to_funcs(do_linter, MEXECUTE,
N_("Linter"), WITHORSANS(lint_gist), BLANKAFTER, NOVIEW); N_("Linter"), WHENHELP(lint_gist), BLANKAFTER);
#endif #endif
#ifdef ENABLE_JUSTIFY #ifdef ENABLE_JUSTIFY
add_to_funcs(do_full_justify, MEXECUTE, add_to_funcs(do_full_justify, MEXECUTE,
N_("Full Justify"), WITHORSANS(fulljustify_gist), TOGETHER, NOVIEW); N_("Full Justify"), WHENHELP(fulljustify_gist), TOGETHER);
#endif #endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
add_to_funcs(do_formatter, MEXECUTE, add_to_funcs(do_formatter, MEXECUTE,
N_("Formatter"), WITHORSANS(formatter_gist), BLANKAFTER, NOVIEW); N_("Formatter"), WHENHELP(formatter_gist), BLANKAFTER);
#endif #endif
#ifdef ENABLE_HELP #ifdef ENABLE_HELP
add_to_funcs(flip_goto, MWHEREIS,
N_("Go To Line"), WHENHELP(gotoline_gist), BLANKAFTER);
add_to_funcs(flip_goto, MGOTOLINE, add_to_funcs(flip_goto, MGOTOLINE,
N_("Go To Text"), WITHORSANS(whereis_gist), BLANKAFTER, VIEW); N_("Go To Text"), WHENHELP(whereis_gist), BLANKAFTER);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(dos_format, MWRITEFILE, add_to_funcs(dos_format, MWRITEFILE,
N_("DOS Format"), WITHORSANS(dos_gist), TOGETHER, NOVIEW); N_("DOS Format"), WHENHELP(dos_gist), TOGETHER);
add_to_funcs(mac_format, MWRITEFILE, add_to_funcs(mac_format, MWRITEFILE,
N_("Mac Format"), WITHORSANS(mac_gist), TOGETHER, NOVIEW); N_("Mac Format"), WHENHELP(mac_gist), TOGETHER);
/* If we're using restricted mode, the Append, Prepend, and Backup toggles /* If we're using restricted mode, the Append, Prepend, and Backup toggles
* are disabled. The first and second are not useful as they only allow * are disabled. The first and second are not useful as they only allow
@ -1110,27 +1097,27 @@ void shortcut_init(void)
* would write to a file not specified on the command line. */ * would write to a file not specified on the command line. */
if (!ISSET(RESTRICTED)) { if (!ISSET(RESTRICTED)) {
add_to_funcs(append_it, MWRITEFILE, add_to_funcs(append_it, MWRITEFILE,
N_("Append"), WITHORSANS(append_gist), TOGETHER, NOVIEW); N_("Append"), WHENHELP(append_gist), TOGETHER);
add_to_funcs(prepend_it, MWRITEFILE, add_to_funcs(prepend_it, MWRITEFILE,
N_("Prepend"), WITHORSANS(prepend_gist), TOGETHER, NOVIEW); N_("Prepend"), WHENHELP(prepend_gist), TOGETHER);
add_to_funcs(back_it_up, MWRITEFILE, add_to_funcs(back_it_up, MWRITEFILE,
N_("Backup File"), WITHORSANS(backup_gist), BLANKAFTER, NOVIEW); N_("Backup File"), WHENHELP(backup_gist), BLANKAFTER);
} }
add_to_funcs(flip_convert, MINSERTFILE, add_to_funcs(flip_convert, MINSERTFILE,
N_("No Conversion"), WITHORSANS(convert_gist), BLANKAFTER, NOVIEW); N_("No Conversion"), WHENHELP(convert_gist), BLANKAFTER);
/* Command execution is only available when not in restricted mode. */ /* Command execution is only available when not in restricted mode. */
if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) { if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) {
add_to_funcs(flip_execute, MINSERTFILE, add_to_funcs(flip_execute, MINSERTFILE,
N_("Execute Command"), WITHORSANS(execute_gist), BLANKAFTER, NOVIEW); N_("Execute Command"), WHENHELP(execute_gist), BLANKAFTER);
add_to_funcs(cut_till_eof, MEXECUTE, add_to_funcs(cut_till_eof, MEXECUTE,
N_("Cut Till End"), WITHORSANS(cuttilleof_gist), BLANKAFTER, NOVIEW); N_("Cut Till End"), WHENHELP(cuttilleof_gist), BLANKAFTER);
add_to_funcs(do_suspend, MEXECUTE, add_to_funcs(do_suspend, MEXECUTE,
N_("Suspend"), WITHORSANS(suspend_gist), BLANKAFTER, VIEW); N_("Suspend"), WHENHELP(suspend_gist), BLANKAFTER);
} }
#endif /* !NANO_TINY */ #endif /* !NANO_TINY */
@ -1139,39 +1126,39 @@ void shortcut_init(void)
if (!ISSET(RESTRICTED)) if (!ISSET(RESTRICTED))
add_to_funcs(to_files, MWRITEFILE|MINSERTFILE, add_to_funcs(to_files, MWRITEFILE|MINSERTFILE,
/* TRANSLATORS: This invokes the file browser. */ /* TRANSLATORS: This invokes the file browser. */
N_("Browse"), WITHORSANS(tofiles_gist), BLANKAFTER, VIEW); N_("Browse"), WHENHELP(tofiles_gist), BLANKAFTER);
add_to_funcs(do_page_up, MBROWSER, add_to_funcs(do_page_up, MBROWSER,
N_("Prev Page"), WITHORSANS(prevpage_gist), TOGETHER, VIEW); N_("Prev Page"), WHENHELP(prevpage_gist), TOGETHER);
add_to_funcs(do_page_down, MBROWSER, add_to_funcs(do_page_down, MBROWSER,
N_("Next Page"), WITHORSANS(nextpage_gist), TOGETHER, VIEW); N_("Next Page"), WHENHELP(nextpage_gist), TOGETHER);
add_to_funcs(to_first_file, MBROWSER|MWHEREISFILE, add_to_funcs(to_first_file, MBROWSER|MWHEREISFILE,
N_("First File"), WITHORSANS(firstfile_gist), TOGETHER, VIEW); N_("First File"), WHENHELP(firstfile_gist), TOGETHER);
add_to_funcs(to_last_file, MBROWSER|MWHEREISFILE, add_to_funcs(to_last_file, MBROWSER|MWHEREISFILE,
N_("Last File"), WITHORSANS(lastfile_gist), BLANKAFTER, VIEW); N_("Last File"), WHENHELP(lastfile_gist), BLANKAFTER);
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_funcs(to_prev_word, MBROWSER, add_to_funcs(to_prev_word, MBROWSER,
N_("Left Column"), WITHORSANS(browserlefthand_gist), TOGETHER, VIEW); N_("Left Column"), WHENHELP(browserlefthand_gist), TOGETHER);
add_to_funcs(to_next_word, MBROWSER, add_to_funcs(to_next_word, MBROWSER,
N_("Right Column"), WITHORSANS(browserrighthand_gist), TOGETHER, VIEW); N_("Right Column"), WHENHELP(browserrighthand_gist), TOGETHER);
add_to_funcs(to_prev_block, MBROWSER, add_to_funcs(to_prev_block, MBROWSER,
N_("Top Row"), WITHORSANS(browsertoprow_gist), TOGETHER, VIEW); N_("Top Row"), WHENHELP(browsertoprow_gist), TOGETHER);
add_to_funcs(to_next_block, MBROWSER, add_to_funcs(to_next_block, MBROWSER,
N_("Bottom Row"), WITHORSANS(browserbottomrow_gist), BLANKAFTER, VIEW); N_("Bottom Row"), WHENHELP(browserbottomrow_gist), BLANKAFTER);
#endif #endif
#endif /* ENABLE_BROWSER */ #endif /* ENABLE_BROWSER */
add_to_funcs(discard_buffer, MWRITEFILE, add_to_funcs(discard_buffer, MWRITEFILE,
N_("Discard buffer"), WITHORSANS(discardbuffer_gist), BLANKAFTER, NOVIEW); N_("Discard buffer"), WHENHELP(discardbuffer_gist), BLANKAFTER);
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
add_to_funcs(do_page_up, MLINTER, add_to_funcs(do_page_up, MLINTER,
/* TRANSLATORS: The next two strings may be up to 37 characters each. */ /* TRANSLATORS: The next two strings may be up to 37 characters each. */
N_("Previous Linter message"), WITHORSANS(prevlint_gist), TOGETHER, VIEW); N_("Previous Linter message"), WHENHELP(prevlint_gist), TOGETHER);
add_to_funcs(do_page_down, MLINTER, add_to_funcs(do_page_down, MLINTER,
N_("Next Linter message"), WITHORSANS(nextlint_gist), TOGETHER, VIEW); N_("Next Linter message"), WHENHELP(nextlint_gist), TOGETHER);
#endif #endif
#ifdef __linux__ #ifdef __linux__
@ -1205,22 +1192,21 @@ void shortcut_init(void)
add_to_sclist(MMOST, "^K", 0, cut_text, 0); add_to_sclist(MMOST, "^K", 0, cut_text, 0);
#ifdef NANO_TINY #ifdef NANO_TINY
add_to_sclist(MMAIN, "^U", 0, paste_text, 0); add_to_sclist(MMAIN, "^U", 0, paste_text, 0);
#ifdef ENABLE_SPELLER
add_to_sclist(MMAIN, "^T", 0, do_spell, 0);
#endif
#else #else
add_to_sclist(MMOST, "^U", 0, paste_text, 0); add_to_sclist(MMOST, "^U", 0, paste_text, 0);
add_to_sclist(MMAIN, "^T", 0, do_execute, 0); add_to_sclist(MMAIN, "^T", 0, do_execute, 0);
#endif
#ifdef ENABLE_JUSTIFY
add_to_sclist(MMAIN, "^J", '\n', do_justify, 0);
#endif
#ifdef ENABLE_SPELLER #ifdef ENABLE_SPELLER
#ifndef NANO_TINY
if (!ISSET(PRESERVE)) if (!ISSET(PRESERVE))
add_to_sclist(MEXECUTE, "^S", 0, do_spell, 0); add_to_sclist(MEXECUTE, "^S", 0, do_spell, 0);
add_to_sclist(MEXECUTE, "^T", 0, do_spell, 0); add_to_sclist(MEXECUTE, "^T", 0, do_spell, 0);
#else
add_to_sclist(MMAIN, "^T", 0, do_spell, 0);
#endif #endif
#endif #endif
#ifdef ENABLE_JUSTIFY
add_to_sclist(MMAIN, "^J", '\n', do_justify, 0);
#endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
add_to_sclist(MMAIN, "M-B", 0, do_linter, 0); add_to_sclist(MMAIN, "M-B", 0, do_linter, 0);
add_to_sclist(MEXECUTE, "^Y", 0, do_linter, 0); add_to_sclist(MEXECUTE, "^Y", 0, do_linter, 0);
@ -1293,7 +1279,7 @@ void shortcut_init(void)
add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x96\xb8", KEY_RIGHT, do_right, 0); add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x96\xb8", KEY_RIGHT, do_right, 0);
add_to_sclist(MSOME, "^\xE2\x97\x82", CONTROL_LEFT, to_prev_word, 0); add_to_sclist(MSOME, "^\xE2\x97\x82", CONTROL_LEFT, to_prev_word, 0);
add_to_sclist(MSOME, "^\xE2\x96\xb8", CONTROL_RIGHT, to_next_word, 0); add_to_sclist(MSOME, "^\xE2\x96\xb8", CONTROL_RIGHT, to_next_word, 0);
#if !defined(NANO_TINY) && defined(ENABLE_MULTIBUFFER) #if defined(ENABLE_MULTIBUFFER) && !defined(NANO_TINY)
if (!on_a_vt) { if (!on_a_vt) {
add_to_sclist(MMAIN, "M-\xE2\x97\x82", ALT_LEFT, switch_to_prev_buffer, 0); add_to_sclist(MMAIN, "M-\xE2\x97\x82", ALT_LEFT, switch_to_prev_buffer, 0);
add_to_sclist(MMAIN, "M-\xE2\x96\xb8", ALT_RIGHT, switch_to_next_buffer, 0); add_to_sclist(MMAIN, "M-\xE2\x96\xb8", ALT_RIGHT, switch_to_next_buffer, 0);
@ -1306,7 +1292,7 @@ void shortcut_init(void)
add_to_sclist(MMOST|MBROWSER|MHELP, "Right", KEY_RIGHT, do_right, 0); add_to_sclist(MMOST|MBROWSER|MHELP, "Right", KEY_RIGHT, do_right, 0);
add_to_sclist(MSOME, "^Left", CONTROL_LEFT, to_prev_word, 0); add_to_sclist(MSOME, "^Left", CONTROL_LEFT, to_prev_word, 0);
add_to_sclist(MSOME, "^Right", CONTROL_RIGHT, to_next_word, 0); add_to_sclist(MSOME, "^Right", CONTROL_RIGHT, to_next_word, 0);
#ifdef ENABLE_MULTIBUFFER #if defined(ENABLE_MULTIBUFFER) && !defined(NANO_TINY)
if (!on_a_vt) { if (!on_a_vt) {
add_to_sclist(MMAIN, "M-Left", ALT_LEFT, switch_to_prev_buffer, 0); add_to_sclist(MMAIN, "M-Left", ALT_LEFT, switch_to_prev_buffer, 0);
add_to_sclist(MMAIN, "M-Right", ALT_RIGHT, switch_to_next_buffer, 0); add_to_sclist(MMAIN, "M-Right", ALT_RIGHT, switch_to_next_buffer, 0);
@ -1475,8 +1461,7 @@ void shortcut_init(void)
add_to_sclist(MINSERTFILE, "M-N", 0, flip_convert, 0); add_to_sclist(MINSERTFILE, "M-N", 0, flip_convert, 0);
#endif #endif
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
/* Only when not in restricted mode, allow multiple buffers. */ if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) {
if (!ISSET(RESTRICTED)) {
add_to_sclist(MINSERTFILE|MEXECUTE, "M-F", 0, flip_newbuffer, 0); add_to_sclist(MINSERTFILE|MEXECUTE, "M-F", 0, flip_newbuffer, 0);
#ifndef NANO_TINY #ifndef NANO_TINY
add_to_sclist(MEXECUTE, "M-\\", 0, flip_pipe, 0); add_to_sclist(MEXECUTE, "M-\\", 0, flip_pipe, 0);

View File

@ -317,10 +317,10 @@ void help_init(void)
/* Hard-wrap the concatenated help text, and write it into a new buffer. */ /* Hard-wrap the concatenated help text, and write it into a new buffer. */
void wrap_help_text_into_buffer(void) void wrap_help_text_into_buffer(void)
{ {
size_t sum = 0;
/* Avoid overtight and overwide paragraphs in the introductory text. */ /* Avoid overtight and overwide paragraphs in the introductory text. */
size_t wrapping_point = ((COLS < 40) ? 40 : (COLS > 74) ? 74 : COLS) - thebar; size_t wrapping_point = ((COLS < 40) ? 40 : (COLS > 74) ? 74 : COLS) - thebar;
const char *ptr = start_of_body; const char *ptr = start_of_body;
size_t sum = 0;
make_new_buffer(); make_new_buffer();
@ -389,7 +389,7 @@ void wrap_help_text_into_buffer(void)
void show_help(void) void show_help(void)
{ {
int kbinput = ERR; int kbinput = ERR;
functionptrtype func; functionptrtype function;
/* The function of the key the user typed in. */ /* The function of the key the user typed in. */
int oldmenu = currmenu; int oldmenu = currmenu;
/* The menu we were called from. */ /* The menu we were called from. */
@ -475,28 +475,28 @@ void show_help(void)
continue; continue;
} }
#endif #endif
func = interpret(&kbinput); function = interpret(kbinput);
if (func == full_refresh) { if (function == full_refresh) {
full_refresh(); full_refresh();
} else if (ISSET(SHOW_CURSOR) && (func == do_left || func == do_right || } else if (ISSET(SHOW_CURSOR) && (function == do_left || function == do_right ||
func == do_up || func == do_down)) { function == do_up || function == do_down)) {
func(); function();
} else if (func == do_up || func == do_scroll_up) { } else if (function == do_up || function == do_scroll_up) {
do_scroll_up(); do_scroll_up();
} else if (func == do_down || func == do_scroll_down) { } else if (function == do_down || function == do_scroll_down) {
if (openfile->edittop->lineno + editwinrows - 1 < openfile->filebot->lineno) if (openfile->edittop->lineno + editwinrows - 1 < openfile->filebot->lineno)
do_scroll_down(); do_scroll_down();
} else if (func == do_page_up || func == do_page_down || } else if (function == do_page_up || function == do_page_down ||
func == to_first_line || func == to_last_line) { function == to_first_line || function == to_last_line) {
func(); function();
} else if (func == do_search_backward || func == do_search_forward || } else if (function == do_search_backward || function == do_search_forward ||
func == do_findprevious || func == do_findnext) { function == do_findprevious || function == do_findnext) {
func(); function();
bottombars(MHELP); bottombars(MHELP);
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
} else if (func == (functionptrtype)implant) { } else if (function == (functionptrtype)implant) {
implant(first_sc_for(MHELP, func)->expansion); implant(first_sc_for(MHELP, function)->expansion);
#endif #endif
#ifdef ENABLE_MOUSE #ifdef ENABLE_MOUSE
} else if (kbinput == KEY_MOUSE) { } else if (kbinput == KEY_MOUSE) {
@ -507,7 +507,7 @@ void show_help(void)
} else if (kbinput == KEY_WINCH) { } else if (kbinput == KEY_WINCH) {
; /* Nothing to do. */ ; /* Nothing to do. */
#endif #endif
} else if (func == do_exit) { } else if (function == do_exit) {
break; break;
} else } else
unbound_key(kbinput); unbound_key(kbinput);

View File

@ -104,8 +104,8 @@ size_t proper_x(linestruct *line, size_t *leftedge, bool forward,
* the middle of a tab that crosses a row boundary. */ * the middle of a tab that crosses a row boundary. */
void set_proper_index_and_pww(size_t *leftedge, size_t target, bool forward) void set_proper_index_and_pww(size_t *leftedge, size_t target, bool forward)
{ {
bool shifted = FALSE;
size_t was_edge = *leftedge; size_t was_edge = *leftedge;
bool shifted = FALSE;
openfile->current_x = proper_x(openfile->current, leftedge, forward, openfile->current_x = proper_x(openfile->current, leftedge, forward,
actual_last_column(*leftedge, target), &shifted); actual_last_column(*leftedge, target), &shifted);

View File

@ -365,9 +365,9 @@ void emergency_save(const char *filename)
* that were modified. */ * that were modified. */
void die(const char *msg, ...) void die(const char *msg, ...)
{ {
va_list ap;
openfilestruct *firstone = openfile; openfilestruct *firstone = openfile;
static int stabs = 0; static int stabs = 0;
va_list ap;
/* When dying for a second time, just give up. */ /* When dying for a second time, just give up. */
if (++stabs > 1) if (++stabs > 1)
@ -658,13 +658,15 @@ void usage(void)
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 #ifndef NANO_TINY
print_opt("-y", "--afterends", N_("Make Ctrl+Right stop at word ends")); print_opt("-y", "--afterends", N_("Make Ctrl+Right stop at word ends"));
print_opt("-%", "--stateflags", N_("Show some states on the title bar"));
print_opt("-_", "--minibar", N_("Show a feedback bar at the bottom"));
print_opt("-0", "--zero", N_("Hide all bars, use whole terminal"));
#endif #endif
#ifdef HAVE_LIBMAGIC #ifdef HAVE_LIBMAGIC
print_opt("-!", "--magic", N_("Also try magic to determine syntax")); print_opt("-!", "--magic", N_("Also try magic to determine syntax"));
#endif #endif
#ifndef NANO_TINY
print_opt("-%", "--stateflags", N_("Show some states on the title bar"));
print_opt("-_", "--minibar", N_("Show a feedback bar at the bottom"));
print_opt("-0", "--zero", N_("Hide all bars, use whole terminal"));
#endif
} }
/* Display the version number of this nano, a copyright notice, some contact /* Display the version number of this nano, a copyright notice, some contact
@ -677,6 +679,7 @@ void version(void)
printf(_(" GNU nano, version %s\n"), VERSION); printf(_(" GNU nano, version %s\n"), VERSION);
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
/* TRANSLATORS: The %s is the year of the latest release. */
printf(_(" (C) %s the Free Software Foundation and various contributors\n"), "2022"); printf(_(" (C) %s the Free Software Foundation and various contributors\n"), "2022");
#endif #endif
printf(_(" Compiled options:")); printf(_(" Compiled options:"));
@ -1273,6 +1276,12 @@ void unbound_key(int code)
/* TRANSLATORS: This refers to a sequence of escape codes /* TRANSLATORS: This refers to a sequence of escape codes
* (from the keyboard) that nano does not recognize. */ * (from the keyboard) that nano does not recognize. */
statusline(AHEM, _("Unknown sequence")); statusline(AHEM, _("Unknown sequence"));
#ifdef ENABLE_NANORC
else if (code == MISSING_BRACE)
statusline(AHEM, _("Missing }"));
else if (code == NO_SUCH_FUNCTION)
statusline(AHEM, _("No such function: %s"), commandname);
#endif
#ifndef NANO_TINY #ifndef NANO_TINY
else if (code > KEY_F0 && code < KEY_F0 + 25) else if (code > KEY_F0 && code < KEY_F0 + 25)
/* TRANSLATORS: This refers to an unbound function key. */ /* TRANSLATORS: This refers to an unbound function key. */
@ -1362,7 +1371,7 @@ int do_mouse(void)
/* Return TRUE when the given function is a cursor-moving command. */ /* Return TRUE when the given function is a cursor-moving command. */
bool wanted_to_move(void (*func)(void)) bool wanted_to_move(void (*func)(void))
{ {
return func == do_left || func == do_right || return (func == do_left || func == do_right ||
func == do_up || func == do_down || func == do_up || func == do_down ||
func == do_home || func == do_end || func == do_home || func == do_end ||
func == to_prev_word || func == to_next_word || func == to_prev_word || func == to_next_word ||
@ -1371,19 +1380,33 @@ bool wanted_to_move(void (*func)(void))
#endif #endif
func == to_prev_block || func == to_next_block || func == to_prev_block || func == to_next_block ||
func == do_page_up || func == do_page_down || func == do_page_up || func == do_page_down ||
func == to_first_line || func == to_last_line; func == to_first_line || func == to_last_line);
} }
/* Return TRUE when the given shortcut is admissible in view mode. */ /* Return TRUE when the given function makes a change -- no good for view mode. */
bool okay_for_view(const keystruct *shortcut) bool changes_something(const void *f)
{ {
funcstruct *item = allfuncs; return (f == do_savefile || f == do_writeout || f == do_enter ||
f == do_tab || f == do_delete || f == do_backspace ||
/* Search the function of the given shortcut in the list of functions. */ f == cut_text || f == paste_text || f == do_replace ||
while (item != NULL && item->func != shortcut->func) #ifndef NANO_TINY
item = item->next; f == chop_previous_word || f == chop_next_word ||
f == zap_text || f == cut_till_eof || f == do_execute ||
return (item == NULL || item->viewok); f == do_indent || f == do_unindent || f == do_comment ||
#endif
#ifdef ENABLE_JUSTIFY
f == do_justify || f == do_full_justify ||
#endif
#ifdef ENABLE_SPELLER
f == do_spell ||
#endif
#ifdef ENABLE_COLOR
f == do_formatter ||
#endif
#ifdef ENABLE_WORDCOMPLETION
f == complete_a_word ||
#endif
f == do_verbatim_input);
} }
#ifndef NANO_TINY #ifndef NANO_TINY
@ -1529,6 +1552,7 @@ void process_a_keystroke(void)
#endif #endif
static bool give_a_hint = TRUE; static bool give_a_hint = TRUE;
const keystruct *shortcut; const keystruct *shortcut;
functionptrtype function;
/* Read in a keystroke, and show the cursor while waiting. */ /* Read in a keystroke, and show the cursor while waiting. */
input = get_kbinput(midwin, VISIBLE); input = get_kbinput(midwin, VISIBLE);
@ -1551,10 +1575,11 @@ void process_a_keystroke(void)
#endif #endif
/* Check for a shortcut in the main list. */ /* Check for a shortcut in the main list. */
shortcut = get_shortcut(&input); shortcut = get_shortcut(input);
function = (shortcut ? shortcut->func : NULL);
/* If not a command, discard anything that is not a normal character byte. */ /* If not a command, discard anything that is not a normal character byte. */
if (shortcut == NULL) { if (!function) {
if (input < 0x20 || input > 0xFF || meta_key) if (input < 0x20 || input > 0xFF || meta_key)
unbound_key(input); unbound_key(input);
else if (ISSET(VIEW_MODE)) else if (ISSET(VIEW_MODE))
@ -1574,7 +1599,7 @@ void process_a_keystroke(void)
/* If we have a command, or if there aren't any other key codes waiting, /* If we have a command, or if there aren't any other key codes waiting,
* it's time to insert the gathered bytes into the edit buffer. */ * it's time to insert the gathered bytes into the edit buffer. */
if ((shortcut || waiting_keycodes() == 0) && puddle != NULL) { if ((function || waiting_keycodes() == 0) && puddle != NULL) {
puddle[depth] = '\0'; puddle[depth] = '\0';
inject(puddle, depth); inject(puddle, depth);
@ -1584,13 +1609,13 @@ void process_a_keystroke(void)
depth = 0; depth = 0;
} }
if (shortcut == NULL) { if (!function) {
pletion_line = NULL; pletion_line = NULL;
keep_cutbuffer = FALSE; keep_cutbuffer = FALSE;
return; return;
} }
if (ISSET(VIEW_MODE) && !okay_for_view(shortcut)) { if (ISSET(VIEW_MODE) && changes_something(function)) {
print_view_warning(); print_view_warning();
return; return;
} }
@ -1603,25 +1628,25 @@ void process_a_keystroke(void)
give_a_hint = FALSE; give_a_hint = FALSE;
/* When not cutting or copying text, drop the cutbuffer the next time. */ /* When not cutting or copying text, drop the cutbuffer the next time. */
if (shortcut->func != cut_text) { if (function != cut_text) {
#ifndef NANO_TINY #ifndef NANO_TINY
if (shortcut->func != copy_text && shortcut->func != zap_text) if (function != copy_text && function != zap_text)
#endif #endif
keep_cutbuffer = FALSE; keep_cutbuffer = FALSE;
} }
#ifdef ENABLE_WORDCOMPLETION #ifdef ENABLE_WORDCOMPLETION
if (shortcut->func != complete_a_word) if (function != complete_a_word)
pletion_line = NULL; pletion_line = NULL;
#endif #endif
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
if (shortcut->func == (functionptrtype)implant) { if (function == (functionptrtype)implant) {
implant(shortcut->expansion); implant(shortcut->expansion);
return; return;
} }
#endif #endif
#ifndef NANO_TINY #ifndef NANO_TINY
if (shortcut->func == do_toggle) { if (function == do_toggle) {
toggle_this(shortcut->toggle); toggle_this(shortcut->toggle);
if (shortcut->toggle == CUT_FROM_CURSOR) if (shortcut->toggle == CUT_FROM_CURSOR)
keep_cutbuffer = FALSE; keep_cutbuffer = FALSE;
@ -1640,32 +1665,21 @@ void process_a_keystroke(void)
#endif #endif
/* Execute the function of the shortcut. */ /* Execute the function of the shortcut. */
shortcut->func(); function();
#ifndef NANO_TINY #ifndef NANO_TINY
/* When the marked region changes without Shift being held, /* When the marked region changes without Shift being held,
* discard a soft mark. And when the marked region covers a * discard a soft mark. And when the set of lines changes,
* different set of lines, reset the "last line too" flag. */ * reset the "last line too" flag. */
if (openfile->mark) { if (openfile->mark && openfile->softmark && !shift_held &&
if (!shift_held && openfile->softmark &&
(openfile->current != was_current || (openfile->current != was_current ||
openfile->current_x != was_x || openfile->current_x != was_x ||
wanted_to_move(shortcut->func))) { wanted_to_move(function))) {
openfile->mark = NULL; openfile->mark = NULL;
refresh_needed = TRUE; refresh_needed = TRUE;
} else if (openfile->current != was_current) } else if (openfile->current != was_current)
also_the_last = FALSE; also_the_last = FALSE;
}
#endif
#ifdef ENABLE_COLOR
if (!refresh_needed && !okay_for_view(shortcut))
check_the_multis(openfile->current);
#endif
if (!refresh_needed && (shortcut->func == do_delete ||
shortcut->func == do_backspace))
update_line(openfile->current, openfile->current_x);
#ifndef NANO_TINY
if (bracketed_paste) if (bracketed_paste)
suck_up_input_and_paste_it(); suck_up_input_and_paste_it();
@ -1822,8 +1836,8 @@ int main(int argc, char **argv)
if (*(tail(argv[0])) == 'r') if (*(tail(argv[0])) == 'r')
SET(RESTRICTED); SET(RESTRICTED);
while ((optchr = getopt_long(argc, argv, "0ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Z" while ((optchr = getopt_long(argc, argv, "ABC:DEFGHIJ:KLMNOPQ:RS$T:UVWX:Y:Z"
"abcdef:ghijklmno:pqr:s:tuvwxyz$%_!", long_options, NULL)) != -1) { "abcdef:ghijklmno:pqr:s:tuvwxy!%_0", long_options, NULL)) != -1) {
switch (optchr) { switch (optchr) {
#ifndef NANO_TINY #ifndef NANO_TINY
case 'A': case 'A':
@ -2056,8 +2070,11 @@ int main(int argc, char **argv)
SET(AFTER_ENDS); SET(AFTER_ENDS);
break; break;
#endif #endif
case 'z': #ifdef HAVE_LIBMAGIC
case '!':
SET(USE_MAGIC);
break; break;
#endif
#ifndef NANO_TINY #ifndef NANO_TINY
case '%': case '%':
SET(STATEFLAGS); SET(STATEFLAGS);
@ -2068,11 +2085,6 @@ int main(int argc, char **argv)
case '0': case '0':
SET(ZERO); SET(ZERO);
break; break;
#endif
#ifdef HAVE_LIBMAGIC
case '!':
SET(USE_MAGIC);
break;
#endif #endif
default: default:
printf(_("Type '%s -h' for a list of available options.\n"), argv[0]); printf(_("Type '%s -h' for a list of available options.\n"), argv[0]);
@ -2532,6 +2544,11 @@ int main(int argc, char **argv)
statusbar(_("Welcome to nano. For basic help, type Ctrl+G.")); statusbar(_("Welcome to nano. For basic help, type Ctrl+G."));
#endif #endif
#ifdef ENABLE_LINENUMBERS
/* Set the margin to an impossible value to force re-evaluation. */
margin = 12345;
#endif
we_are_running = TRUE; we_are_running = TRUE;
while (TRUE) { while (TRUE) {

View File

@ -41,6 +41,33 @@ void do_statusbar_end(void)
} }
#ifndef NANO_TINY #ifndef NANO_TINY
/* Move to the previous word in the answer. */
void do_statusbar_prev_word(void)
{
bool seen_a_word = FALSE, step_forward = FALSE;
/* Move backward until we pass over the start of a word. */
while (typing_x != 0) {
typing_x = step_left(answer, typing_x);
if (is_word_char(answer + typing_x, FALSE))
seen_a_word = TRUE;
#ifdef ENABLE_UTF8
else if (is_zerowidth(answer + typing_x))
; /* skip */
#endif
else if (seen_a_word) {
/* This is space now: we've overshot the start of the word. */
step_forward = TRUE;
break;
}
}
if (step_forward)
/* Move one character forward again to sit on the start of the word. */
typing_x = step_right(answer, typing_x);
}
/* Move to the next word in the answer. */ /* Move to the next word in the answer. */
void do_statusbar_next_word(void) void do_statusbar_next_word(void)
{ {
@ -78,33 +105,6 @@ void do_statusbar_next_word(void)
} }
} }
} }
/* Move to the previous word in the answer. */
void do_statusbar_prev_word(void)
{
bool seen_a_word = FALSE, step_forward = FALSE;
/* Move backward until we pass over the start of a word. */
while (typing_x != 0) {
typing_x = step_left(answer, typing_x);
if (is_word_char(answer + typing_x, FALSE))
seen_a_word = TRUE;
#ifdef ENABLE_UTF8
else if (is_zerowidth(answer + typing_x))
; /* skip */
#endif
else if (seen_a_word) {
/* This is space now: we've overshot the start of the word. */
step_forward = TRUE;
break;
}
}
if (step_forward)
/* Move one character forward again to sit on the start of the word. */
typing_x = step_right(answer, typing_x);
}
#endif /* !NANO_TINY */ #endif /* !NANO_TINY */
/* Move left one character in the answer. */ /* Move left one character in the answer. */
@ -131,6 +131,17 @@ void do_statusbar_right(void)
} }
} }
/* Backspace over one character in the answer. */
void do_statusbar_backspace(void)
{
if (typing_x > 0) {
size_t was_x = typing_x;
typing_x = step_left(answer, typing_x);
memmove(answer + typing_x, answer + was_x, strlen(answer) - was_x + 1);
}
}
/* Delete one character in the answer. */ /* Delete one character in the answer. */
void do_statusbar_delete(void) void do_statusbar_delete(void)
{ {
@ -146,17 +157,6 @@ void do_statusbar_delete(void)
} }
} }
/* Backspace over one character in the answer. */
void do_statusbar_backspace(void)
{
if (typing_x > 0) {
size_t was_x = typing_x;
typing_x = step_left(answer, typing_x);
memmove(answer + typing_x, answer + was_x, strlen(answer) - was_x + 1);
}
}
/* Zap the part of the answer after the cursor, or the whole answer. */ /* Zap the part of the answer after the cursor, or the whole answer. */
void lop_the_answer(void) void lop_the_answer(void)
{ {
@ -250,47 +250,19 @@ void do_statusbar_verbatim_input(void)
free(bytes); free(bytes);
} }
/* Read in a keystroke, interpret it if it is a shortcut or toggle, and /* Add the given input to the input buffer when it's a normal byte,
* return it. Set finished to TRUE if we're done after running * and inject the gathered bytes into the answer when ready. */
* or trying to run a function associated with a shortcut key. */ void absorb_character(int input, functionptrtype function)
int do_statusbar_input(bool *finished)
{ {
int input;
/* The character we read in. */
static char *puddle = NULL; static char *puddle = NULL;
/* The input buffer. */ /* The input buffer. */
static size_t depth = 0; static size_t depth = 0;
/* The length of the input buffer. */ /* The length of the input buffer. */
const keystruct *shortcut;
*finished = FALSE;
/* Read in a character. */
input = get_kbinput(footwin, VISIBLE);
#ifndef NANO_TINY
if (input == KEY_WINCH)
return KEY_WINCH;
#endif
#ifdef ENABLE_MOUSE
/* If we got a mouse click and it was on a shortcut, read in the
* shortcut character. */
if (input == KEY_MOUSE) {
if (do_statusbar_mouse() == 1)
input = get_kbinput(footwin, BLIND);
else
return ERR;
}
#endif
/* Check for a shortcut in the current list. */
shortcut = get_shortcut(&input);
/* If not a command, discard anything that is not a normal character byte. /* If not a command, discard anything that is not a normal character byte.
* Apart from that, only accept input when not in restricted mode, or when * Apart from that, only accept input when not in restricted mode, or when
* not at the "Write File" prompt, or when there is no filename yet. */ * not at the "Write File" prompt, or when there is no filename yet. */
if (shortcut == NULL) { if (!function) {
if (input < 0x20 || input > 0xFF || meta_key) if (input < 0x20 || input > 0xFF || meta_key)
beep(); beep();
else if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE || else if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
@ -303,7 +275,7 @@ int do_statusbar_input(bool *finished)
/* If we got a shortcut, or if there aren't any other keystrokes waiting, /* If we got a shortcut, or if there aren't any other keystrokes waiting,
* it's time to insert all characters in the input buffer (if not empty) * it's time to insert all characters in the input buffer (if not empty)
* into the answer, and then clear the input buffer. */ * into the answer, and then clear the input buffer. */
if ((shortcut || waiting_keycodes() == 0) && puddle != NULL) { if ((function || waiting_keycodes() == 0) && puddle != NULL) {
puddle[depth] = '\0'; puddle[depth] = '\0';
inject_into_answer(puddle, depth); inject_into_answer(puddle, depth);
@ -312,70 +284,54 @@ int do_statusbar_input(bool *finished)
puddle = NULL; puddle = NULL;
depth = 0; depth = 0;
} }
}
if (shortcut) { /* Handle any editing shortcut, and return TRUE when handled. */
if (shortcut->func == do_tab || shortcut->func == do_enter) bool handle_editing(functionptrtype function)
; {
#ifdef ENABLE_HISTORIES if (function == do_left)
else if (shortcut->func == get_older_item ||
shortcut->func == get_newer_item)
;
#endif
else if (shortcut->func == do_left)
do_statusbar_left(); do_statusbar_left();
else if (shortcut->func == do_right) else if (function == do_right)
do_statusbar_right(); do_statusbar_right();
#ifndef NANO_TINY #ifndef NANO_TINY
else if (shortcut->func == to_prev_word) else if (function == to_prev_word)
do_statusbar_prev_word(); do_statusbar_prev_word();
else if (shortcut->func == to_next_word) else if (function == to_next_word)
do_statusbar_next_word(); do_statusbar_next_word();
#endif #endif
else if (shortcut->func == do_home) else if (function == do_home)
do_statusbar_home(); do_statusbar_home();
else if (shortcut->func == do_end) else if (function == do_end)
do_statusbar_end(); do_statusbar_end();
/* When in restricted mode at the "Write File" prompt and the /* When in restricted mode at the "Write File" prompt and the
* filename isn't blank, disallow any input and deletion. */ * filename isn't blank, disallow any input and deletion. */
else if (ISSET(RESTRICTED) && currmenu == MWRITEFILE && else if (ISSET(RESTRICTED) && currmenu == MWRITEFILE &&
openfile->filename[0] != '\0' && openfile->filename[0] != '\0' &&
(shortcut->func == do_verbatim_input || (function == do_verbatim_input ||
shortcut->func == do_delete || function == do_delete || function == do_backspace ||
shortcut->func == do_backspace || function == cut_text || function == paste_text))
shortcut->func == cut_text ||
shortcut->func == paste_text))
; ;
#ifdef ENABLE_NANORC else if (function == do_verbatim_input)
else if (shortcut->func == (functionptrtype)implant)
implant(shortcut->expansion);
#endif
else if (shortcut->func == do_verbatim_input)
do_statusbar_verbatim_input(); do_statusbar_verbatim_input();
else if (shortcut->func == do_delete) else if (function == do_delete)
do_statusbar_delete(); do_statusbar_delete();
else if (shortcut->func == do_backspace) else if (function == do_backspace)
do_statusbar_backspace(); do_statusbar_backspace();
else if (shortcut->func == cut_text) else if (function == cut_text)
lop_the_answer(); lop_the_answer();
#ifndef NANO_TINY #ifndef NANO_TINY
else if (shortcut->func == copy_text) else if (function == copy_text)
copy_the_answer(); copy_the_answer();
else if (shortcut->func == paste_text) { else if (function == paste_text) {
if (cutbuffer != NULL) if (cutbuffer != NULL)
paste_into_answer(); paste_into_answer();
} }
#endif #endif
else { else
/* Handle any other shortcut in the current menu, setting finished return FALSE;
* to TRUE to indicate that we're done after running or trying to
* run its associated function. */
if (!ISSET(VIEW_MODE) || okay_for_view(shortcut))
shortcut->func();
*finished = TRUE;
}
}
return input; /* Don't handle any handled function again. */
return TRUE;
} }
/* Return the column number of the first character of the answer that is /* Return the column number of the first character of the answer that is
@ -460,9 +416,6 @@ void add_or_remove_pipe_symbol_from_answer(void)
functionptrtype acquire_an_answer(int *actual, bool *listed, functionptrtype acquire_an_answer(int *actual, bool *listed,
linestruct **history_list, void (*refresh_func)(void)) linestruct **history_list, void (*refresh_func)(void))
{ {
int kbinput = ERR;
bool finished;
functionptrtype func;
#ifdef ENABLE_HISTORIES #ifdef ENABLE_HISTORIES
char *stored_string = NULL; char *stored_string = NULL;
/* Whatever the answer was before the user foraged into history. */ /* Whatever the answer was before the user foraged into history. */
@ -472,7 +425,10 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
size_t fragment_length = 0; size_t fragment_length = 0;
/* The length of the fragment that the user tries to tab complete. */ /* The length of the fragment that the user tries to tab complete. */
#endif #endif
#endif /* ENABLE_HISTORIES */ #endif
const keystruct *shortcut;
functionptrtype function;
int input;
if (typing_x > strlen(answer)) if (typing_x > strlen(answer))
typing_x = strlen(answer); typing_x = strlen(answer);
@ -480,11 +436,12 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
while (TRUE) { while (TRUE) {
draw_the_promptbar(); draw_the_promptbar();
kbinput = do_statusbar_input(&finished); /* Read in one keystroke. */
input = get_kbinput(footwin, VISIBLE);
#ifndef NANO_TINY #ifndef NANO_TINY
/* If the window size changed, go reformat the prompt string. */ /* If the window size changed, go reformat the prompt string. */
if (kbinput == KEY_WINCH) { if (input == KEY_WINCH) {
refresh_func(); refresh_func();
*actual = KEY_WINCH; *actual = KEY_WINCH;
#ifdef ENABLE_HISTORIES #ifdef ENABLE_HISTORIES
@ -492,15 +449,27 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
#endif #endif
return NULL; return NULL;
} }
#endif /* !NANO_TINY */ #endif
#ifdef ENABLE_MOUSE
/* For a click on a shortcut, read in the resulting keycode. */
if (input == KEY_MOUSE && do_statusbar_mouse() == 1)
input = get_kbinput(footwin, BLIND);
if (input == KEY_MOUSE)
continue;
#endif
func = func_from_key(&kbinput); /* Check for a shortcut in the current list. */
shortcut = get_shortcut(input);
function = (shortcut ? shortcut->func : NULL);
if (func == do_cancel || func == do_enter) /* When it's a normal character, add it to the answer. */
absorb_character(input, function);
if (function == do_cancel || function == do_enter)
break; break;
#ifdef ENABLE_TABCOMP #ifdef ENABLE_TABCOMP
if (func == do_tab) { if (function == do_tab) {
#ifdef ENABLE_HISTORIES #ifdef ENABLE_HISTORIES
if (history_list != NULL) { if (history_list != NULL) {
if (!previous_was_tab) if (!previous_was_tab)
@ -517,9 +486,9 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
if ((currmenu & (MINSERTFILE|MWRITEFILE|MGOTODIR)) && !ISSET(RESTRICTED)) if ((currmenu & (MINSERTFILE|MWRITEFILE|MGOTODIR)) && !ISSET(RESTRICTED))
answer = input_tab(answer, &typing_x, refresh_func, listed); answer = input_tab(answer, &typing_x, refresh_func, listed);
} else } else
#endif /* ENABLE_TABCOMP */ #endif
#ifdef ENABLE_HISTORIES #ifdef ENABLE_HISTORIES
if (func == get_older_item && history_list != NULL) { if (function == get_older_item && history_list != NULL) {
/* If this is the first step into history, start at the bottom. */ /* If this is the first step into history, start at the bottom. */
if (stored_string == NULL) if (stored_string == NULL)
reset_history_pointer_for(*history_list); reset_history_pointer_for(*history_list);
@ -534,7 +503,7 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
answer = mallocstrcpy(answer, (*history_list)->data); answer = mallocstrcpy(answer, (*history_list)->data);
typing_x = strlen(answer); typing_x = strlen(answer);
} }
} else if (func == get_newer_item && history_list != NULL) { } else if (function == get_newer_item && history_list != NULL) {
/* If there is a newer item, move to it and copy its string. */ /* If there is a newer item, move to it and copy its string. */
if ((*history_list)->next != NULL) { if ((*history_list)->next != NULL) {
*history_list = (*history_list)->next; *history_list = (*history_list)->next;
@ -549,29 +518,33 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
} }
} else } else
#endif /* ENABLE_HISTORIES */ #endif /* ENABLE_HISTORIES */
/* If we ran a function that should not exit from the prompt... */ if (function == do_help || function == full_refresh)
if (func == do_help || func == full_refresh) function();
finished = FALSE;
#ifndef NANO_TINY #ifndef NANO_TINY
else if (func == do_nothing) else if (function == do_toggle && shortcut->toggle == NO_HELP) {
finished = FALSE;
else if (func == do_toggle) {
TOGGLE(NO_HELP); TOGGLE(NO_HELP);
window_init(); window_init();
focusing = FALSE; focusing = FALSE;
refresh_func(); refresh_func();
bottombars(currmenu); bottombars(currmenu);
finished = FALSE; } else if (function == do_nothing)
} ;
#endif #endif
#ifdef ENABLE_NANORC
/* If we have a shortcut with an associated function, break out if else if (function == (functionptrtype)implant)
* we're finished after running or trying to run the function. */ implant(shortcut->expansion);
if (finished) #endif
else if (function && !handle_editing(function)) {
/* When it's a permissible shortcut, run it and done. */
if (!ISSET(VIEW_MODE) || !changes_something(function)) {
function();
break; break;
} else
beep();
}
#if defined(ENABLE_HISTORIES) && defined(ENABLE_TABCOMP) #if defined(ENABLE_HISTORIES) && defined(ENABLE_TABCOMP)
previous_was_tab = (func == do_tab); previous_was_tab = (function == do_tab);
#endif #endif
} }
@ -583,9 +556,9 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
} }
#endif #endif
*actual = kbinput; *actual = input;
return func; return function;
} }
/* Ask a question on the status bar. Return 0 when text was entered, /* Ask a question on the status bar. Return 0 when text was entered,
@ -595,10 +568,10 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
int do_prompt(int menu, const char *provided, linestruct **history_list, int do_prompt(int menu, const char *provided, linestruct **history_list,
void (*refresh_func)(void), const char *msg, ...) void (*refresh_func)(void), const char *msg, ...)
{ {
functionptrtype function = NULL;
bool listed = FALSE;
va_list ap; va_list ap;
int retval; int retval;
functionptrtype func = NULL;
bool listed = FALSE;
/* Save a possible current status-bar x position and prompt. */ /* Save a possible current status-bar x position and prompt. */
size_t was_typing_x = typing_x; size_t was_typing_x = typing_x;
char *saved_prompt = prompt; char *saved_prompt = prompt;
@ -620,7 +593,7 @@ int do_prompt(int menu, const char *provided, linestruct **history_list,
lastmessage = VACUUM; lastmessage = VACUUM;
func = acquire_an_answer(&retval, &listed, history_list, refresh_func); function = acquire_an_answer(&retval, &listed, history_list, refresh_func);
free(prompt); free(prompt);
prompt = saved_prompt; prompt = saved_prompt;
@ -631,14 +604,14 @@ int do_prompt(int menu, const char *provided, linestruct **history_list,
/* If we're done with this prompt, restore the x position to what /* If we're done with this prompt, restore the x position to what
* it was at a possible previous prompt. */ * it was at a possible previous prompt. */
if (func == do_cancel || func == do_enter) if (function == do_cancel || function == do_enter)
typing_x = was_typing_x; typing_x = was_typing_x;
/* If we left the prompt via Cancel or Enter, set the return value /* If we left the prompt via Cancel or Enter, set the return value
* properly. */ * properly. */
if (func == do_cancel) if (function == do_cancel)
retval = -1; retval = -1;
else if (func == do_enter) else if (function == do_enter)
retval = (*answer == '\0') ? -2 : 0; retval = (*answer == '\0') ? -2 : 0;
if (lastmessage == VACUUM) if (lastmessage == VACUUM)
@ -667,6 +640,8 @@ int ask_user(bool withall, const char *question)
const char *yesstr = _("Yy"); const char *yesstr = _("Yy");
const char *nostr = _("Nn"); const char *nostr = _("Nn");
const char *allstr = _("Aa"); const char *allstr = _("Aa");
const keystruct *shortcut;
functionptrtype function;
while (choice == UNDECIDED) { while (choice == UNDECIDED) {
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
@ -722,9 +697,11 @@ int ask_user(bool withall, const char *question)
if (kbinput == KEY_WINCH) if (kbinput == KEY_WINCH)
continue; continue;
/* Accept the first character of an external paste. */ /* Accept first character of an external paste and ignore the rest. */
if (bracketed_paste && kbinput == BRACKETED_PASTE_MARKER) if (bracketed_paste)
kbinput = get_kbinput(footwin, BLIND); kbinput = get_kbinput(footwin, BLIND);
while (bracketed_paste)
get_kbinput(footwin, BLIND);
#endif #endif
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
@ -756,8 +733,27 @@ int ask_user(bool withall, const char *question)
choice = NO; choice = NO;
else if (withall && strchr("Aa", kbinput) != NULL) else if (withall && strchr("Aa", kbinput) != NULL)
choice = ALL; choice = ALL;
else if (func_from_key(&kbinput) == do_cancel)
if (choice != UNDECIDED)
break;
shortcut = get_shortcut(kbinput);
function = (shortcut ? shortcut->func : NULL);
if (function == do_cancel)
choice = CANCEL; choice = CANCEL;
else if (function == full_refresh)
full_refresh();
#ifndef NANO_TINY
else if (function == do_toggle && shortcut->toggle == NO_HELP) {
TOGGLE(NO_HELP);
window_init();
titlebar(NULL);
focusing = FALSE;
edit_refresh();
focusing = TRUE;
}
#endif
/* Interpret ^N and ^Q as "No", to allow exiting in anger. */ /* Interpret ^N and ^Q as "No", to allow exiting in anger. */
else if (kbinput == '\x0E' || kbinput == '\x11') else if (kbinput == '\x0E' || kbinput == '\x11')
choice = NO; choice = NO;
@ -781,27 +777,9 @@ int ask_user(bool withall, const char *question)
choice = UNDECIDED; choice = UNDECIDED;
} }
} }
#endif
else if (func_from_key(&kbinput) == full_refresh)
full_refresh();
#ifndef NANO_TINY
else if (func_from_key(&kbinput) == do_toggle) {
TOGGLE(NO_HELP);
window_init();
titlebar(NULL);
focusing = FALSE;
edit_refresh();
focusing = TRUE;
}
#endif #endif
else else
beep(); beep();
#ifndef NANO_TINY
/* Ignore the rest of an external paste. */
while (bracketed_paste)
kbinput = get_kbinput(footwin, BLIND);
#endif
} }
return choice; return choice;

View File

@ -181,6 +181,9 @@ extern char *startup_problem;
#endif #endif
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
extern char *custom_nanorc; extern char *custom_nanorc;
extern char *commandname;
extern keystruct *planted_shortcut;
#endif #endif
extern bool spotlighted; extern bool spotlighted;
@ -316,12 +319,12 @@ char *input_tab(char *buf, size_t *place, void (*refresh_func)(void), bool *list
#endif #endif
/* Some functions in global.c. */ /* Some functions in global.c. */
const keystruct *first_sc_for(int menu, void (*func)(void)); const keystruct *first_sc_for(int menu, void (*function)(void));
size_t shown_entries_for(int menu); size_t shown_entries_for(int menu);
const keystruct *get_shortcut(int *keycode); const keystruct *get_shortcut(const int keycode);
functionptrtype func_from_key(int *keycode); functionptrtype func_from_key(const int keycode);
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP) #if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
functionptrtype interpret(int *keycode); functionptrtype interpret(const int keycode);
#endif #endif
int keycode_from_string(const char *keystring); int keycode_from_string(const char *keystring);
void shortcut_init(void); void shortcut_init(void);
@ -425,7 +428,7 @@ void terminal_init(void);
void confirm_margin(void); void confirm_margin(void);
#endif #endif
void unbound_key(int code); void unbound_key(int code);
bool okay_for_view(const keystruct *shortcut); bool changes_something(const void *f);
void inject(char *burst, size_t count); void inject(char *burst, size_t count);
/* Most functions in prompt.c. */ /* Most functions in prompt.c. */
@ -442,6 +445,7 @@ void display_rcfile_errors(void);
void jot_error(const char *msg, ...); void jot_error(const char *msg, ...);
#endif #endif
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
keystruct *strtosc(const char *input);
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
void parse_one_include(char *file, syntaxtype *syntax); void parse_one_include(char *file, syntaxtype *syntax);
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage); void grab_and_store(const char *kind, char *ptr, regexlisttype **storage);
@ -528,7 +532,9 @@ void do_formatter(void);
void count_lines_words_and_characters(void); void count_lines_words_and_characters(void);
#endif #endif
void do_verbatim_input(void); void do_verbatim_input(void);
#ifdef ENABLE_WORDCOMPLETION
void complete_a_word(void); void complete_a_word(void);
#endif
/* All functions in utils.c. */ /* All functions in utils.c. */
void get_homedir(void); void get_homedir(void);

View File

@ -897,7 +897,7 @@ bool is_good_file(char *file)
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
/* Partially parse the syntaxes in the given file, or (when syntax /* Partially parse the syntaxes in the given file, or (when syntax
* is not NULL) fully parse one specific syntax from the file . */ * is not NULL) fully parse one specific syntax from the file. */
void parse_one_include(char *file, syntaxtype *syntax) void parse_one_include(char *file, syntaxtype *syntax)
{ {
char *was_nanorc = nanorc; char *was_nanorc = nanorc;

View File

@ -91,7 +91,7 @@ void search_init(bool replacing, bool retain_answer)
thedefault = copy_of(""); thedefault = copy_of("");
while (TRUE) { while (TRUE) {
functionptrtype func; functionptrtype function;
/* Ask the user what to search for (or replace). */ /* Ask the user what to search for (or replace). */
int response = do_prompt( int response = do_prompt(
inhelp ? MFINDINHELP : (replacing ? MREPLACE : MWHEREIS), inhelp ? MFINDINHELP : (replacing ? MREPLACE : MWHEREIS),
@ -138,23 +138,23 @@ void search_init(bool replacing, bool retain_answer)
retain_answer = TRUE; retain_answer = TRUE;
func = func_from_key(&response); function = func_from_key(response);
/* If we're here, one of the five toggles was pressed, or /* If we're here, one of the five toggles was pressed, or
* a shortcut was executed. */ * a shortcut was executed. */
if (func == case_sens_void) if (function == case_sens_void)
TOGGLE(CASE_SENSITIVE); TOGGLE(CASE_SENSITIVE);
else if (func == backwards_void) else if (function == backwards_void)
TOGGLE(BACKWARDS_SEARCH); TOGGLE(BACKWARDS_SEARCH);
else if (func == regexp_void) else if (function == regexp_void)
TOGGLE(USE_REGEXP); TOGGLE(USE_REGEXP);
else if (func == flip_replace) { else if (function == flip_replace) {
if (ISSET(VIEW_MODE)) { if (ISSET(VIEW_MODE)) {
print_view_warning(); print_view_warning();
napms(600); napms(600);
} else } else
replacing = !replacing; replacing = !replacing;
} else if (func == flip_goto) { } else if (function == flip_goto) {
goto_line_and_column(openfile->current->lineno, goto_line_and_column(openfile->current->lineno,
openfile->placewewant + 1, TRUE, TRUE); openfile->placewewant + 1, TRUE, TRUE);
break; break;
@ -284,7 +284,7 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
} else } else
meta_key = FALSE; meta_key = FALSE;
if (func_from_key(&input) == do_cancel) { if (func_from_key(input) == do_cancel) {
#ifndef NANO_TINY #ifndef NANO_TINY
if (the_window_resized) if (the_window_resized)
regenerate_screen(); regenerate_screen();
@ -448,8 +448,8 @@ void go_looking(void)
* text in the passed string only when create is TRUE. */ * text in the passed string only when create is TRUE. */
int replace_regexp(char *string, bool create) int replace_regexp(char *string, bool create)
{ {
const char *c = answer;
size_t replacement_size = 0; size_t replacement_size = 0;
const char *c = answer;
/* Iterate through the replacement text to handle subexpression /* Iterate through the replacement text to handle subexpression
* replacement using \1, \2, \3, etc. */ * replacement using \1, \2, \3, etc. */
@ -527,11 +527,11 @@ char *replace_line(const char *needle)
ssize_t do_replace_loop(const char *needle, bool whole_word_only, ssize_t do_replace_loop(const char *needle, bool whole_word_only,
const linestruct *real_current, size_t *real_current_x) const linestruct *real_current, size_t *real_current_x)
{ {
bool skipone = ISSET(BACKWARDS_SEARCH);
bool replaceall = FALSE;
int modus = REPLACING;
ssize_t numreplaced = -1; ssize_t numreplaced = -1;
size_t match_len; size_t match_len;
bool replaceall = FALSE;
bool skipone = ISSET(BACKWARDS_SEARCH);
int modus = REPLACING;
#ifndef NANO_TINY #ifndef NANO_TINY
linestruct *was_mark = openfile->mark; linestruct *was_mark = openfile->mark;
linestruct *top, *bot; linestruct *top, *bot;
@ -739,18 +739,15 @@ void ask_for_and_do_replacements(void)
} }
/* Go to the specified line and x position. */ /* Go to the specified line and x position. */
void goto_line_posx(ssize_t line, size_t pos_x) void goto_line_posx(ssize_t linenumber, size_t pos_x)
{ {
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
if (line > openfile->edittop->lineno + editwinrows || if (linenumber > openfile->edittop->lineno + editwinrows ||
(ISSET(SOFTWRAP) && line > openfile->current->lineno)) (ISSET(SOFTWRAP) && linenumber > openfile->current->lineno))
recook |= perturbed; recook |= perturbed;
#endif #endif
for (openfile->current = openfile->filetop; line > 1 && openfile->current = line_from_number(linenumber);
openfile->current != openfile->filebot; line--)
openfile->current = openfile->current->next;
openfile->current_x = pos_x; openfile->current_x = pos_x;
openfile->placewewant = xplustabs(); openfile->placewewant = xplustabs();
UNFOLD_SEGMENT(openfile->current); UNFOLD_SEGMENT(openfile->current);
@ -776,7 +773,7 @@ void goto_line_and_column(ssize_t line, ssize_t column, bool retain_answer,
return; return;
} }
if (func_from_key(&response) == flip_goto) { if (func_from_key(response) == flip_goto) {
UNSET(BACKWARDS_SEARCH); UNSET(BACKWARDS_SEARCH);
/* Switch to searching but retain what the user typed so far. */ /* Switch to searching but retain what the user typed so far. */
search_init(FALSE, TRUE); search_init(FALSE, TRUE);

View File

@ -119,8 +119,8 @@ void indent_a_line(linestruct *line, char *indentation)
* depending on whether --tabstospaces is in effect. */ * depending on whether --tabstospaces is in effect. */
void do_indent(void) void do_indent(void)
{ {
char *indentation;
linestruct *top, *bot, *line; linestruct *top, *bot, *line;
char *indentation;
/* Use either all the marked lines or just the current line. */ /* Use either all the marked lines or just the current line. */
get_range(&top, &bot); get_range(&top, &bot);
@ -509,10 +509,11 @@ void redo_cut(undostruct *u)
void do_undo(void) void do_undo(void)
{ {
undostruct *u = openfile->current_undo; undostruct *u = openfile->current_undo;
linestruct *line = NULL, *intruder; linestruct *oldcutbuffer, *intruder;
linestruct *oldcutbuffer; linestruct *line = NULL;
char *data, *undidmsg = NULL;
size_t original_x, regain_from_x; size_t original_x, regain_from_x;
char *undidmsg = NULL;
char *data;
if (u == NULL) { if (u == NULL) {
statusline(AHEM, _("Nothing to undo")); statusline(AHEM, _("Nothing to undo"));
@ -546,6 +547,7 @@ void do_undo(void)
line->has_anchor |= line->next->has_anchor; line->has_anchor |= line->next->has_anchor;
unlink_node(line->next); unlink_node(line->next);
renumber_from(line); renumber_from(line);
openfile->current = line;
goto_line_posx(u->head_lineno, original_x); goto_line_posx(u->head_lineno, original_x);
break; break;
case BACK: case BACK:
@ -691,10 +693,12 @@ void do_undo(void)
/* Redo the last thing(s) we undid. */ /* Redo the last thing(s) we undid. */
void do_redo(void) void do_redo(void)
{ {
linestruct *line = NULL, *intruder;
char *data, *redidmsg = NULL;
bool suppress_modification = FALSE;
undostruct *u = openfile->undotop; undostruct *u = openfile->undotop;
bool suppress_modification = FALSE;
linestruct *line = NULL;
linestruct *intruder;
char *redidmsg = NULL;
char *data;
if (u == NULL || u == openfile->current_undo) { if (u == NULL || u == openfile->current_undo) {
statusline(AHEM, _("Nothing to redo")); statusline(AHEM, _("Nothing to redo"));
@ -750,6 +754,7 @@ void do_redo(void)
strcat(line->data, u->strdata); strcat(line->data, u->strdata);
unlink_node(line->next); unlink_node(line->next);
renumber_from(line); renumber_from(line);
openfile->current = line;
goto_line_posx(u->tail_lineno, u->tail_x); goto_line_posx(u->tail_lineno, u->tail_x);
break; break;
case REPLACE: case REPLACE:
@ -2132,8 +2137,11 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
timestamp_nsec = (long)fileinfo.st_mtim.tv_nsec; timestamp_nsec = (long)fileinfo.st_mtim.tv_nsec;
} }
/* Exit from curses mode to give the program control of the terminal. */ /* The spell checker needs the screen, so exit from curses mode. */
if (spelling)
endwin(); endwin();
else
statusbar(_("Invoking formatter..."));
construct_argument_list(&arguments, theprogram, tempfile_name); construct_argument_list(&arguments, theprogram, tempfile_name);
@ -2153,9 +2161,13 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
errornumber = errno; errornumber = errno;
/* Restore the terminal state and reenter curses mode. */ /* After spell checking, restore terminal state and reenter curses mode;
* after formatting, make sure that any formatter output is wiped. */
if (spelling) {
terminal_init(); terminal_init();
doupdate(); doupdate();
} else
full_refresh();
if (thepid < 0) { if (thepid < 0) {
statusline(ALERT, _("Could not fork: %s"), strerror(errornumber)); statusline(ALERT, _("Could not fork: %s"), strerror(errornumber));
@ -2766,7 +2778,7 @@ void do_linter(void)
while (TRUE) { while (TRUE) {
int kbinput; int kbinput;
functionptrtype func; functionptrtype function;
struct stat lintfileinfo; struct stat lintfileinfo;
if (stat(curlint->filename, &lintfileinfo) != -1 && if (stat(curlint->filename, &lintfileinfo) != -1 &&
@ -2862,16 +2874,16 @@ void do_linter(void)
if (kbinput == KEY_WINCH) if (kbinput == KEY_WINCH)
continue; continue;
#endif #endif
func = func_from_key(&kbinput); function = func_from_key(kbinput);
tmplint = curlint; tmplint = curlint;
if (func == do_cancel || func == do_enter) { if (function == do_cancel || function == do_enter) {
wipe_statusbar(); wipe_statusbar();
break; break;
} else if (func == do_help) { } else if (function == do_help) {
tmplint = NULL; tmplint = NULL;
do_help(); do_help();
} else if (func == do_page_up || func == to_prev_block) { } else if (function == do_page_up || function == to_prev_block) {
if (curlint->prev != NULL) if (curlint->prev != NULL)
curlint = curlint->prev; curlint = curlint->prev;
else if (last_wait != time(NULL)) { else if (last_wait != time(NULL)) {
@ -2881,7 +2893,7 @@ void do_linter(void)
last_wait = time(NULL); last_wait = time(NULL);
statusline(NOTICE, curlint->msg); statusline(NOTICE, curlint->msg);
} }
} else if (func == do_page_down || func == to_next_block) { } else if (function == do_page_down || function == to_next_block) {
if (curlint->next != NULL) if (curlint->next != NULL)
curlint = curlint->next; curlint = curlint->next;
else if (last_wait != time(NULL)) { else if (last_wait != time(NULL)) {
@ -3067,12 +3079,14 @@ char *copy_completion(char *text)
return word; return word;
} }
/* Look at the fragment the user has typed, then search the current buffer for /* Look at the fragment the user has typed, then search all buffers for
* the first word that starts with this fragment, and tentatively complete the * the first word that starts with this fragment, and tentatively complete the
* fragment. If the user types 'Complete' again, search and paste the next * fragment. If the user types 'Complete' again, search and paste the next
* possible completion. */ * possible completion. */
void complete_a_word(void) void complete_a_word(void)
{ {
static openfilestruct *scouring = NULL;
/* The buffer that is being searched for possible completions. */
char *shard, *completion = NULL; char *shard, *completion = NULL;
size_t start_of_shard, shard_length = 0; size_t start_of_shard, shard_length = 0;
size_t i = 0, j = 0; size_t i = 0, j = 0;
@ -3095,6 +3109,7 @@ void complete_a_word(void)
openfile->last_action = OTHER; openfile->last_action = OTHER;
/* Initialize the starting point for searching. */ /* Initialize the starting point for searching. */
scouring = openfile;
pletion_line = openfile->filetop; pletion_line = openfile->filetop;
pletion_x = 0; pletion_x = 0;
@ -3206,9 +3221,17 @@ void complete_a_word(void)
pletion_line = pletion_line->next; pletion_line = pletion_line->next;
pletion_x = 0; pletion_x = 0;
#ifdef ENABLE_MULTIBUFFER
/* When at end of buffer and there is another, search that one. */
if (pletion_line == NULL && scouring->next != openfile) {
scouring = scouring->next;
pletion_line = scouring->filetop;
}
#endif
} }
/* The search has reached the end of the file. */ /* The search has gone through all buffers. */
if (list_of_completions != NULL) { if (list_of_completions != NULL) {
edit_refresh(); edit_refresh();
statusline(AHEM, _("No further matches")); statusline(AHEM, _("No further matches"));

View File

@ -130,9 +130,9 @@ bool parse_num(const char *string, ssize_t *result)
* *line and *column. Return FALSE on error, and TRUE otherwise. */ * *line and *column. Return FALSE on error, and TRUE otherwise. */
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column) bool parse_line_column(const char *str, ssize_t *line, ssize_t *column)
{ {
bool retval;
char *firstpart;
const char *comma; const char *comma;
char *firstpart;
bool retval;
while (*str == ' ') while (*str == ' ')
str++; str++;

View File

@ -64,6 +64,10 @@ static bool has_more = FALSE;
/* Whether the current line has more text after the displayed part. */ /* Whether the current line has more text after the displayed part. */
static bool is_shorter = TRUE; static bool is_shorter = TRUE;
/* Whether a row's text is narrower than the screen's width. */ /* Whether a row's text is narrower than the screen's width. */
#ifdef ENABLE_NANORC
static const char *plants_pointer = NULL;
/* Points into the expansion string for the current implantation. */
#endif
#ifndef NANO_TINY #ifndef NANO_TINY
static size_t sequel_column = 0; static size_t sequel_column = 0;
/* The starting column of the next chunk when softwrapping. */ /* The starting column of the next chunk when softwrapping. */
@ -375,14 +379,60 @@ void put_back(int keycode)
} }
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
/* Insert the given string into the keyboard buffer. */ /* Set up the given expansion string to be ingested by the keyboard routines. */
void implant(const char *string) void implant(const char *string)
{ {
for (int i = strlen(string); i > 0; i--) plants_pointer = string;
put_back((unsigned char)string[i - 1]); put_back(MORE_PLANTS);
mute_modifiers = TRUE; mute_modifiers = TRUE;
} }
/* Continue processing an expansion string. Returns either an error code,
* a plain keycode, or a placeholder for a command shortcut. */
int get_code_from_plantation(void)
{
if (*plants_pointer == '{') {
char *closing = strchr(plants_pointer + 1, '}');
if (!closing)
return MISSING_BRACE;
if (plants_pointer[1] == '{' && plants_pointer[2] == '}') {
plants_pointer += 3;
if (*plants_pointer != '\0')
put_back(MORE_PLANTS);
return '{';
}
free(commandname);
free(planted_shortcut);
commandname = measured_copy(plants_pointer + 1, closing - plants_pointer - 1);
planted_shortcut = strtosc(commandname);
if (planted_shortcut) {
plants_pointer = closing + 1;
if (*plants_pointer != '\0')
put_back(MORE_PLANTS);
return PLANTED_COMMAND;
} else
return NO_SUCH_FUNCTION;
} else {
char *opening = strchr(plants_pointer, '{');
int length = (opening ? opening - plants_pointer : strlen(plants_pointer));
if (opening)
put_back(MORE_PLANTS);
for (int index = length - 1; index >= 0; index--)
put_back((unsigned char)plants_pointer[index]);
plants_pointer += length;
return ERR;
}
}
#endif #endif
/* Return one code from the keystroke buffer. If the buffer is empty /* Return one code from the keystroke buffer. If the buffer is empty
@ -396,6 +446,12 @@ int get_input(WINDOW *frame)
if (waiting_codes > 0) { if (waiting_codes > 0) {
waiting_codes--; waiting_codes--;
#ifdef ENABLE_NANORC
if (*nextcodes == MORE_PLANTS) {
nextcodes++;
return get_code_from_plantation();
} else
#endif
return *(nextcodes++); return *(nextcodes++);
} else } else
return ERR; return ERR;
@ -989,7 +1045,8 @@ int parse_kbinput(WINDOW *frame)
} else if (++escapes > 2) } else if (++escapes > 2)
escapes = (last_escape_was_alone ? 0 : 1); escapes = (last_escape_was_alone ? 0 : 1);
return ERR; return ERR;
} } else if (keycode == ERR)
return ERR;
if (escapes == 0) { if (escapes == 0) {
/* Most key codes in byte range cannot be special keys. */ /* Most key codes in byte range cannot be special keys. */
@ -1669,7 +1726,7 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
} }
#if NCURSES_MOUSE_VERSION >= 2 #if NCURSES_MOUSE_VERSION >= 2
/* Handle "presses" of the fourth and fifth mouse buttons /* Handle "presses" of the fourth and fifth mouse buttons
* (upward and downward rolls of the mouse wheel) . */ * (upward and downward rolls of the mouse wheel). */
else if (event.bstate & (BUTTON4_PRESSED | BUTTON5_PRESSED)) { else if (event.bstate & (BUTTON4_PRESSED | BUTTON5_PRESSED)) {
if (in_footer) if (in_footer)
/* Shift the coordinates to be relative to the bottom window. */ /* Shift the coordinates to be relative to the bottom window. */
@ -2316,7 +2373,7 @@ void statusline(message_type importance, const char *msg, ...)
return; return;
} }
#if !defined(NANO_TINY) && defined(ENABLE_MULTIBUFFER) #if defined(ENABLE_MULTIBUFFER) && !defined(NANO_TINY)
if (!we_are_running && importance == ALERT && openfile && !openfile->fmt && if (!we_are_running && importance == ALERT && openfile && !openfile->fmt &&
!openfile->errormessage && openfile->next != openfile) !openfile->errormessage && openfile->next != openfile)
openfile->errormessage = copy_of(compound); openfile->errormessage = copy_of(compound);
@ -2574,7 +2631,7 @@ void draw_linenumber(int row, const linestruct* line, size_t from_col){
#endif #endif
wprintw(midwin, "+"); wprintw(midwin, "+");
else else
#endif /* NANO_TINY */ #endif
wprintw(midwin, " "); wprintw(midwin, " ");
} }
@ -3022,6 +3079,7 @@ bool line_needs_update(const size_t old_column, const size_t new_column)
int go_back_chunks(int nrows, linestruct **line, size_t *leftedge) int go_back_chunks(int nrows, linestruct **line, size_t *leftedge)
{ {
int i; int i;
#ifndef NANO_TINY #ifndef NANO_TINY
if (ISSET(SOFTWRAP)) { if (ISSET(SOFTWRAP)) {
/* Recede through the requested number of chunks. */ /* Recede through the requested number of chunks. */

View File

@ -25,6 +25,16 @@ color brightgreen "^[[:blank:]]*(syntax[[:blank:]]+[^[:space:]]+|(formatter|lint
# Strings # Strings
color brightmagenta "[[:blank:]](start=)?".+"" color brightmagenta "[[:blank:]](start=)?".+""
# Function names in string binds
color crimson "\{(help|cancel|exit|savefile|writeout|discardbuffer|insert|where(is|was)|find(previous|next|bracket)|replace)\}"
color crimson "\{(cut|copy|paste|zap|chopword(left|right)|cutrestoffile|execute|mark|speller|linter|formatter|(full)?justify)\}"
color crimson "\{(location|gotoline|(begin|end)para|comment|complete|(un)?indent|wordcount|(record|run)macro|anchor|undo|redo)\}"
color crimson "\{(left|right|up|down|home|end|(scroll|page)(up|down)|center|(prev|next)(word|block|anchor|buf))\}"
color crimson "\{(tab|enter|delete|backspace|verbatim|refresh|suspend|casesens|regexp|backwards|older|newer|(dos|mac)format)\}"
color crimson "\{(append|prepend|backup|flip(goto|replace|execute|pipe|convert|newbuffer)|browser|gotodir|(first|last)(file|line))\}"
color crimson "\{(nohelp|constantshow|softwrap|linenumbers|whitespacedisplay|nosyntax|zero)\}"
color crimson "\{(smarthome|autoindent|cutfromcursor|breaklonglines|tabstospaces|mouse|\{)\}"
# Commands # Commands
color green "^[[:blank:]]*((un)?(bind|set)|include|syntax|header|magic|comment|formatter|linter|tabgives|extendsyntax)\>" color green "^[[:blank:]]*((un)?(bind|set)|include|syntax|header|magic|comment|formatter|linter|tabgives|extendsyntax)\>"
color magenta "^[[:blank:]]*i?color\>|[[:blank:]](start=|end=)" color magenta "^[[:blank:]]*i?color\>|[[:blank:]](start=|end=)"

View File

@ -5,8 +5,22 @@ header "^#!.*perl"
magic "Perl script" magic "Perl script"
comment "#" comment "#"
color red "\<(accept|alarm|atan2|bin(d|mode)|c(aller|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork))\>" "\<(get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join)\>" "\<(keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek(dir)?)\>" "\<(se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr(y)?|truncate|umask)\>" "\<(un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\>" # Functions.
color magenta "\<(continue|else|elsif|do|for|foreach|if|unless|until|while|eq|ne|lt|gt|le|ge|cmp|x|my|sub|use|package|can|isa)\>" color red "\<(abs|accept|alarm|atan2|bin(d|mode)|bless|caller|ch(dir|mod|op|omp|own|r|root)|close(dir)?|connect|cos|crypt)\>"
color red "\<(dbm(close|open)|defined|delete|dump|each|eof|eval(bytes)?|exec|exists|exp|fc|fcntl|fileno|flock|fork|format|formline)\>"
color red "\<(get(c|login|peername|pgrp|ppid|priority|(gr|pw)nam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport))\>"
color red "\<(([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|glob|gmtime|grep|hex|import|index|int|ioctl|join)\>"
color red "\<(keys|kill|lc|lcfirst|length|link|listen|local(time)?|lock|log|lstat|map|mkdir|msg(ctl|get|snd|rcv)|oct)\>"
color red "\<(open(dir)?|ord|pack|pipe|pop|pos|printf?|prototype|push|q|qq|qr|qx|qw|quotemeta|rand|read(dir|line|link|pipe)?)\>"
color red "\<(recv|redo|ref|rename|require|reset|reverse|rewinddir|rindex|rmdir|say|scalar|seek(dir)?|select|sem(ctl|get|op))\>"
color red "\<(send|set(pgrp|priority|sockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|splice|split)\>"
color red "\<(sprintf|sqrt|srand|state?|study|substr|symlink|sys(call|open|read|seek|tem|write)|tell(dir)?|tied?|times?|try?)\>"
color red "\<(truncate|uc|ucfirst|umask|un(def|link|pack|shift|tie)|utime|values|vec|wait(pid)?|wantarray|warn|write)\>"
# Control flow, logical operators, declarations.
color magenta "\<(continue|die|do|else|elsif|exit|for(each)?|fork|goto|if|last|next|return|unless|until|while)\>"
color magenta "\<(and|cmp|eq|ge|gt|isa|le|lt|ne|not|or|x|xor)\>"
color magenta "\<(my|no|our|package|sub|use)\>"
# Variable names. # Variable names.
color cyan "[$%&@]([A-Za-z_][0-9A-Za-z_]*|\^[][A-Z?\^_]|[0-9]+)\>" color cyan "[$%&@]([A-Za-z_][0-9A-Za-z_]*|\^[][A-Z?\^_]|[0-9]+)\>"
@ -14,8 +28,10 @@ color cyan "[$%&@]\{(\^?[A-Za-z_][0-9A-Za-z_]*|\^[][?\^][0-9]+)\}"
color cyan "[$%&@]([][!"#'()*+,.:;<=>?`|~-]|\{[][!-/:-@\`|~]\})|\$[$%&@]" color cyan "[$%&@]([][!"#'()*+,.:;<=>?`|~-]|\{[][!-/:-@\`|~]\})|\$[$%&@]"
color cyan "(^|[[:blank:]])[$%@][/\]" color cyan "(^|[[:blank:]])[$%@][/\]"
# Strings.
color yellow "".*"|qq\|.*\|" color yellow "".*"|qq\|.*\|"
color white "[sm]/.*/"
color white "[smy]/.*/"
color white start="(^use| = new)" end=";" color white start="(^use| = new)" end=";"
# Comments. # Comments.

View File

@ -5,6 +5,7 @@ header "^#!.*python"
magic "Python script" magic "Python script"
comment "#" comment "#"
# Alternative linter: pylint --exit-zero
linter pyflakes linter pyflakes
# Function definitions. # Function definitions.