Compare commits

..

40 Commits
v4.6 ... v4.7

Author SHA1 Message Date
Benno Schulenberg
075b7e75bc po: update translations and regenerate POT file and PO files 2019-12-23 11:37:33 +01:00
Benno Schulenberg
c00431134f bump version numbers and add a news item for the 4.7 release 2019-12-23 11:15:53 +01:00
Benno Schulenberg
51065ff24b gnulib: update to its current upstream state 2019-12-22 13:25:32 +01:00
Benno Schulenberg
4314feae11 build: fix compilation for --enable-tiny --enable-wrapping 2019-12-22 12:56:18 +01:00
Benno Schulenberg
410280b089 build: fix compilation when configured with --disable-justify 2019-12-22 11:32:49 +01:00
Benno Schulenberg
178dd9181f tweaks: slightly streamline the search for a possible wrapping point
That is, elide an 'if' for the it-is-a-blank case.
2019-12-19 19:22:02 +01:00
Benno Schulenberg
d30ca576b7 tweaks: optimize the trimming of trailing whitespace
When justifying a paragraph, always first squeeze() is called on
the text (which at that moment consists of a single long line),
which means that (in its wrappable part) this line contains only
single spaces as word separators (and maybe a double space after
a period).  So there is no need to call the general is_blank()
function -- checking for a space is enough.
2019-12-19 12:16:15 +01:00
Benno Schulenberg
ed520c89bc tweaks: improve two comments and the ordering of some operands 2019-12-19 12:15:47 +01:00
Benno Schulenberg
cb44a2bd2c tweaks: reshuffle and rename a few things, to elide duplication 2019-12-19 10:52:06 +01:00
Benno Schulenberg
a0055f3640 wrapping: never break in the quoting part nor in the indentation part
Rationale: nano should not wrap inside the quoting part of a line
because it would change the quoting level, which would misrepresent
things, nor should it wrap inside the indentation part because when
the user tries to indent something beyond the target wrapping width,
she/he does not intend to create a line containing only whitespace,
but effectively wants to push the text beyond the wrapping width.

This copies the behavior of the rewrap_paragraph() routine that is
used during justification, so that automatic hard-wrapping ends up
with the same result as justifying.

Also, always do automatic hard-wrapping when --breaklonglines is in
effect, also when --autoindent is active.

This fixes https://savannah.gnu.org/bugs/?57425.

The bug was old -- it existed since at least version 2.0.6.

This furthermore avoids https://savannah.gnu.org/bugs/?57422.
Reported-by: Sébastien Desreux <seb@h-k.fr>

That bug existed since version 4.4, commit 8fce33af.
2019-12-18 11:22:30 +01:00
Benno Schulenberg
b00c1d6110 justify: treat consecutive indentations that look the same as the same
That is: allow tabs and spaces to be mixed when comparing indentation.
When the mix of tabs and spaces pushes the text of a line to the same
column as on a consecutive line, then those two lines are considered
to have the same indentation and thus belong to the same paragraph.

This reverts the previous commit (594ef222), and improves upon how
nano has behaved since version 2.9.8.

This fixes https://savannah.gnu.org/bugs/?57404 differently.
2019-12-17 16:56:28 +01:00
Benno Schulenberg
594ef2225f justify: distinguish between tabs and spaces when comparing indentation
That is: two consecutive lines are considered to belong to separate
paragraphs when the smallest indentation of those two lines is not
character-by-character identical with the corresponding piece of
indentation of the other line.

In other words: if one line is indented with spaces, and a consecutive
line is indented by the same distance but with tabs, they are taken to
belong to different paragraphs: a justification will not merge them.

This fixes https://savannah.gnu.org/bugs/?57404.

Bug existed since version 2.9.8, commit 432a7d77.
2019-12-17 12:23:55 +01:00
Benno Schulenberg
9631e858f2 display: don't color the space that separates line numbers from text
Go back to how line numbers were colored in versions 2.7.1 to 4.3 --
coloring the space (when a background color is used) was unintented.

This fixes https://savannah.gnu.org/bugs/?57412.

Bug existed since version 4.4, commit 699cacf7.
2019-12-16 19:23:08 +01:00
Benno Schulenberg
26d88ccbb1 syntax: sh: recognize shell rc files also in dedicated directories
This fulfills https://savannah.gnu.org/bugs/?57411.
2019-12-16 19:09:48 +01:00
Benno Schulenberg
413b9cb774 tweaks: rename a function, to get rid of a useless suffix 2019-12-15 19:47:05 +01:00
Benno Schulenberg
d3a8d81afb tweaks: rename a function, to get out of the way for another rename 2019-12-15 19:40:22 +01:00
Benno Schulenberg
e16026eacd linter: beep when trying to go beyond first or last message 2019-12-15 16:15:54 +01:00
Benno Schulenberg
90f18af8bd tweaks: reshuffle two declarations, for compactness 2019-12-15 15:30:48 +01:00
Benno Schulenberg
011e8de480 rcfile: demand that function 'exit' is bound in the file browser
For symmetry with the help viewer.

Even though the user could still exit with the bare Q, E, or X keys,
these are not listed in the help text, so they don't really count.
2019-12-15 15:28:22 +01:00
Benno Schulenberg
4e8afb2877 tweaks: drop M-Space and ^Space from the browser's key list
The 'prevword' and 'nextword' functions do not exist in the browser.

The mistake was made in commit a8c13d79 from five years ago.
2019-12-13 19:29:15 +01:00
Benno Schulenberg
c7ad5c8d86 tweaks: reshuffle an item, to avoid a lone 'else' 2019-12-13 19:06:39 +01:00
Benno Schulenberg
0b1a766964 rcfile: accept also function names and menu names only in lowercase 2019-12-13 19:03:38 +01:00
Benno Schulenberg
a7e11495bd tweaks: move three functions to the file where they are used
Also move the corresponding two arrays.
2019-12-13 18:57:42 +01:00
Benno Schulenberg
b56db25a35 docs: mention that all keywords in a nanorc file should be in lowercase 2019-12-12 19:19:07 +01:00
Benno Schulenberg
e3957ee5ee rcfile: accept only keywords in all lowercase, for speed of comparison
As was noted two months ago: nowhere in the manual does it say that
keywords are case-insensitive, and the manual shows all keywords in
lowercase, and all the examples are in lowercase too.  So... simply
expect keywords to be in all lowercase.
2019-12-12 19:18:56 +01:00
Benno Schulenberg
2a73b4a050 tweaks: reshuffle a fragment of code, for efficiency
First comparing each keystring that starts with "^" against "^Space"
was a waste of time when only one out of fifty such strings actually
is "^Space".
2019-12-12 19:00:52 +01:00
Benno Schulenberg
ef7c78910c tweaks: reshuffle a few lines, for brevity or speed or consistency
Also, don't compare case-insensitively where it is not needed.
2019-12-12 12:34:56 +01:00
Benno Schulenberg
772f1029e5 tweaks: avoid using strlen() where it is not needed 2019-12-12 12:14:38 +01:00
Benno Schulenberg
3251a216cd tweaks: unwrap a few lines, and move some strings to among their peers 2019-12-12 11:41:04 +01:00
Benno Schulenberg
00b0316ab8 syntax: nanohelp: colorize also ^/ as a possible keystroke
(In addition, colorize F20...F24 too.)

This fixes https://savannah.gnu.org/bugs/?57390.

Bug existed since version 4.6, commit 2a97cb9f.
2019-12-10 15:42:28 +01:00
Benno Schulenberg
76d90617cc build: avoid three compiler warnings when using gcc-9.2 or newer
This addresses https://savannah.gnu.org/bugs/?57360.
Reported-by: Brand Huntsman <alpha@qzx.com>
2019-12-08 11:27:06 +01:00
Benno Schulenberg
f516cddce7 build: fix compilation on macOS, where 'st_mtim' is unknown
This fixes https://savannah.gnu.org/bugs/?57367.
Reported-by: Bo Anderson <bo@toxicflames.co.uk>
Tested-by: Bo Anderson <bo@toxicflames.co.uk>
2019-12-06 12:19:32 +01:00
Benno Schulenberg
60b826e5ee tweaks: trim or adjust some whitespace in HTML, and add two keywords 2019-12-05 17:01:55 +01:00
Benno Schulenberg
fc0fcdea10 build: add the uploading of PDF and cheatsheet to the release script 2019-12-05 12:23:45 +01:00
Benno Schulenberg
1dd7b216a0 docs: add or improve the 'description' meta tag in the two HTML pages 2019-12-05 12:06:24 +01:00
Benno Schulenberg
87bf46ffb6 docs: add the 'lang' attribute in the right place to the two HTML pages 2019-12-05 11:52:17 +01:00
Benno Schulenberg
a921bdadbf tweaks: remove a stray space
Reported-by: Brand Huntsman <alpha@qzx.com>
2019-12-05 11:23:47 +01:00
Benno Schulenberg
0271e4a187 input: make <Tab> indent only when mark and cursor are on different lines
It allows entering a TAB character at the cursor position while the
mark is on the same line as the cursor, as some users sometimes do.

This refines the feature that was added in version 2.9.2, and makes
it behave like in the Gedit and Kate editors, for example.

This addresses https://savannah.gnu.org/bugs/?57357.
Reported-by: Sébastien Desreux <seb@h-k.fr>
2019-12-04 17:29:40 +01:00
Benno Schulenberg
076eb6f6af docs: mention that a negative number after "+" counts from the end
A negative line number given on the command line counts from the end
of the relevant file (-1 meaning the first line from the bottom),
and a negative column number from the end of the relevant line.

The feature was added in version 2.8.5 but not mentioned in the manual.

This addresses https://savannah.gnu.org/bugs/?57342.
Suggested-by: Andreas Schamanek <schamane@fam.tuwien.ac.at>
2019-12-02 17:00:35 +01:00
Benno Schulenberg
e484918ef2 tweaks: reshuffle a few lines, for symmetry with the preceding function 2019-12-01 17:04:15 +01:00
59 changed files with 14212 additions and 14157 deletions

View File

@@ -1,3 +1,48 @@
Changes between v4.6 and v4.7:
------------------------------
Benno Schulenberg (39):
build: add the uploading of PDF and cheatsheet to the release script
build: avoid three compiler warnings when using gcc-9.2 or newer
build: fix compilation for --enable-tiny --enable-wrapping
build: fix compilation on macOS, where 'st_mtim' is unknown
build: fix compilation when configured with --disable-justify
bump version numbers and add a news item for the 4.7 release
display: don't color the space that separates line numbers from text
docs: add or improve the 'description' meta tag in the two HTML pages
docs: add the 'lang' attribute in the right place to the two HTML pages
docs: mention that all keywords in a nanorc file should be in lowercase
docs: mention that a negative number after "+" counts from the end
gnulib: update to its current upstream state
input: make <Tab> indent only when mark and cursor are on different lines
justify: distinguish between tabs and spaces when comparing indentation
justify: treat consecutive indentations that look the same as the same
linter: beep when trying to go beyond first or last message
rcfile: accept also function names and menu names only in lowercase
rcfile: accept only keywords in all lowercase, for speed of comparison
rcfile: demand that function 'exit' is bound in the file browser
syntax: nanohelp: colorize also ^/ as a possible keystroke
syntax: sh: recognize shell rc files also in dedicated directories
tweaks: avoid using strlen() where it is not needed
tweaks: drop M-Space and ^Space from the browser's key list
tweaks: improve two comments and the ordering of some operands
tweaks: move three functions to the file where they are used
tweaks: optimize the trimming of trailing whitespace
tweaks: remove a stray space
tweaks: rename a function, to get out of the way for another rename
tweaks: rename a function, to get rid of a useless suffix
tweaks: reshuffle a few lines, for brevity or speed or consistency
tweaks: reshuffle a few lines, for symmetry with the preceding function
tweaks: reshuffle a fragment of code, for efficiency
tweaks: reshuffle and rename a few things, to elide duplication
tweaks: reshuffle an item, to avoid a lone 'else'
tweaks: reshuffle two declarations, for compactness
tweaks: slightly streamline the search for a possible wrapping point
tweaks: trim or adjust some whitespace in HTML, and add two keywords
tweaks: unwrap a few lines, and move some strings to among their peers
wrapping: never break in the quoting part nor in the indentation part
Changes between v4.5 and v4.6:
------------------------------

9
NEWS
View File

@@ -1,3 +1,12 @@
2019.12.23 - GNU nano 4.7 "Havikskruid"
• A <Tab> will indent a marked region only when mark and cursor are
on different lines.
• Two indentations (any mix of tabs and spaces) are considered the
same when they look the same (that is: indent to the same level).
• When using --breaklonglines or ^J, a line will never be broken in
its leading whitespace or quoting.
• The keywords in nanorc files must be in lowercase.
2019.11.29 - GNU nano 4.6 "And don't you eat that yellow snow"
• The 'formatter' command has returned, bound by default to M-F.
It allows running a syntax-specific command on the contents of

View File

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

View File

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

View File

@@ -1,14 +1,15 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Cheatsheet for nano</title>
<meta name="description" content="nano">
<meta name="keywords" content="cheatsheet, nano, editor, shortcuts, keystrokes, functions">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="A concise overview of the command shortcuts of the GNU nano editor, grouped by category.">
<meta name="keywords" content="cheatsheet, nano, editor, shortcuts, keystrokes, functions, operations, commands">
<meta name="author" content="Benno Schulenberg">
</head>
<body lang="en">
<body>
<br>
<h1 align="center">Overview of nano's shortcuts &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</h1>
@@ -21,9 +22,9 @@
<b>File handling</b>
<table><tbody>
<tr><td>Ctrl+S &nbsp;&nbsp;</td><td>Save current file</td></tr>
<tr><td>Ctrl+O </td><td> Offer to write file ("Save as")</td></tr>
<tr><td>Ctrl+R </td><td> Insert a file into current one</td></tr>
<tr><td>Ctrl+X </td><td> Close buffer, exit from nano</td></tr>
<tr><td>Ctrl+O</td><td>Offer to write file ("Save as")</td></tr>
<tr><td>Ctrl+R</td><td>Insert a file into current one</td></tr>
<tr><td>Ctrl+X</td><td>Close buffer, exit from nano</td></tr>
</tbody></table>
<br>
@@ -95,7 +96,7 @@
<b>Special movement</b>
<table><tbody>
<tr><td>Alt+G &nbsp;&nbsp;</td><td>Go to specified line</td></tr>
<tr><td>Alt+G &nbsp;&nbsp;&nbsp;</td><td>Go to specified line</td></tr>
<tr><td>Alt+]</td><td>Go to complementary bracket</td></tr>
<tr><td>Alt+⯅</td><td>Scroll viewport up</td></tr>
<tr><td>Alt+⯆</td><td>Scroll viewport down</td></tr>

View File

@@ -1,9 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<title>The GNU nano editor FAQ</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="The genesis story of the nano editor, plus the solution to some common problems.">
</head>
<body text="#330000" bgcolor="#ffffff" link="#0000ef" vlink="#51188e" alink="#ff0000">
<h1>The GNU nano editor FAQ</h1>
@@ -85,7 +88,7 @@
<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>
<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>4.6</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>4.7</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>
<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%">

View File

@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>.
.\"
.TH NANO 1 "version 4.6" "November 2019"
.TH NANO 1 "version 4.7" "December 2019"
.SH NAME
nano \- Nano's ANOther editor, inspired by Pico
@@ -44,6 +44,7 @@ syntax coloring, line numbering, and soft-wrapping overlong lines.
When giving a filename on the command line, the cursor can be put on a
specific line by adding the line number with a plus sign (\fB+\fR) before
the filename, and even in a specific column by adding it with a comma.
(Negative numbers count from the end of the file or line.)
The cursor can be put on the first or last occurrence of a specific string
by specifying that string after \fB+/\fR or \fB+?\fR before the filename.
The string can be made case sensitive and/or caused to be interpreted as a

View File

@@ -8,8 +8,8 @@
@smallbook
@set EDITION 0.5
@set VERSION 4.6
@set UPDATED November 2019
@set VERSION 4.7
@set UPDATED December 2019
@dircategory Editors
@direntry
@@ -23,7 +23,7 @@
@titlepage
@title GNU @command{nano}
@subtitle a small and friendly text editor
@subtitle version 4.6
@subtitle version 4.7
@author Chris Allegretta
@page
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
@node Top
@top
This manual documents the GNU @command{nano} editor, version 4.6.
This manual documents the GNU @command{nano} editor, version 4.7.
@menu
* Introduction::
@@ -128,6 +128,7 @@ section), and to edit several files in a row. Additionally, the cursor
can be put on a specific line of a file by adding the line number
with a plus sign before the filename, and even in a specific column by
adding it with a comma.
(Negative numbers count from the end of the file or line.)
The cursor can also be put on the first or last occurrence of a specific string
by specifying that string after @code{+/} or @code{+?} before the filename.
The string can be made case sensitive and/or caused to be interpreted as a
@@ -694,6 +695,7 @@ be used to configure @command{nano} on startup without using command-line
options. Additionally, there are some commands to define syntax highlighting
and to rebind keys --- @pxref{Syntax Highlighting} and @ref{Rebinding Keys}.
@command{nano} will read one command per line.
All commands and keywords should be written in lowercase.
Options in nanorc files take precedence over @command{nano}'s defaults, and
command-line options override nanorc settings. Also, options that do not

View File

@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>.
.\"
.TH NANORC 5 "version 4.6" "November 2019"
.TH NANORC 5 "version 4.7" "December 2019"
.SH NAME
nanorc \- GNU nano's configuration file
@@ -44,6 +44,7 @@ commands, which can be used to configure nano on startup without using
command-line options. Additionally, there are some commands to define
syntax highlighting and to rebind keys -- see the two separate sections
on those. \fBnano\fP reads one command per line.
All commands and keywords should be written in lowercase.
.sp
Options in \fInanorc\fP files take precedence over nano's defaults, and
command-line options override \fInanorc\fP settings. Also, options that

View File

@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>.
.\"
.TH RNANO 1 "version 4.6" "November 2019"
.TH RNANO 1 "version 4.7" "December 2019"
.SH NAME
rnano \- a restricted nano

758
po/bg.po

File diff suppressed because it is too large Load Diff

758
po/ca.po

File diff suppressed because it is too large Load Diff

758
po/cs.po

File diff suppressed because it is too large Load Diff

758
po/da.po

File diff suppressed because it is too large Load Diff

758
po/de.po

File diff suppressed because it is too large Load Diff

758
po/eo.po

File diff suppressed because it is too large Load Diff

758
po/es.po

File diff suppressed because it is too large Load Diff

758
po/eu.po

File diff suppressed because it is too large Load Diff

758
po/fi.po

File diff suppressed because it is too large Load Diff

758
po/fr.po

File diff suppressed because it is too large Load Diff

758
po/ga.po

File diff suppressed because it is too large Load Diff

758
po/gl.po

File diff suppressed because it is too large Load Diff

766
po/hr.po

File diff suppressed because it is too large Load Diff

758
po/hu.po

File diff suppressed because it is too large Load Diff

758
po/id.po

File diff suppressed because it is too large Load Diff

758
po/it.po

File diff suppressed because it is too large Load Diff

758
po/ja.po

File diff suppressed because it is too large Load Diff

758
po/ko.po

File diff suppressed because it is too large Load Diff

758
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

758
po/nb.po

File diff suppressed because it is too large Load Diff

758
po/nl.po

File diff suppressed because it is too large Load Diff

758
po/nn.po

File diff suppressed because it is too large Load Diff

758
po/pl.po

File diff suppressed because it is too large Load Diff

758
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

758
po/ro.po

File diff suppressed because it is too large Load Diff

758
po/ru.po

File diff suppressed because it is too large Load Diff

758
po/sl.po

File diff suppressed because it is too large Load Diff

758
po/sr.po

File diff suppressed because it is too large Load Diff

758
po/sv.po

File diff suppressed because it is too large Load Diff

758
po/tr.po

File diff suppressed because it is too large Load Diff

758
po/uk.po

File diff suppressed because it is too large Load Diff

758
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
VERSION="4.6"
VERSION="4.7"
./configure -C --enable-tiny && make && ./configure -C &&
@@ -22,6 +22,10 @@ gpg --verify nano-$VERSION.tar.xz.asc &&
git tag -u A0ACE884 -a v$VERSION -m "the nano $VERSION release" &&
make pdf && rm -rf doc/nano.t2p &&
scp doc/nano.pdf bens@wh0rd.org:nano.pdf &&
scp doc/cheatsheet.html bens@wh0rd.org:cheatsheet.html &&
for file in nano-$VERSION.tar.*z*; do scp $file bens@wh0rd.org:$file; done &&
gnupload --to ftp.gnu.org:nano nano-$VERSION.tar.*z &&

View File

@@ -153,9 +153,9 @@ char *do_browser(char *path)
/* Simulate a window resize to force a directory reread. */
kbinput = KEY_WINCH;
#endif
} else if (func == do_help_void) {
} else if (func == do_help) {
#ifdef ENABLE_HELP
do_help_void();
do_help();
#ifndef NANO_TINY
/* The window dimensions might have changed, so act as if. */
kbinput = KEY_WINCH;
@@ -469,7 +469,7 @@ functionptrtype parse_browser_input(int *kbinput)
case 'g':
return goto_dir_void;
case '?':
return do_help_void;
return do_help;
case 'S':
case 's':
return do_enter;

View File

@@ -244,7 +244,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
lockdata[27] = mypid / (256 * 256 * 256);
snprintf(&lockdata[2], 11, "nano %s", VERSION);
strncpy(&lockdata[28], mypwuid->pw_name, 16);
strncpy(&lockdata[68], myhostname, 31);
strncpy(&lockdata[68], myhostname, 32);
if (origfilename != NULL)
strncpy(&lockdata[108], origfilename, 768);
if (modified == TRUE)
@@ -2074,7 +2074,7 @@ int do_writeout(bool exiting, bool withprompt)
continue;
}
#endif /* !NANO_TINY */
if (func == do_help_void) {
if (func == do_help) {
continue;
}
#ifdef ENABLE_EXTRA

View File

@@ -248,20 +248,6 @@ char *homedir = NULL;
char *statedir = NULL;
/* The directory for nano's history files. */
#ifdef ENABLE_NANORC
#define NUMBER_OF_MENUS 16
char *menunames[NUMBER_OF_MENUS] = { "main", "search", "replace", "replacewith",
"yesno", "gotoline", "writeout", "insert",
"extcmd", "help", "spell", "linter",
"browser", "whereisfile", "gotodir",
"all" };
int menusymbols[NUMBER_OF_MENUS] = { MMAIN, MWHEREIS, MREPLACE, MREPLACEWITH,
MYESNO, MGOTOLINE, MWRITEFILE, MINSERTFILE,
MEXTCMD, MHELP, MSPELL, MLINTER,
MBROWSER, MWHEREISFILE, MGOTODIR,
MMOST|MBROWSER|MHELP|MYESNO };
#endif
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
char *startup_problem = NULL;
/* An error message (if any) about nanorc files or history files. */
@@ -486,23 +472,26 @@ functionptrtype func_from_key(int *kbinput)
int keycode_from_string(const char *keystring)
{
if (keystring[0] == '^') {
if (strcasecmp(keystring, "^Space") == 0)
return 0;
if (keystring[2] == '\0') {
if (keystring[1] == '/')
return 31;
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
if (strcasecmp(keystring, "^H") == 0)
return KEY_BACKSPACE;
if (keystring[1] == 'H')
return KEY_BACKSPACE;
#endif
if (keystring[1] == '/' && strlen(keystring) == 2)
return 31;
if (keystring[1] <= '_' && strlen(keystring) == 2)
return keystring[1] - 64;
if (keystring[1] <= '_')
return keystring[1] - 64;
else
return -1;
} else if (strcasecmp(keystring, "^Space") == 0)
return 0;
else
return -1;
} else if (keystring[0] == 'M') {
if (keystring[1] == '-' && keystring[3] == '\0')
return tolower((unsigned char)keystring[2]);
if (strcasecmp(keystring, "M-Space") == 0)
return (int)' ';
if (keystring[1] == '-' && strlen(keystring) == 3)
return tolower((unsigned char)keystring[2]);
else
return -1;
} else if (keystring[0] == 'F') {
@@ -510,9 +499,9 @@ int keycode_from_string(const char *keystring)
if (fn < 1 || fn > 24)
return -1;
return KEY_F0 + fn;
} else if (!strcasecmp(keystring, "Ins"))
} else if (strcasecmp(keystring, "Ins") == 0)
return KEY_IC;
else if (!strcasecmp(keystring, "Del"))
else if (strcasecmp(keystring, "Del") == 0)
return KEY_DC;
else
return -1;
@@ -523,11 +512,7 @@ void assign_keyinfo(keystruct *s, const char *keystring, const int keycode)
{
s->keystr = keystring;
s->meta = (keystring[0] == 'M' && keycode == 0);
if (keycode)
s->keycode = keycode;
else
s->keycode = keycode_from_string(keystring);
s->keycode = (keycode ? keycode : keycode_from_string(keystring));
}
/* These two tags are used elsewhere too, so they are global. */
@@ -543,8 +528,7 @@ void shortcut_init(void)
* they are best kept shorter than 56 characters, but may be longer. */
const char *cancel_gist = N_("Cancel the current function");
const char *help_gist = N_("Display this help text");
const char *exit_gist =
N_("Close the current buffer / Exit from nano");
const char *exit_gist = N_("Close the current buffer / Exit from nano");
const char *writeout_gist =
N_("Write the current buffer (or the marked region) to disk");
const char *readfile_gist =
@@ -553,19 +537,6 @@ void shortcut_init(void)
N_("Search forward for a string or a regular expression");
const char *wherewas_gist =
N_("Search backward for a string or a regular expression");
#ifdef ENABLE_BROWSER
const char *browserwhereis_gist = N_("Search forward for a string");
const char *browserwherewas_gist = N_("Search backward for a string");
const char *browserrefresh_gist = N_("Refresh the file list");
#ifndef NANO_TINY
const char *browserlefthand_gist = N_("Go to lefthand column");
const char *browserrighthand_gist = N_("Go to righthand column");
const char *browsertoprow_gist = N_("Go to first row in this column");
const char *browserbottomrow_gist = N_("Go to last row in this column");
#endif
#endif
const char *prevpage_gist = N_("Go one screenful up");
const char *nextpage_gist = N_("Go one screenful down");
const char *cut_gist =
N_("Cut current line (or marked region) and store it in cutbuffer");
const char *uncut_gist =
@@ -602,6 +573,8 @@ void shortcut_init(void)
const char *paraend_gist =
N_("Go just beyond end of paragraph; then of next paragraph");
#endif
const char *prevpage_gist = N_("Go one screenful up");
const char *nextpage_gist = N_("Go one screenful down");
const char *firstline_gist = N_("Go to the first line of the file");
const char *lastline_gist = N_("Go to the last line of the file");
#ifndef NANO_TINY
@@ -657,12 +630,9 @@ void shortcut_init(void)
const char *recordmacro_gist = N_("Start/stop recording a macro");
const char *runmacro_gist = N_("Run the last recorded macro");
#endif
const char *case_gist =
N_("Toggle the case sensitivity of the search");
const char *reverse_gist =
N_("Reverse the direction of the search");
const char *regexp_gist =
N_("Toggle the use of regular expressions");
const char *case_gist = N_("Toggle the case sensitivity of the search");
const char *reverse_gist = N_("Reverse the direction of the search");
const char *regexp_gist = N_("Toggle the use of regular expressions");
#ifdef ENABLE_HISTORIES
const char *older_gist =
N_("Recall the previous search/replace string");
@@ -691,6 +661,15 @@ void shortcut_init(void)
const char *lastfile_gist = N_("Go to the last file in the list");
const char *backfile_gist = N_("Go to the previous file in the list");
const char *forwardfile_gist = N_("Go to the next file in the list");
#ifndef NANO_TINY
const char *browserlefthand_gist = N_("Go to lefthand column");
const char *browserrighthand_gist = N_("Go to righthand column");
const char *browsertoprow_gist = N_("Go to first row in this column");
const char *browserbottomrow_gist = N_("Go to last row in this column");
#endif
const char *browserwhereis_gist = N_("Search forward for a string");
const char *browserwherewas_gist = N_("Search backward for a string");
const char *browserrefresh_gist = N_("Refresh the file list");
const char *gotodir_gist = N_("Go to directory");
#endif
#ifdef ENABLE_COLOR
@@ -712,7 +691,7 @@ void shortcut_init(void)
/* Start populating the different menus with functions. */
add_to_funcs(do_help_void, (MMOST | MBROWSER) & ~MFINDINHELP,
add_to_funcs(do_help, (MMOST | MBROWSER) & ~MFINDINHELP,
/* TRANSLATORS: Try to keep the next eleven strings at most 10 characters. */
N_("Get Help"), WITHORSANS(help_gist), TOGETHER, VIEW);
@@ -1115,7 +1094,7 @@ void shortcut_init(void)
add_to_sclist(MMOST, "Del", 0, do_delete, 0);
add_to_sclist(MMOST, "^I", 0, do_tab, 0);
add_to_sclist(MMOST, "Tab", TAB_CODE, do_tab, 0);
add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, "^G", 0, do_help_void, 0);
add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, "^G", 0, do_help, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", 0, do_exit, 0);
if (!ISSET(PRESERVE))
add_to_sclist(MMAIN, "^S", 0, do_savefile, 0);
@@ -1216,8 +1195,8 @@ void shortcut_init(void)
add_to_sclist(MMAIN, "M-F", 0, do_next_word_void, 0);
add_to_sclist(MMAIN, "M-N", 0, do_next_word_void, 0);
#endif
add_to_sclist(MMOST|MBROWSER, "M-Space", 0, do_prev_word_void, 0);
add_to_sclist(MMOST|MBROWSER, "^Space", 0, do_next_word_void, 0);
add_to_sclist(MMOST, "M-Space", 0, do_prev_word_void, 0);
add_to_sclist(MMOST, "^Space", 0, do_next_word_void, 0);
add_to_sclist(MMOST, "^A", 0, do_home, 0);
add_to_sclist(MMOST, "Home", KEY_HOME, do_home, 0);
add_to_sclist(MMOST, "^E", 0, do_end, 0);
@@ -1401,7 +1380,7 @@ void shortcut_init(void)
#ifdef ENABLE_COLOR
add_to_sclist(MLINTER, "^X", 0, do_cancel, 0);
#endif
add_to_sclist(MMOST & ~MFINDINHELP, "F1", 0, do_help_void, 0);
add_to_sclist(MMOST & ~MFINDINHELP, "F1", 0, do_help, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", 0, do_exit, 0);
add_to_sclist(MMAIN, "F3", 0, do_writeout_void, 0);
#ifdef ENABLE_JUSTIFY
@@ -1457,295 +1436,3 @@ const char *flagtostr(int flag)
}
}
#endif /* !NANO_TINY */
#ifdef ENABLE_NANORC
/* Interpret a function string given in the rc file, and return a
* shortcut record with the corresponding function filled in. */
keystruct *strtosc(const char *input)
{
keystruct *s = nmalloc(sizeof(keystruct));
#ifndef NANO_TINY
s->toggle = 0;
#endif
#ifdef ENABLE_HELP
if (!strcasecmp(input, "help"))
s->func = do_help_void;
else
#endif
if (!strcasecmp(input, "cancel"))
s->func = do_cancel;
else if (!strcasecmp(input, "exit"))
s->func = do_exit;
else if (!strcasecmp(input, "discardbuffer"))
s->func = discard_buffer;
else if (!strcasecmp(input, "writeout"))
s->func = do_writeout_void;
else if (!strcasecmp(input, "savefile"))
s->func = do_savefile;
else if (!strcasecmp(input, "insert"))
s->func = do_insertfile_void;
else if (!strcasecmp(input, "whereis"))
s->func = do_search_forward;
else if (!strcasecmp(input, "wherewas"))
s->func = do_search_backward;
else if (!strcasecmp(input, "findprevious"))
s->func = do_findprevious;
else if (!strcasecmp(input, "findnext"))
s->func = do_findnext;
else if (!strcasecmp(input, "replace"))
s->func = do_replace;
else if (!strcasecmp(input, "cut"))
s->func = cut_text;
else if (!strcasecmp(input, "paste"))
s->func = paste_text;
#ifndef NANO_TINY
else if (!strcasecmp(input, "cutrestoffile"))
s->func = cut_till_eof;
else if (!strcasecmp(input, "copy"))
s->func = copy_text;
else if (!strcasecmp(input, "zap"))
s->func = zap_text;
else if (!strcasecmp(input, "mark"))
s->func = do_mark;
#endif
#ifdef ENABLE_SPELLER
else if (!strcasecmp(input, "tospell") ||
!strcasecmp(input, "speller"))
s->func = do_spell;
#endif
#ifdef ENABLE_COLOR
else if (!strcasecmp(input, "linter"))
s->func = do_linter;
#ifdef ENABLE_SPELLER
else if (!strcasecmp(input, "formatter"))
s->func = do_formatter;
#endif
#endif
else if (!strcasecmp(input, "curpos"))
s->func = do_cursorpos_void;
else if (!strcasecmp(input, "gotoline"))
s->func = do_gotolinecolumn_void;
#ifdef ENABLE_JUSTIFY
else if (!strcasecmp(input, "justify"))
s->func = do_justify_void;
else if (!strcasecmp(input, "fulljustify"))
s->func = do_full_justify;
else if (!strcasecmp(input, "beginpara"))
s->func = do_para_begin_void;
else if (!strcasecmp(input, "endpara"))
s->func = do_para_end_void;
#endif
#ifdef ENABLE_COMMENT
else if (!strcasecmp(input, "comment"))
s->func = do_comment;
#endif
#ifdef ENABLE_WORDCOMPLETION
else if (!strcasecmp(input, "complete"))
s->func = complete_a_word;
#endif
#ifndef NANO_TINY
else if (!strcasecmp(input, "indent"))
s->func = do_indent;
else if (!strcasecmp(input, "unindent"))
s->func = do_unindent;
else if (!strcasecmp(input, "chopwordleft") ||
!strcasecmp(input, "cutwordleft")) /* Deprecated; remove in 2021. */
s->func = chop_previous_word;
else if (!strcasecmp(input, "chopwordright") ||
!strcasecmp(input, "cutwordright")) /* Deprecated; remove in 2021. */
s->func = chop_next_word;
else if (!strcasecmp(input, "findbracket"))
s->func = do_find_bracket;
else if (!strcasecmp(input, "wordcount"))
s->func = do_wordlinechar_count;
else if (!strcasecmp(input, "recordmacro"))
s->func = record_macro;
else if (!strcasecmp(input, "runmacro"))
s->func = run_macro;
else if (!strcasecmp(input, "undo"))
s->func = do_undo;
else if (!strcasecmp(input, "redo"))
s->func = do_redo;
#endif
else if (!strcasecmp(input, "left") ||
!strcasecmp(input, "back"))
s->func = do_left;
else if (!strcasecmp(input, "right") ||
!strcasecmp(input, "forward"))
s->func = do_right;
else if (!strcasecmp(input, "up") ||
!strcasecmp(input, "prevline"))
s->func = do_up;
else if (!strcasecmp(input, "down") ||
!strcasecmp(input, "nextline"))
s->func = do_down;
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
else if (!strcasecmp(input, "scrollup"))
s->func = do_scroll_up;
else if (!strcasecmp(input, "scrolldown"))
s->func = do_scroll_down;
#endif
else if (!strcasecmp(input, "prevword"))
s->func = do_prev_word_void;
else if (!strcasecmp(input, "nextword"))
s->func = do_next_word_void;
else if (!strcasecmp(input, "home"))
s->func = do_home;
else if (!strcasecmp(input, "end"))
s->func = do_end;
else if (!strcasecmp(input, "prevblock"))
s->func = do_prev_block;
else if (!strcasecmp(input, "nextblock"))
s->func = do_next_block;
else if (!strcasecmp(input, "pageup") ||
!strcasecmp(input, "prevpage"))
s->func = do_page_up;
else if (!strcasecmp(input, "pagedown") ||
!strcasecmp(input, "nextpage"))
s->func = do_page_down;
else if (!strcasecmp(input, "firstline"))
s->func = to_first_line;
else if (!strcasecmp(input, "lastline"))
s->func = to_last_line;
#ifdef ENABLE_MULTIBUFFER
else if (!strcasecmp(input, "prevbuf"))
s->func = switch_to_prev_buffer;
else if (!strcasecmp(input, "nextbuf"))
s->func = switch_to_next_buffer;
#endif
else if (!strcasecmp(input, "verbatim"))
s->func = do_verbatim_input;
else if (!strcasecmp(input, "tab"))
s->func = do_tab;
else if (!strcasecmp(input, "enter"))
s->func = do_enter;
else if (!strcasecmp(input, "delete"))
s->func = do_delete;
else if (!strcasecmp(input, "backspace"))
s->func = do_backspace;
else if (!strcasecmp(input, "refresh"))
s->func = total_refresh;
else if (!strcasecmp(input, "suspend"))
s->func = do_suspend_void;
else if (!strcasecmp(input, "casesens"))
s->func = case_sens_void;
else if (!strcasecmp(input, "regexp"))
s->func = regexp_void;
else if (!strcasecmp(input, "backwards"))
s->func = backwards_void;
else if (!strcasecmp(input, "flipreplace"))
s->func = flip_replace;
else if (!strcasecmp(input, "flipgoto"))
s->func = flip_goto;
#ifdef ENABLE_HISTORIES
else if (!strcasecmp(input, "older"))
s->func = get_history_older_void;
else if (!strcasecmp(input, "newer"))
s->func = get_history_newer_void;
#endif
#ifndef NANO_TINY
else if (!strcasecmp(input, "dosformat"))
s->func = dos_format_void;
else if (!strcasecmp(input, "macformat"))
s->func = mac_format_void;
else if (!strcasecmp(input, "append"))
s->func = append_void;
else if (!strcasecmp(input, "prepend"))
s->func = prepend_void;
else if (!strcasecmp(input, "backup"))
s->func = backup_file_void;
else if (!strcasecmp(input, "flipexecute"))
s->func = flip_execute;
else if (!strcasecmp(input, "flippipe"))
s->func = flip_pipe;
else if (!strcasecmp(input, "flipconvert"))
s->func = flip_convert;
#endif
#ifdef ENABLE_MULTIBUFFER
else if (!strcasecmp(input, "flipnewbuffer"))
s->func = flip_newbuffer;
#endif
#ifdef ENABLE_BROWSER
else if (!strcasecmp(input, "tofiles") ||
!strcasecmp(input, "browser"))
s->func = to_files_void;
else if (!strcasecmp(input, "gotodir"))
s->func = goto_dir_void;
else if (!strcasecmp(input, "firstfile"))
s->func = to_first_file;
else if (!strcasecmp(input, "lastfile"))
s->func = to_last_file;
#endif
else {
#ifndef NANO_TINY
s->func = do_toggle_void;
if (!strcasecmp(input, "nohelp"))
s->toggle = NO_HELP;
else if (!strcasecmp(input, "constantshow"))
s->toggle = CONSTANT_SHOW;
else if (!strcasecmp(input, "softwrap"))
s->toggle = SOFTWRAP;
#ifdef ENABLE_LINENUMBERS
else if (!strcasecmp(input, "linenumbers"))
s->toggle = LINE_NUMBERS;
#endif
else if (!strcasecmp(input, "whitespacedisplay"))
s->toggle = WHITESPACE_DISPLAY;
#ifdef ENABLE_COLOR
else if (!strcasecmp(input, "nosyntax"))
s->toggle = NO_COLOR_SYNTAX;
#endif
else if (!strcasecmp(input, "smarthome"))
s->toggle = SMART_HOME;
else if (!strcasecmp(input, "autoindent"))
s->toggle = AUTOINDENT;
else if (!strcasecmp(input, "cutfromcursor"))
s->toggle = CUT_FROM_CURSOR;
#ifdef ENABLE_WRAPPING
else if (!strcasecmp(input, "nowrap"))
s->toggle = BREAK_LONG_LINES;
#endif
else if (!strcasecmp(input, "tabstospaces"))
s->toggle = TABS_TO_SPACES;
#ifdef ENABLE_MOUSE
else if (!strcasecmp(input, "mouse"))
s->toggle = USE_MOUSE;
#endif
else if (!strcasecmp(input, "suspendenable"))
s->toggle = SUSPEND;
else
#endif /* !NANO_TINY */
{
free(s);
return NULL;
}
}
return s;
}
/* Return the symbol that corresponds to the given menu name. */
int name_to_menu(const char *name)
{
int index = -1;
while (++index < NUMBER_OF_MENUS)
if (strcasecmp(name, menunames[index]) == 0)
return menusymbols[index];
return -1;
}
/* Return the name that corresponds to the given menu symbol. */
char *menu_to_name(int menu)
{
int index = -1;
while (++index < NUMBER_OF_MENUS)
if (menusymbols[index] == menu)
return menunames[index];
return "boooo";
}
#endif /* ENABLE_NANORC */

View File

@@ -88,8 +88,8 @@ void wrap_help_text_into_buffer(void)
openfile->edittop = openfile->current;
}
/* Our main help-viewer function. */
void do_help(void)
/* Assemble a help text, display it, and allow scrolling through it. */
void show_help(void)
{
int kbinput = ERR;
functionptrtype func;
@@ -140,8 +140,9 @@ void do_help(void)
#endif
curs_set(0);
/* Compose the help text from all the pieces. */
/* Compose the help text from all the relevant pieces. */
help_init();
inhelp = TRUE;
location = 0;
didfind = 0;
@@ -600,14 +601,13 @@ size_t help_line_len(const char *ptr)
else
return 1;
}
#endif /* ENABLE_HELP */
/* Start the help viewer. */
void do_help_void(void)
/* Start the help viewer, or indicate that there is no help. */
void do_help(void)
{
#ifdef ENABLE_HELP
do_help();
show_help();
#else
if (currmenu == MMAIN)
say_there_is_no_help();

View File

@@ -255,7 +255,7 @@ void unpartition_buffer(void)
strlen(antedata) + strlen(openfile->filetop->data) + 1);
memmove(openfile->filetop->data + strlen(antedata),
openfile->filetop->data, strlen(openfile->filetop->data) + 1);
strncpy(openfile->filetop->data, antedata, strlen(antedata));
memcpy(openfile->filetop->data, antedata, strlen(antedata));
free(antedata);
antedata = NULL;

View File

@@ -543,9 +543,9 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
}
} else
#endif /* ENABLE_HISTORIES */
if (func == do_help_void) {
if (func == do_help) {
/* This key has a shortcut-list entry when it's used to go to
* the help browser or display a message indicating that help
* the help viewer or display a message indicating that help
* is disabled, which means that finished has been set to TRUE.
* Set it back to FALSE here, so that we aren't kicked out of
* the statusbar prompt. */

View File

@@ -328,21 +328,15 @@ int keycode_from_string(const char *keystring);
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode);
void shortcut_init(void);
const char *flagtostr(int flag);
#ifdef ENABLE_NANORC
keystruct *strtosc(const char *input);
int name_to_menu(const char *name);
char *menu_to_name(int menu);
#endif
/* All functions in help.c. */
#ifdef ENABLE_HELP
void wrap_help_text_into_buffer(void);
void do_help(void);
void help_init(void);
functionptrtype parse_help_input(int *kbinput);
size_t help_line_len(const char *ptr);
#endif
void do_help_void(void);
void do_help(void);
/* Most functions in history.c. */
#ifdef ENABLE_HISTORIES
@@ -537,7 +531,7 @@ bool do_wrap(void);
#if defined(ENABLE_HELP) || defined(ENABLED_WRAPORJUSTIFY)
ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl);
#endif
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
#if !defined(NANO_TINY) || defined(ENABLED_WRAPORJUSTIFY)
size_t indent_length(const char *line);
#endif
#ifdef ENABLE_JUSTIFY

View File

@@ -146,6 +146,18 @@ static bool seen_color_command = FALSE;
static colortype *lastcolor = NULL;
/* The end of the color list for the current syntax. */
#endif
#define NUMBER_OF_MENUS 16
char *menunames[NUMBER_OF_MENUS] = { "main", "search", "replace", "replacewith",
"yesno", "gotoline", "writeout", "insert",
"extcmd", "help", "spell", "linter",
"browser", "whereisfile", "gotodir",
"all" };
int menusymbols[NUMBER_OF_MENUS] = { MMAIN, MWHEREIS, MREPLACE, MREPLACEWITH,
MYESNO, MGOTOLINE, MWRITEFILE, MINSERTFILE,
MEXTCMD, MHELP, MSPELL, MLINTER,
MBROWSER, MWHEREISFILE, MGOTODIR,
MMOST|MBROWSER|MHELP|MYESNO };
#endif /* ENABLE_NANORC */
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
@@ -200,6 +212,295 @@ void jot_error(const char *msg, ...)
#endif /* ENABLE_NANORC || ENABLE_HISTORIES */
#ifdef ENABLE_NANORC
/* Interpret a function string given in the rc file, and return a
* shortcut record with the corresponding function filled in. */
keystruct *strtosc(const char *input)
{
keystruct *s = nmalloc(sizeof(keystruct));
#ifndef NANO_TINY
s->toggle = 0;
#endif
if (!strcmp(input, "cancel"))
s->func = do_cancel;
#ifdef ENABLE_HELP
else if (!strcmp(input, "help"))
s->func = do_help;
#endif
else if (!strcmp(input, "exit"))
s->func = do_exit;
else if (!strcmp(input, "discardbuffer"))
s->func = discard_buffer;
else if (!strcmp(input, "writeout"))
s->func = do_writeout_void;
else if (!strcmp(input, "savefile"))
s->func = do_savefile;
else if (!strcmp(input, "insert"))
s->func = do_insertfile_void;
else if (!strcmp(input, "whereis"))
s->func = do_search_forward;
else if (!strcmp(input, "wherewas"))
s->func = do_search_backward;
else if (!strcmp(input, "findprevious"))
s->func = do_findprevious;
else if (!strcmp(input, "findnext"))
s->func = do_findnext;
else if (!strcmp(input, "replace"))
s->func = do_replace;
else if (!strcmp(input, "cut"))
s->func = cut_text;
else if (!strcmp(input, "paste"))
s->func = paste_text;
#ifndef NANO_TINY
else if (!strcmp(input, "cutrestoffile"))
s->func = cut_till_eof;
else if (!strcmp(input, "copy"))
s->func = copy_text;
else if (!strcmp(input, "zap"))
s->func = zap_text;
else if (!strcmp(input, "mark"))
s->func = do_mark;
#endif
#ifdef ENABLE_SPELLER
else if (!strcmp(input, "tospell") ||
!strcmp(input, "speller"))
s->func = do_spell;
#endif
#ifdef ENABLE_COLOR
else if (!strcmp(input, "linter"))
s->func = do_linter;
#ifdef ENABLE_SPELLER
else if (!strcmp(input, "formatter"))
s->func = do_formatter;
#endif
#endif
else if (!strcmp(input, "curpos"))
s->func = do_cursorpos_void;
else if (!strcmp(input, "gotoline"))
s->func = do_gotolinecolumn_void;
#ifdef ENABLE_JUSTIFY
else if (!strcmp(input, "justify"))
s->func = do_justify_void;
else if (!strcmp(input, "fulljustify"))
s->func = do_full_justify;
else if (!strcmp(input, "beginpara"))
s->func = do_para_begin_void;
else if (!strcmp(input, "endpara"))
s->func = do_para_end_void;
#endif
#ifdef ENABLE_COMMENT
else if (!strcmp(input, "comment"))
s->func = do_comment;
#endif
#ifdef ENABLE_WORDCOMPLETION
else if (!strcmp(input, "complete"))
s->func = complete_a_word;
#endif
#ifndef NANO_TINY
else if (!strcmp(input, "indent"))
s->func = do_indent;
else if (!strcmp(input, "unindent"))
s->func = do_unindent;
else if (!strcmp(input, "chopwordleft") ||
!strcmp(input, "cutwordleft")) /* Deprecated; remove in 2021. */
s->func = chop_previous_word;
else if (!strcmp(input, "chopwordright") ||
!strcmp(input, "cutwordright")) /* Deprecated; remove in 2021. */
s->func = chop_next_word;
else if (!strcmp(input, "findbracket"))
s->func = do_find_bracket;
else if (!strcmp(input, "wordcount"))
s->func = do_wordlinechar_count;
else if (!strcmp(input, "recordmacro"))
s->func = record_macro;
else if (!strcmp(input, "runmacro"))
s->func = run_macro;
else if (!strcmp(input, "undo"))
s->func = do_undo;
else if (!strcmp(input, "redo"))
s->func = do_redo;
#endif
else if (!strcmp(input, "left") ||
!strcmp(input, "back"))
s->func = do_left;
else if (!strcmp(input, "right") ||
!strcmp(input, "forward"))
s->func = do_right;
else if (!strcmp(input, "up") ||
!strcmp(input, "prevline"))
s->func = do_up;
else if (!strcmp(input, "down") ||
!strcmp(input, "nextline"))
s->func = do_down;
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
else if (!strcmp(input, "scrollup"))
s->func = do_scroll_up;
else if (!strcmp(input, "scrolldown"))
s->func = do_scroll_down;
#endif
else if (!strcmp(input, "prevword"))
s->func = do_prev_word_void;
else if (!strcmp(input, "nextword"))
s->func = do_next_word_void;
else if (!strcmp(input, "home"))
s->func = do_home;
else if (!strcmp(input, "end"))
s->func = do_end;
else if (!strcmp(input, "prevblock"))
s->func = do_prev_block;
else if (!strcmp(input, "nextblock"))
s->func = do_next_block;
else if (!strcmp(input, "pageup") ||
!strcmp(input, "prevpage"))
s->func = do_page_up;
else if (!strcmp(input, "pagedown") ||
!strcmp(input, "nextpage"))
s->func = do_page_down;
else if (!strcmp(input, "firstline"))
s->func = to_first_line;
else if (!strcmp(input, "lastline"))
s->func = to_last_line;
#ifdef ENABLE_MULTIBUFFER
else if (!strcmp(input, "prevbuf"))
s->func = switch_to_prev_buffer;
else if (!strcmp(input, "nextbuf"))
s->func = switch_to_next_buffer;
#endif
else if (!strcmp(input, "verbatim"))
s->func = do_verbatim_input;
else if (!strcmp(input, "tab"))
s->func = do_tab;
else if (!strcmp(input, "enter"))
s->func = do_enter;
else if (!strcmp(input, "delete"))
s->func = do_delete;
else if (!strcmp(input, "backspace"))
s->func = do_backspace;
else if (!strcmp(input, "refresh"))
s->func = total_refresh;
else if (!strcmp(input, "suspend"))
s->func = do_suspend_void;
else if (!strcmp(input, "casesens"))
s->func = case_sens_void;
else if (!strcmp(input, "regexp"))
s->func = regexp_void;
else if (!strcmp(input, "backwards"))
s->func = backwards_void;
else if (!strcmp(input, "flipreplace"))
s->func = flip_replace;
else if (!strcmp(input, "flipgoto"))
s->func = flip_goto;
#ifdef ENABLE_HISTORIES
else if (!strcmp(input, "older"))
s->func = get_history_older_void;
else if (!strcmp(input, "newer"))
s->func = get_history_newer_void;
#endif
#ifndef NANO_TINY
else if (!strcmp(input, "dosformat"))
s->func = dos_format_void;
else if (!strcmp(input, "macformat"))
s->func = mac_format_void;
else if (!strcmp(input, "append"))
s->func = append_void;
else if (!strcmp(input, "prepend"))
s->func = prepend_void;
else if (!strcmp(input, "backup"))
s->func = backup_file_void;
else if (!strcmp(input, "flipexecute"))
s->func = flip_execute;
else if (!strcmp(input, "flippipe"))
s->func = flip_pipe;
else if (!strcmp(input, "flipconvert"))
s->func = flip_convert;
#endif
#ifdef ENABLE_MULTIBUFFER
else if (!strcmp(input, "flipnewbuffer"))
s->func = flip_newbuffer;
#endif
#ifdef ENABLE_BROWSER
else if (!strcmp(input, "tofiles") ||
!strcmp(input, "browser"))
s->func = to_files_void;
else if (!strcmp(input, "gotodir"))
s->func = goto_dir_void;
else if (!strcmp(input, "firstfile"))
s->func = to_first_file;
else if (!strcmp(input, "lastfile"))
s->func = to_last_file;
#endif
else {
#ifndef NANO_TINY
s->func = do_toggle_void;
if (!strcmp(input, "nohelp"))
s->toggle = NO_HELP;
else if (!strcmp(input, "constantshow"))
s->toggle = CONSTANT_SHOW;
else if (!strcmp(input, "softwrap"))
s->toggle = SOFTWRAP;
#ifdef ENABLE_LINENUMBERS
else if (!strcmp(input, "linenumbers"))
s->toggle = LINE_NUMBERS;
#endif
else if (!strcmp(input, "whitespacedisplay"))
s->toggle = WHITESPACE_DISPLAY;
#ifdef ENABLE_COLOR
else if (!strcmp(input, "nosyntax"))
s->toggle = NO_COLOR_SYNTAX;
#endif
else if (!strcmp(input, "smarthome"))
s->toggle = SMART_HOME;
else if (!strcmp(input, "autoindent"))
s->toggle = AUTOINDENT;
else if (!strcmp(input, "cutfromcursor"))
s->toggle = CUT_FROM_CURSOR;
#ifdef ENABLE_WRAPPING
else if (!strcmp(input, "nowrap"))
s->toggle = BREAK_LONG_LINES;
#endif
else if (!strcmp(input, "tabstospaces"))
s->toggle = TABS_TO_SPACES;
#ifdef ENABLE_MOUSE
else if (!strcmp(input, "mouse"))
s->toggle = USE_MOUSE;
#endif
else if (!strcmp(input, "suspendenable"))
s->toggle = SUSPEND;
else
#endif /* !NANO_TINY */
{
free(s);
return NULL;
}
}
return s;
}
/* Return the symbol that corresponds to the given menu name. */
int name_to_menu(const char *name)
{
int index = -1;
while (++index < NUMBER_OF_MENUS)
if (strcmp(name, menunames[index]) == 0)
return menusymbols[index];
return -1;
}
/* Return the name that corresponds to the given menu symbol. */
char *menu_to_name(int menu)
{
int index = -1;
while (++index < NUMBER_OF_MENUS)
if (menusymbols[index] == menu)
return menunames[index];
return "boooo";
}
/* Parse the next word from the string, null-terminate it, and return
* a pointer to the first character after the null terminator. The
* returned pointer will point to '\0' if we hit the end of the line. */
@@ -419,7 +720,7 @@ void parse_binding(char *ptr, bool dobind)
ptr = parse_next_word(ptr);
keycopy = copy_of(keyptr);
if (strlen(keycopy) < 2) {
if (keycopy[1] == '\0') {
jot_error(N_("Key name is too short"));
goto free_things;
}
@@ -428,12 +729,11 @@ void parse_binding(char *ptr, bool dobind)
keycopy[0] = toupper((unsigned char)keycopy[0]);
keycopy[1] = toupper((unsigned char)keycopy[1]);
if (keycopy[0] == 'M' && keycopy[1] == '-') {
if (strlen(keycopy) > 2)
keycopy[2] = toupper((unsigned char)keycopy[2]);
else {
if (keycopy[2] == '\0') {
jot_error(N_("Key name is too short"));
goto free_things;
}
} else
keycopy[2] = toupper((unsigned char)keycopy[2]);
}
/* Allow the codes for Insert and Delete to be rebound, but apart
@@ -676,23 +976,23 @@ short color_to_short(const char *colorname, bool *bright)
} else
*bright = FALSE;
if (strcasecmp(colorname, "green") == 0)
if (strcmp(colorname, "green") == 0)
return COLOR_GREEN;
else if (strcasecmp(colorname, "red") == 0)
else if (strcmp(colorname, "red") == 0)
return COLOR_RED;
else if (strcasecmp(colorname, "blue") == 0)
else if (strcmp(colorname, "blue") == 0)
return COLOR_BLUE;
else if (strcasecmp(colorname, "white") == 0)
else if (strcmp(colorname, "white") == 0)
return COLOR_WHITE;
else if (strcasecmp(colorname, "yellow") == 0)
else if (strcmp(colorname, "yellow") == 0)
return COLOR_YELLOW;
else if (strcasecmp(colorname, "cyan") == 0)
else if (strcmp(colorname, "cyan") == 0)
return COLOR_CYAN;
else if (strcasecmp(colorname, "magenta") == 0)
else if (strcmp(colorname, "magenta") == 0)
return COLOR_MAGENTA;
else if (strcasecmp(colorname, "black") == 0)
else if (strcmp(colorname, "black") == 0)
return COLOR_BLACK;
else if (strcasecmp(colorname, "normal") == 0)
else if (strcmp(colorname, "normal") == 0)
return USE_THE_DEFAULT;
jot_error(N_("Color \"%s\" not understood"), colorname);
@@ -952,21 +1252,21 @@ void pick_up_name(const char *kind, char *ptr, char **storage)
/* Handle the four syntax-only commands. */
bool parse_syntax_commands(char *keyword, char *ptr)
{
if (strcasecmp(keyword, "color") == 0)
if (strcmp(keyword, "color") == 0)
parse_colors(ptr, NANO_REG_EXTENDED);
else if (strcasecmp(keyword, "icolor") == 0)
else if (strcmp(keyword, "icolor") == 0)
parse_colors(ptr, NANO_REG_EXTENDED | REG_ICASE);
else if (strcasecmp(keyword, "comment") == 0) {
else if (strcmp(keyword, "comment") == 0) {
#ifdef ENABLE_COMMENT
pick_up_name("comment", ptr, &live_syntax->comment);
#endif
} else if (strcasecmp(keyword, "tabgives") == 0) {
} else if (strcmp(keyword, "tabgives") == 0) {
#ifdef ENABLE_COLOR
pick_up_name("tabgives", ptr, &live_syntax->tab);
#endif
} else if (strcasecmp(keyword, "linter") == 0)
} else if (strcmp(keyword, "linter") == 0)
pick_up_name("linter", ptr, &live_syntax->linter);
else if (strcasecmp(keyword, "formatter") == 0)
else if (strcmp(keyword, "formatter") == 0)
pick_up_name("formatter", ptr, &live_syntax->formatter);
else
return FALSE;
@@ -979,14 +1279,12 @@ bool parse_syntax_commands(char *keyword, char *ptr)
* function that we consider 'vital' (such as "Exit"). */
static void check_vitals_mapped(void)
{
funcstruct *f;
int v;
#define VITALS 3
void (*vitals[VITALS])(void) = { do_exit, do_exit, do_cancel };
int inmenus[VITALS] = { MMAIN, MHELP, MYESNO };
#define VITALS 4
void (*vitals[VITALS])(void) = { do_exit, do_exit, do_exit, do_cancel };
int inmenus[VITALS] = { MMAIN, MBROWSER, MHELP, MYESNO };
for (v = 0; v < VITALS; v++) {
for (f = allfuncs; f != NULL; f = f->next) {
for (int v = 0; v < VITALS; v++) {
for (funcstruct *f = allfuncs; f != NULL; f = f->next) {
if (f->func == vitals[v] && f->menus & inmenus[v]) {
const keystruct *s = first_sc_for(inmenus[v], f->func);
if (!s) {
@@ -1045,7 +1343,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
#ifdef ENABLE_COLOR
/* Handle extending first... */
if (!just_syntax && strcasecmp(keyword, "extendsyntax") == 0) {
if (!just_syntax && strcmp(keyword, "extendsyntax") == 0) {
augmentstruct *newitem, *extra;
char *syntaxname = ptr;
syntaxtype *sint;
@@ -1095,37 +1393,37 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
}
/* Try to parse the keyword. */
if (strcasecmp(keyword, "syntax") == 0) {
if (strcmp(keyword, "syntax") == 0) {
if (intros_only) {
check_for_nonempty_syntax();
begin_new_syntax(ptr);
} else
break;
} else if (strcasecmp(keyword, "header") == 0) {
} else if (strcmp(keyword, "header") == 0) {
if (intros_only)
grab_and_store("header", ptr, &live_syntax->headers);
} else if (strcasecmp(keyword, "magic") == 0) {
} else if (strcmp(keyword, "magic") == 0) {
#ifdef HAVE_LIBMAGIC
if (intros_only)
grab_and_store("magic", ptr, &live_syntax->magics);
#endif
} else if (just_syntax && (strcasecmp(keyword, "set") == 0 ||
strcasecmp(keyword, "unset") == 0 ||
strcasecmp(keyword, "bind") == 0 ||
strcasecmp(keyword, "unbind") == 0 ||
strcasecmp(keyword, "include") == 0 ||
strcasecmp(keyword, "extendsyntax") == 0)) {
} else if (just_syntax && (strcmp(keyword, "set") == 0 ||
strcmp(keyword, "unset") == 0 ||
strcmp(keyword, "bind") == 0 ||
strcmp(keyword, "unbind") == 0 ||
strcmp(keyword, "include") == 0 ||
strcmp(keyword, "extendsyntax") == 0)) {
if (intros_only)
jot_error(N_("Command \"%s\" not allowed in included file"),
keyword);
else
break;
} else if (intros_only && (strcasecmp(keyword, "color") == 0 ||
strcasecmp(keyword, "icolor") == 0 ||
strcasecmp(keyword, "comment") == 0 ||
strcasecmp(keyword, "tabgives") == 0 ||
strcasecmp(keyword, "linter") == 0 ||
strcasecmp(keyword, "formatter") == 0)) {
} else if (intros_only && (strcmp(keyword, "color") == 0 ||
strcmp(keyword, "icolor") == 0 ||
strcmp(keyword, "comment") == 0 ||
strcmp(keyword, "tabgives") == 0 ||
strcmp(keyword, "linter") == 0 ||
strcmp(keyword, "formatter") == 0)) {
if (!opensyntax)
jot_error(N_("A '%s' command requires a preceding "
"'syntax' command"), keyword);
@@ -1134,17 +1432,17 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
continue;
} else if (parse_syntax_commands(keyword, ptr))
;
else if (strcasecmp(keyword, "include") == 0)
else if (strcmp(keyword, "include") == 0)
parse_includes(ptr);
else
#endif /* ENABLE_COLOR */
if (strcasecmp(keyword, "set") == 0)
if (strcmp(keyword, "set") == 0)
set = 1;
else if (strcasecmp(keyword, "unset") == 0)
else if (strcmp(keyword, "unset") == 0)
set = -1;
else if (strcasecmp(keyword, "bind") == 0)
else if (strcmp(keyword, "bind") == 0)
parse_binding(ptr, TRUE);
else if (strcasecmp(keyword, "unbind") == 0)
else if (strcmp(keyword, "unbind") == 0)
parse_binding(ptr, FALSE);
else if (intros_only)
jot_error(N_("Command \"%s\" not understood"), keyword);
@@ -1168,7 +1466,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
/* Find the just parsed option name among the existing names. */
for (i = 0; rcopts[i].name != NULL; i++) {
if (strcasecmp(option, rcopts[i].name) == 0)
if (strcmp(option, rcopts[i].name) == 0)
break;
}
@@ -1212,31 +1510,31 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
argument = copy_of(argument);
#ifdef ENABLE_COLOR
if (strcasecmp(option, "titlecolor") == 0)
if (strcmp(option, "titlecolor") == 0)
color_combo[TITLE_BAR] = parse_interface_color(argument);
else if (strcasecmp(option, "numbercolor") == 0)
else if (strcmp(option, "numbercolor") == 0)
color_combo[LINE_NUMBER] = parse_interface_color(argument);
else if (strcasecmp(option, "stripecolor") == 0)
else if (strcmp(option, "stripecolor") == 0)
color_combo[GUIDE_STRIPE] = parse_interface_color(argument);
else if (strcasecmp(option, "selectedcolor") == 0)
else if (strcmp(option, "selectedcolor") == 0)
color_combo[SELECTED_TEXT] = parse_interface_color(argument);
else if (strcasecmp(option, "statuscolor") == 0)
else if (strcmp(option, "statuscolor") == 0)
color_combo[STATUS_BAR] = parse_interface_color(argument);
else if (strcasecmp(option, "errorcolor") == 0)
else if (strcmp(option, "errorcolor") == 0)
color_combo[ERROR_MESSAGE] = parse_interface_color(argument);
else if (strcasecmp(option, "keycolor") == 0)
else if (strcmp(option, "keycolor") == 0)
color_combo[KEY_COMBO] = parse_interface_color(argument);
else if (strcasecmp(option, "functioncolor") == 0)
else if (strcmp(option, "functioncolor") == 0)
color_combo[FUNCTION_TAG] = parse_interface_color(argument);
else
#endif
#ifdef ENABLE_OPERATINGDIR
if (strcasecmp(option, "operatingdir") == 0)
if (strcmp(option, "operatingdir") == 0)
operating_dir = argument;
else
#endif
#ifdef ENABLED_WRAPORJUSTIFY
if (strcasecmp(option, "fill") == 0) {
if (strcmp(option, "fill") == 0) {
if (!parse_num(argument, &fill)) {
jot_error(N_("Requested fill size \"%s\" is invalid"), argument);
fill = -COLUMNS_FROM_EOL;
@@ -1245,13 +1543,13 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
} else
#endif
#ifndef NANO_TINY
if (strcasecmp(option, "guidestripe") == 0) {
if (strcmp(option, "guidestripe") == 0) {
if (!parse_num(argument, &stripe_column) || stripe_column <= 0) {
jot_error(N_("Guide column \"%s\" is invalid"), argument);
stripe_column = 0;
}
free(argument);
} else if (strcasecmp(option, "matchbrackets") == 0) {
} else if (strcmp(option, "matchbrackets") == 0) {
if (has_blank_char(argument)) {
jot_error(N_("Non-blank characters required"));
free(argument);
@@ -1260,7 +1558,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
free(argument);
} else
matchbrackets = argument;
} else if (strcasecmp(option, "whitespace") == 0) {
} else if (strcmp(option, "whitespace") == 0) {
if (mbstrlen(argument) != 2 || breadth(argument) != 2) {
jot_error(N_("Two single-column characters required"));
free(argument);
@@ -1272,36 +1570,36 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
} else
#endif
#ifdef ENABLE_JUSTIFY
if (strcasecmp(option, "punct") == 0) {
if (strcmp(option, "punct") == 0) {
if (has_blank_char(argument)) {
jot_error(N_("Non-blank characters required"));
free(argument);
} else
punct = argument;
} else if (strcasecmp(option, "brackets") == 0) {
} else if (strcmp(option, "brackets") == 0) {
if (has_blank_char(argument)) {
jot_error(N_("Non-blank characters required"));
free(argument);
} else
brackets = argument;
} else if (strcasecmp(option, "quotestr") == 0)
} else if (strcmp(option, "quotestr") == 0)
quotestr = argument;
else
#endif
#ifndef NANO_TINY
if (strcasecmp(option, "backupdir") == 0)
if (strcmp(option, "backupdir") == 0)
backup_dir = argument;
else
if (strcasecmp(option, "wordchars") == 0)
if (strcmp(option, "wordchars") == 0)
word_chars = argument;
else
#endif
#ifdef ENABLE_SPELLER
if (strcasecmp(option, "speller") == 0)
if (strcmp(option, "speller") == 0)
alt_speller = argument;
else
#endif
if (strcasecmp(option, "tabsize") == 0) {
if (strcmp(option, "tabsize") == 0) {
if (!parse_num(argument, &tabsize) || tabsize <= 0) {
jot_error(N_("Requested tab size \"%s\" is invalid"), argument);
tabsize = -1;

View File

@@ -31,6 +31,10 @@
#include <unistd.h>
#include <sys/wait.h>
#if defined(__APPLE__) && !defined(st_mtim)
#define st_mtim st_mtimespec
#endif
#ifndef NANO_TINY
static pid_t pid_of_command = -1;
/* The PID of the forked process -- needed when wanting to abort it. */
@@ -98,7 +102,7 @@ void indent_a_line(linestruct *line, char *indentation)
/* Add the fabricated indentation to the beginning of the line. */
line->data = charealloc(line->data, length + indent_len + 1);
memmove(line->data + indent_len, line->data, length + 1);
strncpy(line->data, indentation, indent_len);
memcpy(line->data, indentation, indent_len);
openfile->totsize += indent_len;
@@ -1401,6 +1405,14 @@ bool do_wrap(void)
/* The line to be wrapped, if needed and possible. */
size_t line_len = strlen(line->data);
/* The length of this line. */
#ifdef ENABLE_JUSTIFY
size_t quot_len = quote_length(line->data);
/* The length of the quoting part of this line. */
size_t lead_len = quot_len + indent_length(line->data + quot_len);
/* The length of the quoting part plus subsequent whitespace. */
#else
size_t lead_len = indent_length(line->data);
#endif
size_t cursor_x = openfile->current_x;
/* The current cursor position, for comparison with the wrap point. */
ssize_t wrap_loc;
@@ -1411,31 +1423,28 @@ bool do_wrap(void)
/* The length of the remainder. */
/* First find the last blank character where we can break the line. */
wrap_loc = break_line(line->data, wrap_at, FALSE);
wrap_loc = break_line(line->data + lead_len,
wrap_at - wideness(line->data, lead_len), FALSE);
/* If no wrapping point was found before end-of-line, we don't wrap. */
if (wrap_loc == -1 || line->data[wrap_loc] == '\0')
if (wrap_loc < 0 || lead_len + wrap_loc == line_len)
return FALSE;
/* Step forward to the character just after the blank. */
wrap_loc = step_right(line->data, wrap_loc);
/* Adjust the wrap location to its position in the full line,
* and step forward to the character just after the blank. */
wrap_loc = lead_len + step_right(line->data + lead_len, wrap_loc);
/* When now at end-of-line, no need to wrap. */
if (line->data[wrap_loc] == '\0')
return FALSE;
#ifndef NANO_TINY
/* When autoindenting, we don't wrap right after the indentation. */
if (ISSET(AUTOINDENT) && wrap_loc == indent_length(line->data))
return FALSE;
add_undo(SPLIT_BEGIN, NULL);
#endif
#ifdef ENABLE_JUSTIFY
bool autowhite = ISSET(AUTOINDENT);
size_t lead_len = quote_length(line->data);
if (lead_len > 0)
if (quot_len > 0)
UNSET(AUTOINDENT);
#endif
@@ -1471,8 +1480,8 @@ bool do_wrap(void)
do_delete();
#ifdef ENABLE_JUSTIFY
/* If the quoting part of the current line equals the quoting part of
* what was the next line, then strip this second quoting part. */
/* If the leading part of the current line equals the leading part of
* what was the next line, then strip this second leading part. */
if (strncmp(line->data, line->data + openfile->current_x, lead_len) == 0)
for (size_t i = lead_len; i > 0; i--)
do_delete();
@@ -1503,9 +1512,7 @@ bool do_wrap(void)
#ifdef ENABLE_JUSTIFY
/* If the original line has quoting, copy it to the spillage line. */
if (lead_len > 0) {
lead_len += indent_length(line->data + lead_len);
if (quot_len > 0) {
line = line->next;
line_len = strlen(line->data);
line->data = charealloc(line->data, lead_len + line_len + 1);
@@ -1559,13 +1566,14 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl)
/* Find the last blank that does not overshoot the target column. */
while (*line != '\0' && ((ssize_t)column <= goal)) {
if (is_blank_mbchar(line) || (snap_at_nl && *line == '\n')) {
if (is_blank_mbchar(line))
lastblank = index;
if (*line == '\n')
break;
#ifdef ENABLE_HELP
else if (snap_at_nl && *line == '\n') {
lastblank = index;
break;
}
#endif
charlen = advance_over(line, &column);
line += charlen;
index += charlen;
@@ -1614,7 +1622,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl)
}
#endif /* ENABLE_HELP || ENABLED_WRAPORJUSTIFY */
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
#if !defined(NANO_TINY) || defined(ENABLED_WRAPORJUSTIFY)
/* Return the length of the indentation part of the given line. The
* "indentation" of a line is the leading consecutive whitespace. */
size_t indent_length(const char *line)
@@ -1635,7 +1643,7 @@ size_t indent_length(const char *line)
return len;
}
#endif /* !NANO_TINY || ENABLE_JUSTIFY */
#endif
#ifdef ENABLE_JUSTIFY
/* Copy a character from one place to another. */
@@ -1747,10 +1755,9 @@ bool begpar(const linestruct *const line, int depth)
if (line->prev->data[quote_len + prev_dent_len] == '\0')
return TRUE;
/* If the indentation of the preceding line equals the indentation
* of this line, this is not a BOP. */
if (prev_dent_len == indent_len && strncmp(line->prev->data + quote_len,
line->data + quote_len, indent_len) == 0)
/* If indentation of this and preceding line are equal, this is not a BOP. */
if (wideness(line->prev->data, quote_len + prev_dent_len) ==
wideness(line->data, quote_len + indent_len))
return FALSE;
/* Otherwise, this is a BOP if the preceding line is not. */
@@ -1838,7 +1845,7 @@ void rewrap_paragraph(linestruct **line, char *lead_string, size_t lead_len)
wrap_at - wideness((*line)->data, lead_len), FALSE);
/* If we can't break the line, or don't need to, we're done. */
if (break_pos == -1 || break_pos + lead_len == line_len)
if (break_pos < 0 || lead_len + break_pos == line_len)
break;
/* Adjust the breaking position for the leading part and
@@ -1852,10 +1859,9 @@ void rewrap_paragraph(linestruct **line, char *lead_string, size_t lead_len)
strncpy((*line)->next->data, lead_string, lead_len);
strcpy((*line)->next->data + lead_len, (*line)->data + break_pos);
/* When requested, snip all trailing blanks. */
/* When requested, snip the one or two trailing spaces. */
if (ISSET(TRIM_BLANKS)) {
while (break_pos > 0 &&
is_blank_mbchar(&(*line)->data[break_pos - 1]))
while (break_pos > 0 && (*line)->data[break_pos - 1] == ' ')
break_pos--;
}
@@ -2979,14 +2985,15 @@ void do_linter(void)
if (func == do_cancel || func == do_enter) {
wipe_statusbar();
break;
} else if (func == do_help_void) {
} else if (func == do_help) {
tmplint = NULL;
do_help_void();
do_help();
} else if (func == do_page_up || func == do_prev_block) {
if (curlint->prev != NULL)
curlint = curlint->prev;
else if (last_wait != time(NULL)) {
statusbar(_("At first message"));
beep();
napms(600);
last_wait = time(NULL);
statusline(NOTICE, curlint->msg);
@@ -2996,6 +3003,7 @@ void do_linter(void)
curlint = curlint->next;
else if (last_wait != time(NULL)) {
statusbar(_("At last message"));
beep();
napms(600);
last_wait = time(NULL);
statusline(NOTICE, curlint->msg);

View File

@@ -658,7 +658,8 @@ int parse_kbinput(WINDOW *win)
#ifndef NANO_TINY
/* When <Tab> is pressed while the mark is on, do an indent. */
if (retval == TAB_CODE && openfile->mark && currmenu == MMAIN)
if (retval == TAB_CODE && openfile->mark && currmenu == MMAIN &&
openfile->mark != openfile->current)
return INDENT_KEY;
#endif
@@ -2403,11 +2404,12 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col)
wattron(edit, interface_color_pair[LINE_NUMBER]);
#ifndef NANO_TINY
if (ISSET(SOFTWRAP) && from_col != 0)
mvwprintw(edit, row, 0, "%*s", margin, " ");
mvwprintw(edit, row, 0, "%*s", margin - 1, " ");
else
#endif
mvwprintw(edit, row, 0, "%*zd ", margin - 1, line->lineno);
mvwprintw(edit, row, 0, "%*zd", margin - 1, line->lineno);
wattroff(edit, interface_color_pair[LINE_NUMBER]);
wprintw(edit, " ");
}
#endif
@@ -3118,14 +3120,14 @@ size_t chunk_for(size_t column, linestruct *line)
* column is on. */
size_t leftedge_for(size_t column, linestruct *line)
{
size_t leftedge;
if (ISSET(SOFTWRAP)) {
size_t leftedge;
if (!ISSET(SOFTWRAP))
get_chunk_and_edge(column, line, &leftedge);
return leftedge;
} else
return 0;
get_chunk_and_edge(column, line, &leftedge);
return leftedge;
}
/* Return the row of the last softwrapped chunk of the given line, relative to

View File

@@ -4,7 +4,7 @@
syntax nanohelp
# Key combos:
color cyan "\^[]4-8A-Z^\_◀▶▲▼]" "[◀▶▲▼]" "\<M-." "\<F1?[0-9]"
color cyan "\^[]/4-8A-Z\^_◀▶▲▼]" "[◀▶▲▼]" "\<M-." "\<F([1-9]|1[0-9]|2[0-4])"
color cyan "\<((Sh-)?Tab|Enter|Ins|(Sh-\^?)?Del|Space|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
# Quoted indicators:

View File

@@ -1,6 +1,6 @@
## Here is an example for Bourne shell scripts.
syntax sh "(\.sh|\.(a|ba|c|da|k|mk|pdk|tc|z)(sh|shrc|sh_profile)|/(etc/|\.)profile)$"
syntax sh "(\.sh|(\.|/)(a|ba|c|da|k|mk|pdk|tc|z)sh(rc|_profile)?|/(etc/|\.)profile)$"
header "^#!.*/(((a|ba|c|da|k|mk|pdk|tc|z)?sh)|(busybox|env) +sh|openrc-run|runscript)"
magic "(POSIX|Bourne-Again) shell script.*text"
comment "#"