Compare commits
113 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e92c3110a1 | ||
|
|
1ca9241eaa | ||
|
|
0b6889cbd8 | ||
|
|
00410d83fc | ||
|
|
fcad442d80 | ||
|
|
34d22d3f00 | ||
|
|
1326af7eae | ||
|
|
11aa191bdc | ||
|
|
ea844d28fe | ||
|
|
7668bfe6f2 | ||
|
|
493f215513 | ||
|
|
723451a5ce | ||
|
|
326e41d799 | ||
|
|
3ce74eb8fe | ||
|
|
ec4883b6a9 | ||
|
|
e8f69e40d1 | ||
|
|
297fb013cb | ||
|
|
4e52c75568 | ||
|
|
192a303e40 | ||
|
|
dcec8a4112 | ||
|
|
5316f5078f | ||
|
|
286c877853 | ||
|
|
8613285321 | ||
|
|
8a4639cdd6 | ||
|
|
576c20c4e4 | ||
|
|
3a0a6b5db8 | ||
|
|
c039aaad9d | ||
|
|
145bb6e01a | ||
|
|
9cc70d2069 | ||
|
|
3604ad2950 | ||
|
|
1fe3e2ed69 | ||
|
|
baca8bb19e | ||
|
|
1c707d4f99 | ||
|
|
c0e3779453 | ||
|
|
bf6bcde078 | ||
|
|
167a8e5c09 | ||
|
|
90cbdbbe75 | ||
|
|
d83a8eb359 | ||
|
|
98cc39e8e5 | ||
|
|
b20fadd604 | ||
|
|
cdf0f8e68a | ||
|
|
f645009a5e | ||
|
|
2b2736d41a | ||
|
|
5a6029a938 | ||
|
|
8d272db4e6 | ||
|
|
70885d0f9a | ||
|
|
f1e5da6cdd | ||
|
|
d79b9823ae | ||
|
|
82f1ce8ebf | ||
|
|
50ee655f9d | ||
|
|
5459f56f6d | ||
|
|
209531a761 | ||
|
|
2552307064 | ||
|
|
5601b9a66b | ||
|
|
81dcb13783 | ||
|
|
580fd13424 | ||
|
|
790ce3791a | ||
|
|
97cd62a8fb | ||
|
|
2f68bbb5e8 | ||
|
|
55952c0984 | ||
|
|
d9cfdd364b | ||
|
|
c9605e7308 | ||
|
|
c3f97bc9b7 | ||
|
|
4399b734db | ||
|
|
b9581bd50a | ||
|
|
408f15954e | ||
|
|
f585403b36 | ||
|
|
601973ddc2 | ||
|
|
25a5fb8231 | ||
|
|
897e557ce3 | ||
|
|
81bee1f5fd | ||
|
|
691eb1145c | ||
|
|
fb04dff6d7 | ||
|
|
c224ea3ce7 | ||
|
|
2a2fe7208a | ||
|
|
3f9d8011b9 | ||
|
|
4788c5f97d | ||
|
|
a5869ba450 | ||
|
|
7bc324f276 | ||
|
|
8d40b568fa | ||
|
|
0c0afb0039 | ||
|
|
2281ec9a31 | ||
|
|
cd0917fe10 | ||
|
|
1a1519b6cd | ||
|
|
947ccbb597 | ||
|
|
671db5e1e3 | ||
|
|
acfee2538e | ||
|
|
32431cddf8 | ||
|
|
8e302738e8 | ||
|
|
aa2568858e | ||
|
|
5375403b9d | ||
|
|
b0c9809a2e | ||
|
|
19c82e6a43 | ||
|
|
84d21b0972 | ||
|
|
f8e0320722 | ||
|
|
e5a8c35104 | ||
|
|
7ad232d714 | ||
|
|
85804ec70d | ||
|
|
e473ba5e6c | ||
|
|
9120a62cdd | ||
|
|
53ecb3225f | ||
|
|
3f695b8fb7 | ||
|
|
55699dc171 | ||
|
|
fa48d523b2 | ||
|
|
92cbc7c426 | ||
|
|
6f07f2b444 | ||
|
|
f58869d072 | ||
|
|
978c121de1 | ||
|
|
f6a7983a8a | ||
|
|
a1375474d9 | ||
|
|
d0cc75f197 | ||
|
|
0fccfc0373 | ||
|
|
d0a7e6e6a6 |
129
ChangeLog
129
ChangeLog
@@ -1,3 +1,132 @@
|
||||
Changes between v4.1 and v4.2:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (23):
|
||||
build: be more specific and avoid committing accidentally changed files
|
||||
bump version numbers and add a news item for the 4.2 release
|
||||
docs: put the 'set guidestripe' option into its alphabetical position
|
||||
options: make --breaklonglines work also when --ignorercfiles is used
|
||||
speller: do not crash by trying to free something that cannot be freed
|
||||
tweaks: adjust a few comments and some indentation
|
||||
tweaks: condense and improve a handful of comments
|
||||
tweaks: declare a function as const and let its allocated string leak
|
||||
tweaks: drop an unneeded saving and restoring of a variable
|
||||
tweaks: elide an unneeded intermediate variable
|
||||
tweaks: elide an unneeded parameter, as the function already assumes it
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: exclude a bit more code from a single-buffer build
|
||||
tweaks: remove an unneeded condition
|
||||
tweaks: remove a redundant, enclosed #ifdef
|
||||
tweaks: rename a function, to be distinct and fitting
|
||||
tweaks: rename another function, to be distinct and fitting
|
||||
tweaks: rename a variable, for a little more meaning
|
||||
tweaks: rename a variable, to distinguish it from a browser function
|
||||
wrapping: add a missing space only when the remainder will be prepended
|
||||
wrapping: compute the width of a succeeding line in the correct manner
|
||||
wrapping: improve the persistence of the prepending behavior
|
||||
wrapping: trim any trailing blanks when cursor goes to next line
|
||||
|
||||
|
||||
Changes between v4.0 and v4.1:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (85):
|
||||
bindings: add easier keystrokes for the linenumber and softwrap toggles
|
||||
bindings: disallow executing an external command when in view mode
|
||||
bindings: recognize the ^W^Y and ^W^V legacy keystrokes again
|
||||
bindings: remove the jumpy-scrolling toggle entirely
|
||||
build: add gnulib modules to the list of files with translatable strings
|
||||
build: add src/cut.c to the list of files with translatable strings
|
||||
build: don't do fuzzy matching when merging PO files against the POT file
|
||||
build: remove obsolete translations from the PO files after merging
|
||||
bump version numbers and add a news item for the 4.1 release
|
||||
display: report and catch a bad state, to prevent a possible hang
|
||||
docs: for two of the toggles, mention the new instead of the old option
|
||||
docs: give the FILES section in the man page its canonical title
|
||||
docs: mention that -b is the opposite of -w also in the latter's item
|
||||
docs: mention that M-S now toggles softwrap and M-N line numbers
|
||||
docs: put paths and filenames in italics, per 'man man-pages'
|
||||
docs: remove all mention of --finalnewline, and undefault --nonewlines
|
||||
docs: remove the AUTHOR section, per advice from 'man man-pages'
|
||||
docs: re-title the temporary section about the changed defaults
|
||||
feedback: replace an assert with a check plus error message at startup
|
||||
feedback: show a message while executing an external command
|
||||
feedback: spare the user a superfluous scaring when trying to exit
|
||||
gnulib: update to its current upstream state
|
||||
help: don't doubly list toggles that have two keys assigned to them
|
||||
indenting, commenting: ensure a partial line stays displayed properly
|
||||
justify: correctly compute the number of lines to take, to avoid a crash
|
||||
options: make --nowrap override again a contrary nanorc setting
|
||||
options: remove -f (--finalnewline); go back to auto-adding this newline
|
||||
rcfile: don't break a chain of 'else if' [scan-build]
|
||||
rcfile: read the syntax files in alphabetical order when globbing
|
||||
speller: block the resizing signal again during an external spell check
|
||||
speller: block the resizing signal also during an integrated spell check
|
||||
speller: resizing can happen also when configured with --enable-tiny
|
||||
syntax: c: color as a type any lowercase word that ends with "_t"
|
||||
syntax: default: color in red also versions 4.x of nano
|
||||
syntax: man: add comments, and color all the safe lowercase macros
|
||||
syntax: man: anchor macros at start of line, as only then they are valid
|
||||
syntax: man: require the dot to be at start of line, not the comment
|
||||
syntax: nanorc: colorize also strings preceded by 'start=' or 'end='
|
||||
syntax: nanorc: require whitespace both before and after a quoted string
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: condense a bit of copying code
|
||||
tweaks: consistently use .sp instead of .PP to insert a blank line
|
||||
tweaks: do a check up front instead of every time round the loop
|
||||
tweaks: don't bother copying the NUL byte -- it is set nine lines down
|
||||
tweaks: don't bother reallocating the data when a line gets hard-wrapped
|
||||
tweaks: don't bother reallocating the squeezed string, just terminate it
|
||||
tweaks: don't bother special-casing non-UTF8 when seeking a character
|
||||
tweaks: drop an assignment whose value is never used [scan-build]
|
||||
tweaks: drop two 'const' qualifiers, to silence the compiler
|
||||
tweaks: free some memory before a possible error exit [coverity]
|
||||
tweaks: free the copy of a linter message in all cases [valgrind]
|
||||
tweaks: free the result string from an invocation error [coverity]
|
||||
tweaks: initialize a boolean before it is referenced [valgrind]
|
||||
tweaks: put the unblocking of SIGWINCHes in a better place
|
||||
tweaks: remove a function that is now unused
|
||||
tweaks: remove an unneeded check for NULL and its associated message
|
||||
tweaks: remove an unneeded check for NULL [coverity]
|
||||
tweaks: remove an unpaired closing parenthesis from the NEWS file
|
||||
tweaks: remove a superfluous check for NULL plus the associated message
|
||||
tweaks: remove several unneeded bad-state checks and their messages
|
||||
tweaks: rename a cryptic type to something that makes a little sense
|
||||
tweaks: rename a function plus parameter, to stay closer to what it does
|
||||
tweaks: rename another variable, to be more descriptive
|
||||
tweaks: rename another variable, to be more fitting
|
||||
tweaks: rename an overshort type to something that makes some sense
|
||||
tweaks: rename a variable, to be more distinct and more apt
|
||||
tweaks: rename a variable, to be more distinct and more descriptive
|
||||
tweaks: rename a variable, to get out of the way for another rename
|
||||
tweaks: rename some variables, for more contrast and to match others
|
||||
tweaks: rename some variables, to be less repititious
|
||||
tweaks: rename two variables, for more contrast
|
||||
tweaks: rename two variables, to be more distinct and more fitting
|
||||
tweaks: rename two variables, to make more sense
|
||||
tweaks: rename two variables, to match others
|
||||
tweaks: reshuffle some lines, condense a comment and drop another
|
||||
tweaks: reshuffle some lines, to elide an 'if'
|
||||
tweaks: reshuffle two lines, and reword a comment
|
||||
tweaks: reword a comment, and drop an unneeded assert
|
||||
tweaks: shorten a comment to its essence
|
||||
tweaks: shorten and improve some comments, and reshuffle a few lines
|
||||
tweaks: simplify a message, and normalize the spelling of another one
|
||||
tweaks: stop doing tandem assignments (one passing through the other)
|
||||
tweaks: switch back from checking FINAL_NEWLINE to checking NO_NEWLINES
|
||||
tweaks: use a signed type for a result that could be negative [coverity]
|
||||
unindent: ensure that a partial line gets displayed properly afterwards
|
||||
|
||||
Brand Huntsman (1):
|
||||
files: block the resizing signal while reading from an external command
|
||||
|
||||
Devin Hussey (1):
|
||||
files: initialize a variable before referencing it
|
||||
|
||||
Liu Hao (1):
|
||||
syntax: c: change the highlighting of preprocessor directives
|
||||
|
||||
|
||||
Changes between v3.2 and v4.0:
|
||||
------------------------------
|
||||
|
||||
|
||||
26
NEWS
26
NEWS
@@ -1,3 +1,23 @@
|
||||
2019.04.24 - GNU nano 4.2 "Tax the rich, pay the teachers"
|
||||
• The integrated spell checker does not crash when 'spell' is missing.
|
||||
• Option --breaklonglines works also when --ignorercfiles is used.
|
||||
• Automatic hard-wrapping is more persistent in pushing words to the
|
||||
same overflow line.
|
||||
|
||||
2019.04.15 - GNU nano 4.1 "Qué corchos será eso?"
|
||||
• By default, a newline character is again automatically added at the
|
||||
end of a buffer, to produce valid POSIX text files by default, but
|
||||
also to get back the easy adding of text at the bottom.
|
||||
• The now unneeded option --finalnewline (-f) has been removed.
|
||||
• Syntax files are read in alphabetical order when globbing, so that
|
||||
the precedence of syntaxes becomes predictable.
|
||||
• In the C syntax, preprocessor directives are highlighted differently.
|
||||
• M-S now toggles soft wrapping, and M-N toggles line numbers.
|
||||
• The jumpy-scrolling toggle has been removed.
|
||||
• The legacy keystrokes ^W^Y and ^W^V are recognized again.
|
||||
• Executing an external command is disallowed when in view mode.
|
||||
• Problems with resizing during external or speller commands were fixed.
|
||||
|
||||
2019.03.24 - GNU nano 4.0 "Thy Rope of Sands"
|
||||
• An overlong line is no longer automatically hard-wrapped.
|
||||
• Smooth scrolling (one line at a time) has become the default.
|
||||
@@ -13,7 +33,7 @@
|
||||
• Option --guidestripe=<number> draws a vertical bar at the given column.
|
||||
• Option --fill=<number> no longer turns on automatic hard-wrapping.
|
||||
• When a line continues offscreen, it now ends with a highlighted ">".
|
||||
• The halfs of a split two-column character are shown as "[" and "]".
|
||||
• The halves of a split two-column character are shown as "[" and "]".
|
||||
• A line now scrolls horizontally one column earlier.
|
||||
• The bindable functions 'cutwordleft' and 'cutwordright' were renamed
|
||||
to 'chopwordleft' and 'chopwordright' as they don't use the cutbuffer.
|
||||
@@ -670,8 +690,8 @@
|
||||
without the usual truncation and a '$' symbol at the end
|
||||
of the line. It can be enabled via Meta-$ inside the
|
||||
editor, via the -$ or --softwrap command-line flags,
|
||||
or "set softwrap" in your .nanorc). As always, please
|
||||
report any bugs to the nano Savannah project page
|
||||
or via "set softwrap" in your .nanorc. As always,
|
||||
please report any bugs to the nano Savannah project page
|
||||
(http://savannah.gnu.org/bugs/?func=additem&group=nano)
|
||||
Remember: data loss happens, back up your files.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="69c4509f33c6a6ac159f3429d4150bf119ac4d76"
|
||||
gnulib_hash="91584ed612fa26a505c8fc4c7f6fb19f7413795d"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
@@ -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.0], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [4.2], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.14])
|
||||
|
||||
@@ -85,7 +85,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 "establishes a full duplex terminal connection to a remote host", 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.0</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.2</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%">
|
||||
|
||||
49
doc/nano.1
49
doc/nano.1
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 4.0" "March 2019"
|
||||
.TH NANO 1 "version 4.2" "April 2019"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, inspired by Pico
|
||||
@@ -25,15 +25,13 @@ nano \- Nano's ANOther editor, inspired by Pico
|
||||
.B nano
|
||||
.RI [ options "] [[+" line [, column "]]\ " file "]..."
|
||||
|
||||
.SH NOTE
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
line by default, and no longer automatically adds a newline at the end
|
||||
of the text if one is missing. Furthermore, it uses smooth scrolling
|
||||
by default and makes use of the line below the title bar.
|
||||
line by default, uses smooth scrolling by default, and by default makes
|
||||
use of the line below the title bar.
|
||||
.sp
|
||||
If you want the old, Pico behavior back, you can use \fB\-\-breaklonglines\fR,
|
||||
\fB\-\-finalnewline\fR, \fB\-\-jumpyscrolling\fR, and \fB\-\-emptyline\fR
|
||||
(or \fB\-bfje\fR for short).
|
||||
\fB\-\-jumpyscrolling\fR, and \fB\-\-emptyline\fR (or \fB\-bje\fR for short).
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBnano\fP is a small and friendly editor. It copies the look and feel
|
||||
@@ -57,18 +55,18 @@ Consecutive \fB^K\fRs will put all deleted lines together in the cutbuffer.
|
||||
Any cursor movement or executing any other command will cause the next
|
||||
\fB^K\fR to overwrite the cutbuffer. A \fB^U\fR will paste the current
|
||||
contents of the cutbuffer at the current cursor position.
|
||||
.PP
|
||||
.sp
|
||||
When a more precise piece of text needs to be cut or copied, one can mark
|
||||
its start with \fB^6\fR, move the cursor to its end (the marked text will be
|
||||
highlighted), and then use \fB^K\fR to cut it, or \fBM\-6\fR to copy it to the
|
||||
cutbuffer. One can also save the marked text to a file with \fB^O\fR, or
|
||||
spell check it with \fB^T\fR.
|
||||
.PP
|
||||
.sp
|
||||
On some terminals, text can be selected also by holding down Shift while
|
||||
using the arrow keys. Holding down the Ctrl or Alt key too will increase
|
||||
the stride.
|
||||
Any cursor movement without Shift being held will cancel such a selection.
|
||||
.PP
|
||||
.sp
|
||||
The two lines at the bottom of the screen show some important commands;
|
||||
the built-in help (\fB^G\fR) lists all the available ones.
|
||||
The default key bindings can be changed via a \fInanorc\fR file -- see
|
||||
@@ -124,7 +122,6 @@ mouse support.
|
||||
.TP
|
||||
.BR \-L ", " \-\-nonewlines
|
||||
Don't automatically add a newline when a file does not end with one.
|
||||
(This is the default.)
|
||||
.TP
|
||||
.BR \-M ", " \-\-trimblanks
|
||||
Snip trailing whitespace from the wrapped line when automatic
|
||||
@@ -213,11 +210,6 @@ system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
.BR \-e ", " \-\-emptyline
|
||||
Do not use the line below the title bar, leaving it entirely blank.
|
||||
.TP
|
||||
.BR \-f ", " \-\-finalnewline
|
||||
If the buffer is not empty, ensure that it ends with a newline character.
|
||||
(This option is the opposite of \fB\-L\fR (\fB\-\-nonewlines\fR) --
|
||||
the last one given takes effect.)
|
||||
.TP
|
||||
.BR \-g ", " \-\-showcursor
|
||||
Make the cursor visible in the file browser (putting it on the
|
||||
highlighted item) and in the help viewer. Useful for braille users
|
||||
@@ -288,7 +280,9 @@ unless \fB\-\-restricted\fR is given too.
|
||||
.TP
|
||||
.BR \-w ", " \-\-nowrap
|
||||
Do not automatically hard-wrap the current line when it becomes overlong.
|
||||
(This is the default.)
|
||||
This is the default. (This option is the opposite of \fB\-b\fR
|
||||
(\fB\-\-breaklonglines\fR) -- the last one given takes effect.)
|
||||
|
||||
.TP
|
||||
.BR \-x ", " \-\-nohelp
|
||||
Don't show the two help lines at the bottom of the screen.
|
||||
@@ -310,16 +304,16 @@ separately (e.g.\& 'nano \-wS \-$').
|
||||
.SH TOGGLES
|
||||
Several of the above options can be switched on and off also while
|
||||
\fBnano\fR is running. For example, \fBM\-L\fR toggles the
|
||||
hard-wrapping of long lines, \fBM\-$\fR toggles soft-wrapping,
|
||||
\fBM\-#\fR toggles line numbers, \fBM\-M\fR toggles the mouse,
|
||||
hard-wrapping of long lines, \fBM\-S\fR toggles soft-wrapping,
|
||||
\fBM\-N\fR toggles line numbers, \fBM\-M\fR toggles the mouse,
|
||||
\fBM\-I\fR auto-indentation, and \fBM\-X\fR the help lines.
|
||||
See at the end of the \fB^G\fR help text for a complete list.
|
||||
|
||||
.SH INITIALIZATION FILE
|
||||
.SH FILES
|
||||
\fBnano\fR will read two configuration files: first the system's
|
||||
\fInanorc\fR (if it exists), and then the user's \fInanorc\fR (if it
|
||||
exists), either \fB~/.nanorc\fR or \fI$XDG_CONFIG_HOME\fB/nano/nanorc\fR
|
||||
or \fB~/.config/nano/nanorc\fR, whichever is encountered first. See
|
||||
exists), either \fI~/.nanorc\fR or \fI$XDG_CONFIG_HOME/nano/nanorc\fR
|
||||
or \fI~/.config/nano/nanorc\fR, whichever is encountered first. See
|
||||
.BR nanorc (5)
|
||||
for more information on the possible contents of those files.
|
||||
|
||||
@@ -345,21 +339,16 @@ not by default distinguish modified from unmodified arrow keys.
|
||||
.sp
|
||||
Please report any other bugs that you encounter via:
|
||||
.br
|
||||
\fIhttps://savannah.gnu.org/bugs/?group=nano\fR.
|
||||
.IR https://savannah.gnu.org/bugs/?group=nano .
|
||||
.sp
|
||||
When nano crashes, it will save any modified buffers to emergency .save files.
|
||||
If you are able to reproduce the crash and you want to get a backtrace, define
|
||||
the environment variable \fBNANO_NOCATCH\fR.
|
||||
|
||||
.SH HOMEPAGE
|
||||
\fIhttps://nano\-editor.org/\fR
|
||||
.I https://nano\-editor.org/
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR nanorc (5)
|
||||
.PP
|
||||
.sp
|
||||
\fI/usr/share/doc/nano/\fP (or equivalent on your system)
|
||||
|
||||
.SH AUTHOR
|
||||
Chris Allegretta and others (see the files \fIAUTHORS\fR and
|
||||
\fITHANKS\fP for details). This manual page was originally written by
|
||||
Jordi Mallach for the Debian system (but may be used by others).
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 4.0
|
||||
@set UPDATED March 2019
|
||||
@set VERSION 4.2
|
||||
@set UPDATED April 2019
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 4.0
|
||||
@subtitle version 4.2
|
||||
|
||||
@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.0.
|
||||
This manual documents the GNU @command{nano} editor, version 4.2.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@@ -97,14 +97,13 @@ as is reasonable while offering a superset of Pico's functionality.
|
||||
Pico differ.
|
||||
|
||||
Starting with version 4.0, @command{nano} no longer hard-wraps an overlong
|
||||
line by default, and no longer automatically adds a newline at the end
|
||||
of the text if one is missing. Furthermore, it uses smooth scrolling
|
||||
by default and makes use of the line below the title bar.
|
||||
line by default, uses smooth scrolling by default, and by default makes
|
||||
use of the line below the title bar.
|
||||
|
||||
If you want the old, Pico behavior back, you can use the
|
||||
following options: @option{--breaklonglines}, @option{--finalnewline},
|
||||
following options: @option{--breaklonglines},
|
||||
@option{--jumpyscrolling}, and @option{--emptyline}
|
||||
(or @option{-bfje} for short).
|
||||
(or @option{-bje} for short).
|
||||
|
||||
Please report bugs via @url{https://savannah.gnu.org/bugs/?group=nano}.
|
||||
|
||||
@@ -216,7 +215,6 @@ mouse support.
|
||||
@item -L
|
||||
@itemx --nonewlines
|
||||
Don't automatically add a newline when a file does not end with one.
|
||||
(This is the default.)
|
||||
|
||||
@item -M
|
||||
@itemx --trimblanks
|
||||
@@ -325,12 +323,6 @@ system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
@itemx --emptyline
|
||||
Do not use the line below the title bar, leaving it entirely blank.
|
||||
|
||||
@item -f
|
||||
@itemx --finalnewline
|
||||
If the buffer is not empty, ensure that it ends with a newline character.
|
||||
(This option is the opposite of @option{-L} (@option{--nonewlines}) ---
|
||||
the last one given takes effect.)
|
||||
|
||||
@item -g
|
||||
@itemx --showcursor
|
||||
Make the cursor visible in the file browser (putting it on the
|
||||
@@ -426,7 +418,9 @@ file permissions to implement a read-only file.)
|
||||
@item -w
|
||||
@itemx --nowrap
|
||||
Do not automatically hard-wrap the current line when it becomes overlong.
|
||||
(This is the default.)
|
||||
This is the default. (This option is the opposite of @option{-b}
|
||||
(@option{--breaklonglines}) --- the last one given takes effect.)
|
||||
|
||||
|
||||
@anchor{Expert Mode}
|
||||
@item -x
|
||||
@@ -643,19 +637,22 @@ The following global toggles are available:
|
||||
@kbd{Meta-K} toggles the @option{-k} (@option{--cutfromcursor}) command-line option.
|
||||
|
||||
@item Long-Line Wrapping
|
||||
@kbd{Meta-L} toggles the @option{-w} (@option{--nowrap}) command-line option.
|
||||
@kbd{Meta-L} toggles the @option{-b} (@option{--breaklonglines}) command-line option.
|
||||
|
||||
@item Mouse Support
|
||||
@kbd{Meta-M} toggles the @option{-m} (@option{--mouse}) command-line option.
|
||||
|
||||
@item Line Numbers
|
||||
@kbd{Meta-N} toggles the @option{-l} (@option{--linenumbers}) command-line option.
|
||||
|
||||
@item Tabs To Spaces
|
||||
@kbd{Meta-O} toggles the @option{-E} (@option{--tabstospaces}) command-line option.
|
||||
|
||||
@item Whitespace Display
|
||||
@kbd{Meta-P} toggles the displaying of whitespace (@pxref{Whitespace}).
|
||||
|
||||
@item Smooth Scrolling
|
||||
@kbd{Meta-S} toggles the @option{-S} (@option{--smooth}) command-line option.
|
||||
@item Soft Wrapping
|
||||
@kbd{Meta-S} toggles the @option{-$} (@option{--softwrap}) command-line option.
|
||||
|
||||
@item Expert/No Help
|
||||
@kbd{Meta-X} toggles the @option{-x} (@option{--nohelp}) command-line option.
|
||||
@@ -667,12 +664,6 @@ The following global toggles are available:
|
||||
@item Suspension
|
||||
@kbd{Meta-Z} toggles the @option{-z} (@option{--suspend}) command-line option.
|
||||
|
||||
@item Line Numbers
|
||||
@kbd{Meta-#} toggles the @option{-l} (@option{--linenumbers}) command-line option.
|
||||
|
||||
@item Soft Wrapping
|
||||
@kbd{Meta-$} toggles the @option{-$} (@option{--softwrap}) command-line option.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@@ -776,9 +767,6 @@ Do not use the line below the title bar, leaving it entirely blank.
|
||||
Use this color combination for the status bar when an error message is displayed.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set finalnewline
|
||||
If the buffer is not empty, ensure that it ends with a newline character.
|
||||
|
||||
@item set fill @var{number}
|
||||
Set the target width for justifying and automatic hard-wrapping at this
|
||||
@var{number} of columns. If the value is 0 or less, wrapping will occur
|
||||
@@ -797,6 +785,10 @@ Valid names for foreground and background color are:
|
||||
The name of the foreground color may be prefixed with @code{bright}.
|
||||
And either @var{fgcolor} or ,@var{bgcolor} may be left out.
|
||||
|
||||
@item set guidestripe @var{number}
|
||||
Draw a vertical stripe at the given column, to help judge the width of the
|
||||
text. (The color of the stripe can be changed with @code{set stripecolor}.)
|
||||
|
||||
@item set historylog
|
||||
Save the last hundred search strings and replacement strings and
|
||||
executed commands, so they can be easily reused in later sessions.
|
||||
@@ -815,10 +807,6 @@ Display line numbers to the left of the text area.
|
||||
@item set locking
|
||||
Enable vim-style lock-files for when editing files.
|
||||
|
||||
@item set guidestripe @var{number}
|
||||
Draw a vertical stripe at the given column, to help judge the width of the
|
||||
text. (The color of the stripe can be changed with @code{set stripecolor}.)
|
||||
|
||||
@item set matchbrackets "@var{string}"
|
||||
Set the opening and closing brackets that can be found by bracket
|
||||
searches. This may not include blank characters. The opening set must
|
||||
@@ -843,8 +831,7 @@ Don't convert files from DOS/Mac format.
|
||||
Don't display the help lists at the bottom of the screen.
|
||||
|
||||
@item set nonewlines
|
||||
Deprecated option since it has become the default setting.
|
||||
When needed, use @code{unset finalnewline} instead.
|
||||
Don't automatically add a newline when a file does not end with one.
|
||||
|
||||
@item set nopauses
|
||||
Don't pause between warnings at startup. This means that only
|
||||
@@ -1442,9 +1429,6 @@ Toggles the presence of the two-line list of key bindings at the bottom of the s
|
||||
@item constantshow
|
||||
Toggles the constant display of the current line, column, and character positions.
|
||||
|
||||
@item smoothscroll
|
||||
Toggles smooth scrolling (when moving around with the arrow keys).
|
||||
|
||||
@item softwrap
|
||||
Toggles the displaying of overlong lines on multiple screen lines.
|
||||
|
||||
@@ -1576,12 +1560,6 @@ switched on with the @option{--breaklonglines} option. With that option,
|
||||
whereas Pico does it at screen width minus six columns. You can make
|
||||
@command{nano} do as Pico by using @option{--fill=-6}.
|
||||
|
||||
@item Magic Newline
|
||||
Pico ensures that any text always ends with a newline character.
|
||||
Nano does not do this by default: the user is left in full control
|
||||
of the formatting. You can get the automatic newline by using the
|
||||
@option{--finalnewline} option.
|
||||
|
||||
@item Scrolling
|
||||
By default, @command{nano} will scroll just one line (instead of half
|
||||
a screen) when the cursor is moved to a line that is just out of view.
|
||||
|
||||
55
doc/nanorc.5
55
doc/nanorc.5
@@ -16,28 +16,27 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 4.0" "March 2019"
|
||||
.TH NANORC 5 "version 4.2" "April 2019"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
|
||||
.SH NOTE
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
line by default, and no longer automatically adds a newline at the end
|
||||
of the text if one is missing. Furthermore, it uses smooth scrolling
|
||||
by default and makes use of the line below the title bar.
|
||||
line by default, uses smooth scrolling by default, and by default makes
|
||||
use of the line below the title bar.
|
||||
.sp
|
||||
If you want the old, Pico behavior back, you can use \fBset breaklonglines\fR,
|
||||
\fBset finalnewline\fR, \fBset jumpyscrolling\fR, and \fBset emptyline\fR.
|
||||
\fBset jumpyscrolling\fR, and \fBset emptyline\fR.
|
||||
|
||||
.SH DESCRIPTION
|
||||
The \fInanorc\fP file contains the default settings for \fBnano\fP, a
|
||||
small and friendly editor. The file should be in Unix format, not in
|
||||
DOS or Mac format. During startup, \fBnano\fP will first read the
|
||||
system-wide settings, from \fB/etc/nanorc\fP (the exact path might be
|
||||
system-wide settings, from \fI/etc/nanorc\fP (the exact path might be
|
||||
different on your system), and then the user-specific settings, either
|
||||
from \fB~/.nanorc\fR or from \fI$XDG_CONFIG_HOME\fB/nano/nanorc\fR
|
||||
or from \fB~/.config/nano/nanorc\fR, whichever is encountered first.
|
||||
from \fI~/.nanorc\fR or from \fI$XDG_CONFIG_HOME/nano/nanorc\fR
|
||||
or from \fI~/.config/nano/nanorc\fR, whichever is encountered first.
|
||||
|
||||
.SH OPTIONS
|
||||
The configuration file accepts a series of \fBset\fP and \fBunset\fP
|
||||
@@ -45,20 +44,20 @@ 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.
|
||||
.PP
|
||||
.sp
|
||||
Options in \fInanorc\fP files take precedence over nano's defaults, and
|
||||
command-line options override \fInanorc\fP settings. Also, options that
|
||||
do not take an argument are unset by default. So using the \fBunset\fR
|
||||
command is only needed when wanting to override a setting of the system's
|
||||
\fInanorc\fR file in your own \fInanorc\fR. Options that take an
|
||||
argument cannot be unset.
|
||||
.PP
|
||||
.sp
|
||||
Below, the \fIstring\fR parameters need to be enclosed in double quotes.
|
||||
Quotes inside these string parameters don't have to be escaped with
|
||||
backslashes. The last double quote in the string will be treated as its
|
||||
end. For example, for the \fBbrackets\fP option, "\fB"')>]}\fP" will
|
||||
match \fB"\fP, \fB'\fP, \fB)\fP, \fB>\fP, \fB]\fP, and \fB}\fP.
|
||||
.PP
|
||||
.sp
|
||||
The supported commands and arguments are:
|
||||
|
||||
.TP 3
|
||||
@@ -121,9 +120,6 @@ Do not use the line below the title bar, leaving it entirely blank.
|
||||
Use this color combination for the status bar when an error message is displayed.
|
||||
See \fBset titlecolor\fR for valid color names.
|
||||
.TP
|
||||
.B set finalnewline
|
||||
If the buffer is not empty, ensure that it ends with a newline character.
|
||||
.TP
|
||||
.B set fill \fInumber\fR
|
||||
Set the target width for justifying and automatic hard-wrapping at this
|
||||
\fInumber\fR of columns. If the value is 0 or less, wrapping will occur
|
||||
@@ -136,6 +132,10 @@ Specify the color combination to use for the function descriptions
|
||||
in the two help lines at the bottom of the screen.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.B set guidestripe \fInumber
|
||||
Draw a vertical stripe at the given column, to help judge the width of the
|
||||
text. (The color of the stripe can be changed with \fBset stripecolor\fR.)
|
||||
.TP
|
||||
.B set historylog
|
||||
Save the last hundred search strings and replacement strings and
|
||||
executed commands, so they can be easily reused in later sessions.
|
||||
@@ -154,10 +154,6 @@ Display line numbers to the left of the text area.
|
||||
.B set locking
|
||||
Enable vim-style lock-files for when editing files.
|
||||
.TP
|
||||
.B set guidestripe \fInumber
|
||||
Draw a vertical stripe at the given column, to help judge the width of the
|
||||
text. (The color of the stripe can be changed with \fBset stripecolor\fR.)
|
||||
.TP
|
||||
.B set matchbrackets "\fIstring\fP"
|
||||
Set the opening and closing brackets that can be found by bracket
|
||||
searches. This may not include blank characters. The opening set must
|
||||
@@ -185,8 +181,7 @@ Don't convert files from DOS/Mac format.
|
||||
Don't display the two help lines at the bottom of the screen.
|
||||
.TP
|
||||
.B set nonewlines
|
||||
Deprecated option since it has become the default setting.
|
||||
When needed, use \fBunset finalnewline\fR instead.
|
||||
Don't automatically add a newline when a file does not end with one.
|
||||
.TP
|
||||
.B set nopauses
|
||||
Don't pause between warnings at startup. This means that only
|
||||
@@ -434,14 +429,14 @@ a more general mechanism: the filtering of buffer or marked text through
|
||||
an external command. Such filtering is done by typing \fB^R^X\fR and then
|
||||
preceding your formatter command with the pipe symbol (\fB|\fR). It has
|
||||
the added advantage that the operation can be undone.
|
||||
.PP
|
||||
.sp
|
||||
If you use such a formatting command regularly, you could assign the relevant
|
||||
series of keystrokes to a single key in your nanorc:
|
||||
.PP
|
||||
.sp
|
||||
.RS
|
||||
.B "bind M\-F \(dq^R^X|yourformatcommand^M\(dq main"
|
||||
.RE
|
||||
.PP
|
||||
.sp
|
||||
(Note that the \fB^R\fR, \fB^X\fR, and \fB^M\fR are each a single, literal
|
||||
control character. You can enter them by preceding each with \fBM\-V\fR.)
|
||||
|
||||
@@ -776,9 +771,6 @@ Toggles the presence of the two-line list of key bindings at the bottom of the s
|
||||
.B constantshow
|
||||
Toggles the constant display of the current line, column, and character positions.
|
||||
.TP
|
||||
.B smoothscroll
|
||||
Toggles smooth scrolling (when moving around with the arrow keys).
|
||||
.TP
|
||||
.B softwrap
|
||||
Toggles the displaying of overlong lines on multiple screen lines.
|
||||
.TP
|
||||
@@ -873,16 +865,11 @@ for \fBunbind\fR it means all menus where the specified \fIkey\fR exists.
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.B /etc/nanorc
|
||||
.I /etc/nanorc
|
||||
System-wide configuration file.
|
||||
.TP
|
||||
.BR ~/.nanorc " or " \fI$XDG_CONFIG_HOME\fB/nano/nanorc " or " ~/.config/nano/nanorc
|
||||
.IR ~/.nanorc " or " $XDG_CONFIG_HOME/nano/nanorc " or " ~/.config/nano/nanorc
|
||||
Per-user configuration file.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR nano (1)
|
||||
|
||||
.SH AUTHOR
|
||||
Chris Allegretta and others (see the files \fIAUTHORS\fP and
|
||||
\fITHANKS\fP for details). This manual page was originally written by
|
||||
Jordi Mallach for the Debian system (but may be used by others).
|
||||
|
||||
20
doc/rnano.1
20
doc/rnano.1
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 4.0" "March 2019"
|
||||
.TH RNANO 1 "version 4.2" "April 2019"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
@@ -29,7 +29,7 @@ rnano \- a restricted nano
|
||||
\fBrnano\fR runs the \fBnano\fR editor in restricted mode. This allows
|
||||
editing only the specified file or files, and doesn't allow the user
|
||||
access to the filesystem nor to a command shell.
|
||||
.PP
|
||||
.sp
|
||||
In restricted mode, \fBnano\fR will:
|
||||
.IP \[bu] 2
|
||||
not allow suspending;
|
||||
@@ -45,20 +45,16 @@ not make backup files nor do spell checking.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Show a summary of command-line options and exit.
|
||||
.PP
|
||||
See the \fBnano\fP(1) manpage for all available options.
|
||||
Show the available command-line options and exit.
|
||||
.P
|
||||
For all existing options, see the \fBnano\fR(1) man page.
|
||||
|
||||
.SH BUGS
|
||||
Please report bugs via \fIhttps://savannah.gnu.org/bugs/?group=nano\fR.
|
||||
Please report bugs via
|
||||
.IR https://savannah.gnu.org/bugs/?group=nano .
|
||||
|
||||
.SH HOMEPAGE
|
||||
https://nano-editor.org/
|
||||
.I https://nano-editor.org/
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR nano (1)
|
||||
|
||||
.SH AUTHOR
|
||||
Chris Allegretta and others (see the files \fIAUTHORS\fR and \fITHANKS\fR
|
||||
for details). This manual page was originally written by Thijs Kinkhorst
|
||||
for the Debian system (but may be used by others).
|
||||
|
||||
@@ -61,9 +61,6 @@
|
||||
## less, the wrapping point will be the screen width minus this number.
|
||||
# set fill -8
|
||||
|
||||
## Ensure that a non-empty buffer ends with a newline character.
|
||||
# set finalnewline
|
||||
|
||||
## Remember the used search/replace strings for the next session.
|
||||
# set historylog
|
||||
|
||||
@@ -99,6 +96,9 @@
|
||||
## Don't display the helpful shortcut lists at the bottom of the screen.
|
||||
# set nohelp
|
||||
|
||||
## Don't automatically add a newline when a file does not end with one.
|
||||
# set nonewlines
|
||||
|
||||
## Don't pause between warnings at startup. Which means that only the
|
||||
## last one will be readable (when there are multiple ones).
|
||||
# set nopauses
|
||||
|
||||
11
po/Makevars
11
po/Makevars
@@ -11,15 +11,12 @@ top_builddir = ..
|
||||
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --keyword=P_:1,2
|
||||
|
||||
# This is the copyright holder that gets inserted into the header of the
|
||||
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
|
||||
# package. (Note that the msgstr strings, extracted from the package's
|
||||
# sources, belong to the copyright holder of the package.) Translators are
|
||||
# expected to transfer the copyright for their translations to this person
|
||||
# or entity, or to disclaim their copyright. The empty string stands for
|
||||
# the public domain; in this case the translators are expected to disclaim
|
||||
# their copyright.
|
||||
# $(DOMAIN).pot file. Translators are expected to disclaim their copyright.
|
||||
COPYRIGHT_HOLDER = Free Software Foundation, Inc.
|
||||
|
||||
# This is the list of locale categories, beyond LC_MESSAGES, for which the
|
||||
# message catalogs shall be used. It is usually empty.
|
||||
EXTRA_LOCALE_CATEGORIES =
|
||||
|
||||
# Don't do fuzzy matching when merging the PO files against the POT file.
|
||||
MSGMERGE_OPTIONS = --no-fuzzy-matching
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
src/browser.c
|
||||
src/color.c
|
||||
src/cut.c
|
||||
src/files.c
|
||||
src/global.c
|
||||
src/help.c
|
||||
@@ -13,3 +14,6 @@ src/search.c
|
||||
src/text.c
|
||||
src/utils.c
|
||||
src/winio.c
|
||||
|
||||
lib/getopt.c
|
||||
lib/regcomp.c
|
||||
|
||||
1109
po/nano.pot
1109
po/nano.pot
File diff suppressed because it is too large
Load Diff
1418
po/pt_BR.po
1418
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
@@ -21,8 +21,11 @@ fi
|
||||
echo "Regenerating POT file and remerging and recompiling PO files..."
|
||||
make update-po
|
||||
|
||||
# Ensure that the PO files are newer than the POT.
|
||||
touch *.po
|
||||
echo "Removing the dead weight of obsolete and fuzzy translations..."
|
||||
for pofile in *.po; do
|
||||
msgattrib --no-obsolete --no-fuzzy $pofile >trimmed.po || exit 4
|
||||
mv trimmed.po $pofile || exit 4
|
||||
done
|
||||
|
||||
# If needed, fix a problem in the Makefile template.
|
||||
grep -q '^datarootdir' Makefile.in.in || \
|
||||
|
||||
1366
po/zh_CN.po
1366
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1406
po/zh_TW.po
1406
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION="4.0"
|
||||
VERSION="4.2"
|
||||
|
||||
./configure -C --enable-tiny && make && ./configure -C &&
|
||||
|
||||
@@ -12,8 +12,8 @@ po/update_linguas.sh &&
|
||||
|
||||
make distcheck && make dist-xz &&
|
||||
|
||||
git add po/*.po &&
|
||||
git commit -a -m "$(git log -1 --grep 'po: up' | grep o: | sed 's/^ //')" &&
|
||||
git add po/*.po po/nano.pot &&
|
||||
git commit -m "$(git log -1 --grep 'po: up' | grep o: | sed 's/^ //')" &&
|
||||
|
||||
gpg -a -b nano-$VERSION.tar.gz &&
|
||||
gpg -a -b nano-$VERSION.tar.xz &&
|
||||
|
||||
@@ -400,7 +400,7 @@ void read_the_list(const char *path, DIR *dir)
|
||||
|
||||
/* Find the length of the longest filename in the current folder. */
|
||||
while ((nextdir = readdir(dir)) != NULL) {
|
||||
size_t name_len = strlenpt(nextdir->d_name);
|
||||
size_t name_len = breadth(nextdir->d_name);
|
||||
|
||||
if (name_len > longest)
|
||||
longest = name_len;
|
||||
@@ -518,7 +518,7 @@ void browser_refresh(void)
|
||||
struct stat st;
|
||||
const char *thename = tail(filelist[i]);
|
||||
/* The filename we display, minus the path. */
|
||||
size_t namelen = strlenpt(thename);
|
||||
size_t namelen = breadth(thename);
|
||||
/* The length of the filename in columns. */
|
||||
size_t infolen;
|
||||
/* The length of the file information in columns. */
|
||||
@@ -598,7 +598,7 @@ void browser_refresh(void)
|
||||
}
|
||||
|
||||
/* Make sure info takes up no more than infomaxlen columns. */
|
||||
infolen = strlenpt(info);
|
||||
infolen = breadth(info);
|
||||
if (infolen > infomaxlen) {
|
||||
info[actual_x(info, infomaxlen)] = '\0';
|
||||
infolen = infomaxlen;
|
||||
@@ -672,7 +672,7 @@ int filesearch_init(bool forwards)
|
||||
thedefault = charalloc(strlen(disp) + 7);
|
||||
/* We use (COLS / 3) here because we need to see more on the line. */
|
||||
sprintf(thedefault, " [%s%s]", disp,
|
||||
(strlenpt(last_search) > COLS / 3) ? "..." : "");
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
thedefault = mallocstrcpy(NULL, "");
|
||||
|
||||
70
src/chars.c
70
src/chars.c
@@ -572,66 +572,40 @@ char *mbstrchr(const char *s, const char *c)
|
||||
#endif /* !NANO_TINY || ENABLE_JUSTIFY */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* This function is equivalent to strpbrk() for multibyte strings. */
|
||||
char *mbstrpbrk(const char *s, const char *accept)
|
||||
/* Locate, in the given string, the first occurrence of any of
|
||||
* the characters in accept, searching forward. */
|
||||
char *mbstrpbrk(const char *string, const char *accept)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
for (; *s != '\0'; s += move_mbright(s, 0)) {
|
||||
if (mbstrchr(accept, s) != NULL)
|
||||
return (char *)s;
|
||||
}
|
||||
while (*string != '\0') {
|
||||
if (mbstrchr(accept, string) != NULL)
|
||||
return (char *)string;
|
||||
|
||||
return NULL;
|
||||
} else
|
||||
#endif
|
||||
return (char *) strpbrk(s, accept);
|
||||
}
|
||||
|
||||
/* Locate, in the string that starts at head, the first occurrence of any of
|
||||
* the characters in the string accept, starting from pointer and searching
|
||||
* backwards. */
|
||||
char *revstrpbrk(const char *head, const char *accept, const char *pointer)
|
||||
{
|
||||
if (*pointer == '\0') {
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
pointer--;
|
||||
}
|
||||
|
||||
while (pointer >= head) {
|
||||
if (strchr(accept, *pointer) != NULL)
|
||||
return (char *)pointer;
|
||||
pointer--;
|
||||
string += move_mbright(string, 0);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The same as the preceding function but then for multibyte strings. */
|
||||
/* Locate, in the string that starts at head, the first occurrence of any of
|
||||
* the characters in accept, starting from pointer and searching backwards. */
|
||||
char *mbrevstrpbrk(const char *head, const char *accept, const char *pointer)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
if (*pointer == '\0') {
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
pointer = head + move_mbleft(head, pointer - head);
|
||||
}
|
||||
if (*pointer == '\0') {
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
pointer = head + move_mbleft(head, pointer - head);
|
||||
}
|
||||
|
||||
while (TRUE) {
|
||||
if (mbstrchr(accept, pointer) != NULL)
|
||||
return (char *)pointer;
|
||||
while (TRUE) {
|
||||
if (mbstrchr(accept, pointer) != NULL)
|
||||
return (char *)pointer;
|
||||
|
||||
/* If we've reached the head of the string, we found nothing. */
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
/* If we've reached the head of the string, we found nothing. */
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
|
||||
pointer = head + move_mbleft(head, pointer - head);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
return revstrpbrk(head, accept, pointer);
|
||||
pointer = head + move_mbleft(head, pointer - head);
|
||||
}
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
|
||||
16
src/cut.c
16
src/cut.c
@@ -67,7 +67,7 @@ void do_deletion(undo_type action)
|
||||
|
||||
/* If there is a magic line, and we're before it: don't eat it. */
|
||||
if (joining == openfile->filebot && openfile->current_x != 0 &&
|
||||
ISSET(FINAL_NEWLINE)) {
|
||||
!ISSET(NO_NEWLINES)) {
|
||||
#ifndef NANO_TINY
|
||||
if (action == BACK)
|
||||
add_undo(BACK);
|
||||
@@ -279,7 +279,7 @@ void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append)
|
||||
size_t cb_save_len = 0;
|
||||
/* The length of the string at the current end of the cutbuffer,
|
||||
* before we add text to it. */
|
||||
bool using_magicline = ISSET(FINAL_NEWLINE);
|
||||
bool using_magicline = !ISSET(NO_NEWLINES);
|
||||
/* Whether an automatic newline should be added at end-of-buffer. */
|
||||
bool right_side_up = TRUE;
|
||||
/* There *is* no region, *or* it is marked forward. */
|
||||
@@ -301,7 +301,7 @@ void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append)
|
||||
cb_save_len = strlen(cutbottom->data);
|
||||
}
|
||||
/* Don't add a magic line when moving text to the cutbuffer. */
|
||||
UNSET(FINAL_NEWLINE);
|
||||
SET(NO_NEWLINES);
|
||||
}
|
||||
|
||||
if (cut_till_eof) {
|
||||
@@ -339,7 +339,7 @@ void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append)
|
||||
}
|
||||
/* Restore the magic-line behavior now that we're done fiddling. */
|
||||
if (using_magicline)
|
||||
SET(FINAL_NEWLINE);
|
||||
UNSET(NO_NEWLINES);
|
||||
} else
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
@@ -358,8 +358,8 @@ bool is_cuttable(bool test_cliff)
|
||||
(openfile->mark == openfile->current &&
|
||||
openfile->mark_x == openfile->current_x) ||
|
||||
(test_cliff && openfile->current->data[openfile->current_x] == '\0' &&
|
||||
((!ISSET(FINAL_NEWLINE) && openfile->current == openfile->filebot) ||
|
||||
(ISSET(FINAL_NEWLINE) && openfile->current == openfile->filebot->prev))
|
||||
((ISSET(NO_NEWLINES) && openfile->current == openfile->filebot) ||
|
||||
(!ISSET(NO_NEWLINES) && openfile->current == openfile->filebot->prev))
|
||||
#endif
|
||||
)) {
|
||||
#ifndef NANO_TINY
|
||||
@@ -428,7 +428,7 @@ void do_copy_text(void)
|
||||
void do_cut_till_eof(void)
|
||||
{
|
||||
if ((openfile->current == openfile->filebot && openfile->current->data[0] == '\0') ||
|
||||
(ISSET(FINAL_NEWLINE) && openfile->current->next == openfile->filebot &&
|
||||
(!ISSET(NO_NEWLINES) && openfile->current->next == openfile->filebot &&
|
||||
openfile->current->data[openfile->current_x] == '\0')) {
|
||||
statusbar(_("Nothing was cut"));
|
||||
return;
|
||||
@@ -478,7 +478,7 @@ void do_uncut_text(void)
|
||||
/* The leftedge where we started the paste. */
|
||||
|
||||
if (cutbuffer == NULL) {
|
||||
statusbar(_("The cutbuffer is empty"));
|
||||
statusbar(_("Cutbuffer is empty"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
44
src/files.c
44
src/files.c
@@ -64,26 +64,25 @@ void make_new_buffer(void)
|
||||
{
|
||||
openfilestruct *newnode = nmalloc(sizeof(openfilestruct));
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (openfile == NULL) {
|
||||
/* Make the first open file the only element in the list. */
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
newnode->prev = newnode;
|
||||
newnode->next = newnode;
|
||||
#endif
|
||||
firstfile = newnode;
|
||||
|
||||
startfile = newnode;
|
||||
} else {
|
||||
/* Add the new open file after the current one in the list. */
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
newnode->prev = openfile;
|
||||
newnode->next = openfile->next;
|
||||
openfile->next->prev = newnode;
|
||||
openfile->next = newnode;
|
||||
#endif
|
||||
|
||||
/* There is more than one file open: show "Close" in help lines. */
|
||||
exitfunc->desc = close_tag;
|
||||
more_than_one = !inhelp || more_than_one;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Make the new buffer the current one, and start initializing it. */
|
||||
openfile = newnode;
|
||||
|
||||
@@ -95,6 +94,9 @@ void make_new_buffer(void)
|
||||
openfile->current_y = 0;
|
||||
|
||||
openfile->modified = FALSE;
|
||||
#ifdef ENABLE_WRAPPING
|
||||
openfile->spillage_line = NULL;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
openfile->mark = NULL;
|
||||
|
||||
@@ -353,13 +355,13 @@ int do_lockfile(const char *filename)
|
||||
|
||||
/* TRANSLATORS: The second %s is the name of the user, the third that of the editor. */
|
||||
question = _("File %s is being edited (by %s with %s, PID %s); continue?");
|
||||
room = COLS - strlenpt(question) + 7 - strlenpt(lockuser) -
|
||||
strlenpt(lockprog) - strlenpt(pidstring);
|
||||
room = COLS - breadth(question) + 7 - breadth(lockuser) -
|
||||
breadth(lockprog) - breadth(pidstring);
|
||||
if (room < 4)
|
||||
postedname = mallocstrcpy(NULL, "_");
|
||||
else if (room < strlenpt(filename)) {
|
||||
else if (room < breadth(filename)) {
|
||||
char *fragment = display_string(filename,
|
||||
strlenpt(filename) - room + 3, room, FALSE, FALSE);
|
||||
breadth(filename) - room + 3, room, FALSE, FALSE);
|
||||
postedname = charalloc(strlen(fragment) + 4);
|
||||
strcpy(postedname, "...");
|
||||
strcat(postedname, fragment);
|
||||
@@ -557,7 +559,7 @@ void replace_marked_buffer(const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int descriptor;
|
||||
bool using_magicline = ISSET(FINAL_NEWLINE);
|
||||
bool using_magicline = !ISSET(NO_NEWLINES);
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
|
||||
descriptor = open_file(filename, FALSE, TRUE, &f);
|
||||
@@ -566,7 +568,7 @@ void replace_marked_buffer(const char *filename)
|
||||
return;
|
||||
|
||||
/* Don't add a magic line when replacing text in the buffer. */
|
||||
UNSET(FINAL_NEWLINE);
|
||||
SET(NO_NEWLINES);
|
||||
|
||||
add_undo(COUPLE_BEGIN);
|
||||
openfile->undotop->strdata = mallocstrcpy(NULL, _("spelling correction"));
|
||||
@@ -584,7 +586,7 @@ void replace_marked_buffer(const char *filename)
|
||||
|
||||
/* Restore the magic-line behavior now that we're done fiddling. */
|
||||
if (using_magicline)
|
||||
SET(FINAL_NEWLINE);
|
||||
UNSET(NO_NEWLINES);
|
||||
|
||||
add_undo(COUPLE_END);
|
||||
openfile->undotop->strdata = mallocstrcpy(NULL, _("spelling correction"));
|
||||
@@ -800,6 +802,10 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
topline = make_new_node(NULL);
|
||||
bottomline = topline;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
block_sigwinch(TRUE);
|
||||
#endif
|
||||
|
||||
/* Lock the file before starting to read it, to avoid the overhead
|
||||
* of locking it for each single byte that we read from it. */
|
||||
flockfile(f);
|
||||
@@ -875,6 +881,10 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
/* We are done with the file, unlock it. */
|
||||
funlockfile(f);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
block_sigwinch(FALSE);
|
||||
#endif
|
||||
|
||||
/* Perhaps this could use some better handling. */
|
||||
if (ferror(f))
|
||||
nperror(filename);
|
||||
@@ -2054,7 +2064,7 @@ bool write_marked_file(const char *name, FILE *f_open, bool tmp,
|
||||
|
||||
/* If we are using a magic line, and the last line of the partition
|
||||
* isn't blank, then add a newline at the end of the buffer. */
|
||||
if (ISSET(FINAL_NEWLINE) && openfile->filebot->data[0] != '\0') {
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0') {
|
||||
new_magicline();
|
||||
added_magicline = TRUE;
|
||||
}
|
||||
@@ -2101,7 +2111,7 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
|
||||
while (TRUE) {
|
||||
const char *msg;
|
||||
int response, choice;
|
||||
int response = 0, choice = 0;
|
||||
functionptrtype func;
|
||||
#ifndef NANO_TINY
|
||||
const char *formatstr, *backupstr;
|
||||
@@ -2256,7 +2266,7 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
if (name_exists) {
|
||||
char *question = _("File \"%s\" exists; OVERWRITE? ");
|
||||
char *name = display_string(answer, 0,
|
||||
COLS - strlenpt(question) + 1, FALSE, FALSE);
|
||||
COLS - breadth(question) + 1, FALSE, FALSE);
|
||||
char *message = charalloc(strlen(question) +
|
||||
strlen(name) + 1);
|
||||
|
||||
@@ -2673,7 +2683,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
|
||||
/* Find the length of the longest among the choices. */
|
||||
for (match = 0; match < num_matches; match++) {
|
||||
size_t namelen = strlenpt(matches[match]);
|
||||
size_t namelen = breadth(matches[match]);
|
||||
|
||||
if (namelen > longest_name)
|
||||
longest_name = namelen;
|
||||
|
||||
62
src/global.c
62
src/global.c
@@ -127,8 +127,10 @@ partition *filepart = NULL;
|
||||
/* The "partition" where we store a portion of the current file. */
|
||||
openfilestruct *openfile = NULL;
|
||||
/* The list of all open file buffers. */
|
||||
openfilestruct *firstfile = NULL;
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
openfilestruct *startfile = NULL;
|
||||
/* The first open buffer. */
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
char *matchbrackets = NULL;
|
||||
@@ -194,13 +196,13 @@ bool refresh_needed = FALSE;
|
||||
|
||||
int currmenu = MMOST;
|
||||
/* The currently active menu, initialized to a dummy value. */
|
||||
sc *sclist = NULL;
|
||||
keystruct *sclist = NULL;
|
||||
/* The start of the shortcuts list. */
|
||||
subnfunc *allfuncs = NULL;
|
||||
funcstruct *allfuncs = NULL;
|
||||
/* The start of the functions list. */
|
||||
subnfunc *tailfunc;
|
||||
funcstruct *tailfunc;
|
||||
/* The last function in the list. */
|
||||
subnfunc *exitfunc;
|
||||
funcstruct *exitfunc;
|
||||
/* A pointer to the special Exit/Close item. */
|
||||
|
||||
linestruct *search_history = NULL;
|
||||
@@ -269,7 +271,7 @@ size_t light_to_col = 0;
|
||||
/* Return the number of entries in the shortcut list for a given menu. */
|
||||
size_t length_of_list(int menu)
|
||||
{
|
||||
subnfunc *f;
|
||||
funcstruct *f;
|
||||
size_t i = 0;
|
||||
|
||||
for (f = allfuncs; f != NULL; f = f->next)
|
||||
@@ -359,7 +361,7 @@ void do_cancel(void)
|
||||
void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *help,
|
||||
bool blank_after, bool viewok)
|
||||
{
|
||||
subnfunc *f = nmalloc(sizeof(subnfunc));
|
||||
funcstruct *f = nmalloc(sizeof(funcstruct));
|
||||
|
||||
if (allfuncs == NULL)
|
||||
allfuncs = f;
|
||||
@@ -386,18 +388,17 @@ void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *h
|
||||
void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
void (*func)(void), int toggle)
|
||||
{
|
||||
static sc *tailsc;
|
||||
static keystruct *tailsc;
|
||||
#ifndef NANO_TINY
|
||||
static int counter = 0;
|
||||
#endif
|
||||
sc *s = nmalloc(sizeof(sc));
|
||||
keystruct *s = nmalloc(sizeof(keystruct));
|
||||
|
||||
/* Start the list, or tack on the next item. */
|
||||
if (sclist == NULL)
|
||||
sclist = s;
|
||||
else
|
||||
tailsc->next = s;
|
||||
tailsc = s;
|
||||
s->next = NULL;
|
||||
|
||||
/* Fill in the data. */
|
||||
@@ -405,11 +406,14 @@ void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
s->func = func;
|
||||
#ifndef NANO_TINY
|
||||
s->toggle = toggle;
|
||||
/* When not the same toggle as the previous one, increment the ID. */
|
||||
if (toggle)
|
||||
s->ordinal = ++counter;
|
||||
s->ordinal = (tailsc->toggle == toggle) ? counter : ++counter;
|
||||
#endif
|
||||
assign_keyinfo(s, scstring, keycode);
|
||||
|
||||
tailsc = s;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Setting keycode to %d for shortcut \"%s\" in menus %x\n", s->keycode, scstring, s->menus);
|
||||
#endif
|
||||
@@ -417,9 +421,9 @@ void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
|
||||
/* Return the first shortcut in the list of shortcuts that
|
||||
* matches the given func in the given menu. */
|
||||
const sc *first_sc_for(int menu, void (*func)(void))
|
||||
const keystruct *first_sc_for(int menu, void (*func)(void))
|
||||
{
|
||||
const sc *s;
|
||||
const keystruct *s;
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if ((s->menus & menu) && s->func == func)
|
||||
@@ -435,7 +439,7 @@ const sc *first_sc_for(int menu, void (*func)(void))
|
||||
* current menu, if any; otherwise, return the given default value. */
|
||||
int the_code_for(void (*func)(void), int defaultval)
|
||||
{
|
||||
const sc *s = first_sc_for(currmenu, func);
|
||||
const keystruct *s = first_sc_for(currmenu, func);
|
||||
|
||||
if (s == NULL)
|
||||
return defaultval;
|
||||
@@ -447,7 +451,7 @@ int the_code_for(void (*func)(void), int defaultval)
|
||||
/* Return a pointer to the function that is bound to the given key. */
|
||||
functionptrtype func_from_key(int *kbinput)
|
||||
{
|
||||
const sc *s = get_shortcut(kbinput);
|
||||
const keystruct *s = get_shortcut(kbinput);
|
||||
|
||||
if (s)
|
||||
return s->func;
|
||||
@@ -456,7 +460,7 @@ functionptrtype func_from_key(int *kbinput)
|
||||
}
|
||||
|
||||
/* Set the string and its corresponding keycode for the given shortcut s. */
|
||||
void assign_keyinfo(sc *s, const char *keystring, const int keycode)
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode)
|
||||
{
|
||||
s->keystr = keystring;
|
||||
s->meta = (keystring[0] == 'M' && keycode == 0);
|
||||
@@ -505,8 +509,8 @@ int keycode_from_string(const char *keystring)
|
||||
#ifdef DEBUG
|
||||
void print_sclist(void)
|
||||
{
|
||||
sc *s;
|
||||
const subnfunc *f;
|
||||
keystruct *s;
|
||||
const funcstruct *f;
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next) {
|
||||
f = sctofunc(s);
|
||||
@@ -1039,7 +1043,7 @@ void shortcut_init(void)
|
||||
N_("No Conversion"), WITHORSANS(convert_gist), TOGETHER, NOVIEW);
|
||||
|
||||
/* Command execution is only available when not in restricted mode. */
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) {
|
||||
add_to_funcs(flip_execute, MINSERTFILE,
|
||||
N_("Execute Command"), WITHORSANS(execute_gist), TOGETHER, NOVIEW);
|
||||
|
||||
@@ -1256,9 +1260,10 @@ void shortcut_init(void)
|
||||
/* Group of "Appearance" toggles. */
|
||||
add_to_sclist(MMAIN, "M-X", 0, do_toggle_void, NO_HELP);
|
||||
add_to_sclist(MMAIN, "M-C", 0, do_toggle_void, CONSTANT_SHOW);
|
||||
add_to_sclist(MMAIN, "M-S", 0, do_toggle_void, JUMPY_SCROLLING);
|
||||
add_to_sclist(MMAIN, "M-S", 0, do_toggle_void, SOFTWRAP);
|
||||
add_to_sclist(MMAIN, "M-$", 0, do_toggle_void, SOFTWRAP);
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
add_to_sclist(MMAIN, "M-N", 0, do_toggle_void, LINE_NUMBERS);
|
||||
add_to_sclist(MMAIN, "M-#", 0, do_toggle_void, LINE_NUMBERS);
|
||||
#endif
|
||||
add_to_sclist(MMAIN, "M-P", 0, do_toggle_void, WHITESPACE_DISPLAY);
|
||||
@@ -1309,6 +1314,9 @@ void shortcut_init(void)
|
||||
#endif
|
||||
add_to_sclist(MGOTOLINE, "^Y", 0, to_first_line, 0);
|
||||
add_to_sclist(MGOTOLINE, "^V", 0, to_last_line, 0);
|
||||
/* Some people are used to having these keystrokes in the Search menu. */
|
||||
add_to_sclist(MWHEREIS, "^Y", 0, to_first_line, 0);
|
||||
add_to_sclist(MWHEREIS, "^V", 0, to_last_line, 0);
|
||||
#ifdef ENABLE_BROWSER
|
||||
add_to_sclist(MWHEREISFILE, "^Y", 0, to_first_file, 0);
|
||||
add_to_sclist(MWHEREISFILE, "^V", 0, to_last_file, 0);
|
||||
@@ -1328,7 +1336,7 @@ void shortcut_init(void)
|
||||
add_to_sclist(MWRITEFILE, "M-M", 0, mac_format_void, 0);
|
||||
/* Only when not in restricted mode, allow Appending, Prepending,
|
||||
* making backups, and executing a command. */
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) {
|
||||
add_to_sclist(MWRITEFILE, "M-A", 0, append_void, 0);
|
||||
add_to_sclist(MWRITEFILE, "M-P", 0, prepend_void, 0);
|
||||
add_to_sclist(MWRITEFILE, "M-B", 0, backup_file_void, 0);
|
||||
@@ -1387,9 +1395,9 @@ void shortcut_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
const subnfunc *sctofunc(const sc *s)
|
||||
const funcstruct *sctofunc(const keystruct *s)
|
||||
{
|
||||
subnfunc *f = allfuncs;
|
||||
funcstruct *f = allfuncs;
|
||||
|
||||
while (f != NULL && f->func != s->func)
|
||||
f = f->next;
|
||||
@@ -1408,8 +1416,6 @@ const char *flagtostr(int flag)
|
||||
return N_("Help mode");
|
||||
case CONSTANT_SHOW:
|
||||
return N_("Constant cursor position display");
|
||||
case JUMPY_SCROLLING:
|
||||
return N_("Jumpy scrolling (per half-screen)");
|
||||
case SOFTWRAP:
|
||||
return N_("Soft wrapping of overlong lines");
|
||||
case WHITESPACE_DISPLAY:
|
||||
@@ -1441,9 +1447,9 @@ const char *flagtostr(int flag)
|
||||
#ifdef ENABLE_NANORC
|
||||
/* Interpret a function string given in the rc file, and return a
|
||||
* shortcut record with the corresponding function filled in. */
|
||||
sc *strtosc(const char *input)
|
||||
keystruct *strtosc(const char *input)
|
||||
{
|
||||
sc *s = nmalloc(sizeof(sc));
|
||||
keystruct *s = nmalloc(sizeof(keystruct));
|
||||
|
||||
#ifndef NANO_TINY
|
||||
s->toggle = 0;
|
||||
@@ -1661,8 +1667,6 @@ sc *strtosc(const char *input)
|
||||
s->toggle = NO_HELP;
|
||||
else if (!strcasecmp(input, "constantshow"))
|
||||
s->toggle = CONSTANT_SHOW;
|
||||
else if (!strcasecmp(input, "smoothscroll"))
|
||||
s->toggle = JUMPY_SCROLLING;
|
||||
else if (!strcasecmp(input, "softwrap"))
|
||||
s->toggle = SOFTWRAP;
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
|
||||
@@ -291,8 +291,8 @@ void help_init(void)
|
||||
/* Untranslated help introduction. We break it up into three chunks
|
||||
* in case the full string is too long for the compiler to handle. */
|
||||
char *ptr;
|
||||
const subnfunc *f;
|
||||
const sc *s;
|
||||
const funcstruct *f;
|
||||
const keystruct *s;
|
||||
|
||||
/* First, set up the initial help text for the current function. */
|
||||
if (currmenu == MWHEREIS || currmenu == MREPLACE || currmenu == MREPLACEWITH) {
|
||||
@@ -556,9 +556,6 @@ void help_init(void)
|
||||
}
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
if (strlen(help_text) > allocsize)
|
||||
statusline(ALERT, "Help text spilled over -- please report a bug");
|
||||
}
|
||||
|
||||
/* Return the function that is bound to the given key, accepting certain
|
||||
@@ -613,7 +610,7 @@ size_t help_line_len(const char *ptr)
|
||||
length = move_mbright(ptr, length);
|
||||
|
||||
/* If the entire line will just fit the screen, don't wrap it. */
|
||||
if (strnlenpt(ptr, length) <= wrapping_point + 1)
|
||||
if (wideness(ptr, length) <= wrapping_point + 1)
|
||||
return length;
|
||||
else if (wrap_location > 0)
|
||||
return wrap_location;
|
||||
|
||||
@@ -75,7 +75,7 @@ size_t proper_x(linestruct *line, size_t *leftedge, bool forward,
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP) && line->data[index] == '\t' &&
|
||||
((forward && strnlenpt(line->data, index) < *leftedge) ||
|
||||
((forward && wideness(line->data, index) < *leftedge) ||
|
||||
(!forward && column / tabsize == (*leftedge - 1) / tabsize &&
|
||||
column / tabsize < (*leftedge + editwincols - 1) / tabsize))) {
|
||||
index++;
|
||||
@@ -85,7 +85,7 @@ size_t proper_x(linestruct *line, size_t *leftedge, bool forward,
|
||||
}
|
||||
|
||||
if (ISSET(SOFTWRAP))
|
||||
*leftedge = leftedge_for(strnlenpt(line->data, index), line);
|
||||
*leftedge = leftedge_for(wideness(line->data, index), line);
|
||||
#endif
|
||||
|
||||
return index;
|
||||
|
||||
101
src/nano.c
101
src/nano.c
@@ -131,6 +131,11 @@ void unlink_node(linestruct *fileptr)
|
||||
/* Free the data structures in the given node. */
|
||||
void delete_node(linestruct *fileptr)
|
||||
{
|
||||
#ifdef ENABLE_WRAPPING
|
||||
/* If the spill-over line for hard-wrapping is deleted... */
|
||||
if (fileptr == openfile->spillage_line)
|
||||
openfile->spillage_line = NULL;
|
||||
#endif
|
||||
free(fileptr->data);
|
||||
#ifdef ENABLE_COLOR
|
||||
free(fileptr->multidata);
|
||||
@@ -178,16 +183,7 @@ void free_lines(linestruct *src)
|
||||
/* Renumber the lines in a buffer, starting with the given line. */
|
||||
void renumber(linestruct *line)
|
||||
{
|
||||
ssize_t number;
|
||||
|
||||
if (line == NULL) {
|
||||
#ifndef NANO_TINY
|
||||
statusline(ALERT, "Trying to renumber nothing -- please report a bug");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
number = (line->prev == NULL) ? 0 : line->prev->lineno;
|
||||
ssize_t number = (line->prev == NULL) ? 0 : line->prev->lineno;
|
||||
|
||||
while (line != NULL) {
|
||||
line->lineno = ++number;
|
||||
@@ -389,7 +385,7 @@ void extract_buffer(linestruct **file_top, linestruct **file_bot,
|
||||
renumber(top_save);
|
||||
|
||||
/* If the text doesn't end with a newline, and it should, add one. */
|
||||
if (ISSET(FINAL_NEWLINE) && openfile->filebot->data[0] != '\0')
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
}
|
||||
|
||||
@@ -486,7 +482,7 @@ void ingraft_buffer(linestruct *somebuffer)
|
||||
renumber(top_save);
|
||||
|
||||
/* If the text doesn't end with a newline, and it should, add one. */
|
||||
if (ISSET(FINAL_NEWLINE) && openfile->filebot->data[0] != '\0')
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
}
|
||||
|
||||
@@ -502,13 +498,12 @@ void copy_from_buffer(linestruct *somebuffer)
|
||||
/* Unlink a node from the rest of the circular list, and delete it. */
|
||||
void unlink_opennode(openfilestruct *fileptr)
|
||||
{
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (fileptr == firstfile)
|
||||
firstfile = firstfile->next;
|
||||
if (fileptr == startfile)
|
||||
startfile = startfile->next;
|
||||
|
||||
fileptr->prev->next = fileptr->next;
|
||||
fileptr->next->prev = fileptr->prev;
|
||||
#endif
|
||||
|
||||
delete_opennode(fileptr);
|
||||
}
|
||||
|
||||
@@ -525,7 +520,7 @@ void delete_opennode(openfilestruct *fileptr)
|
||||
#endif
|
||||
free(fileptr);
|
||||
}
|
||||
#endif
|
||||
#endif /* ENABLE_MULTIBUFFER */
|
||||
|
||||
/* Display a warning about a key disabled in view mode. */
|
||||
void print_view_warning(void)
|
||||
@@ -746,13 +741,13 @@ void mouse_init(void)
|
||||
void print_opt(const char *shortflag, const char *longflag, const char *desc)
|
||||
{
|
||||
printf(" %s\t", shortflag);
|
||||
if (strlenpt(shortflag) < 8)
|
||||
if (breadth(shortflag) < 8)
|
||||
printf("\t");
|
||||
|
||||
printf("%s\t", longflag);
|
||||
if (strlenpt(longflag) < 8)
|
||||
if (breadth(longflag) < 8)
|
||||
printf("\t\t");
|
||||
else if (strlenpt(longflag) < 16)
|
||||
else if (breadth(longflag) < 16)
|
||||
printf("\t");
|
||||
|
||||
printf("%s\n", _(desc));
|
||||
@@ -806,7 +801,7 @@ void usage(void)
|
||||
N_("Fix numeric keypad key confusion problem"));
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-L", "--nonewlines",
|
||||
N_("Don't add an automatic newline [default]"));
|
||||
N_("Don't add an automatic newline"));
|
||||
#endif
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
print_opt("-M", "--trimblanks",
|
||||
@@ -853,7 +848,6 @@ void usage(void)
|
||||
print_opt("-d", "--rebinddelete",
|
||||
N_("Fix Backspace/Delete confusion problem"));
|
||||
print_opt("-e", "--emptyline", N_("Keep the line below the title bar empty"));
|
||||
print_opt("-f", "--finalnewline", N_("Ensure that text ends with a newline"));
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (!ISSET(RESTRICTED))
|
||||
print_opt("-g", "--showcursor", N_("Show cursor in file browser & help text"));
|
||||
@@ -1064,8 +1058,7 @@ void do_exit(void)
|
||||
if (ISSET(TEMP_FILE))
|
||||
warn_and_shortly_pause(_("No file name"));
|
||||
|
||||
choice = do_yesno_prompt(FALSE, _("Save modified buffer? "
|
||||
"(Answering \"No\" will DISCARD changes.) "));
|
||||
choice = do_yesno_prompt(FALSE, _("Save modified buffer? "));
|
||||
}
|
||||
|
||||
/* If the user chose not to save, or if the user chose to save and
|
||||
@@ -1300,6 +1293,23 @@ RETSIGTYPE do_continue(int signal)
|
||||
ungetch(KEY_FLUSH);
|
||||
}
|
||||
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER)
|
||||
/* Block or unblock the SIGWINCH signal, depending on the blockit parameter. */
|
||||
void block_sigwinch(bool blockit)
|
||||
{
|
||||
sigset_t winch;
|
||||
|
||||
sigemptyset(&winch);
|
||||
sigaddset(&winch, SIGWINCH);
|
||||
sigprocmask(blockit ? SIG_BLOCK : SIG_UNBLOCK, &winch, NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (the_window_resized)
|
||||
regenerate_screen();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Handler for SIGWINCH (window size change). */
|
||||
RETSIGTYPE handle_sigwinch(int signal)
|
||||
@@ -1649,9 +1659,9 @@ bool wanted_to_move(void (*func)(void))
|
||||
}
|
||||
|
||||
/* Return TRUE when the given shortcut is admissible in view mode. */
|
||||
bool okay_for_view(const sc *shortcut)
|
||||
bool okay_for_view(const keystruct *shortcut)
|
||||
{
|
||||
const subnfunc *func = sctofunc(shortcut);
|
||||
const funcstruct *func = sctofunc(shortcut);
|
||||
|
||||
return (func == NULL || func->viewok);
|
||||
}
|
||||
@@ -1668,7 +1678,7 @@ void do_input(void)
|
||||
/* The length of the input buffer. */
|
||||
bool retain_cuts = FALSE;
|
||||
/* Whether to conserve the current contents of the cutbuffer. */
|
||||
const sc *shortcut;
|
||||
const keystruct *shortcut;
|
||||
|
||||
/* Read in a keystroke, and show the cursor while waiting. */
|
||||
input = get_kbinput(edit, VISIBLE);
|
||||
@@ -1775,9 +1785,6 @@ void do_input(void)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef ENABLE_WRAPPING
|
||||
linestruct *was_next = openfile->current->next;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
linestruct *was_current = openfile->current;
|
||||
size_t was_x = openfile->current_x;
|
||||
@@ -1807,14 +1814,6 @@ void do_input(void)
|
||||
also_the_last = FALSE;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_WRAPPING
|
||||
/* If the cursor moved to another line and this was not caused
|
||||
* by adding characters to the buffer, clear the prepend flag. */
|
||||
if (openfile->current->next != was_next &&
|
||||
shortcut->func != do_tab &&
|
||||
shortcut->func != do_verbatim_input)
|
||||
wrap_reset();
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
if (!refresh_needed && !okay_for_view(shortcut))
|
||||
check_the_multis(openfile->current);
|
||||
@@ -1906,7 +1905,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
#endif
|
||||
|
||||
/* If we've added text to the magic line, create a new magic line. */
|
||||
if (openfile->filebot == openfile->current && ISSET(FINAL_NEWLINE)) {
|
||||
if (openfile->filebot == openfile->current && !ISSET(NO_NEWLINES)) {
|
||||
new_magicline();
|
||||
if (margin > 0)
|
||||
refresh_needed = TRUE;
|
||||
@@ -1914,7 +1913,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
|
||||
#ifdef ENABLE_WRAPPING
|
||||
/* If text gets wrapped, the edit window needs a refresh. */
|
||||
if (ISSET(BREAK_LONG_LINES) && do_wrap(openfile->current))
|
||||
if (ISSET(BREAK_LONG_LINES) && do_wrap())
|
||||
refresh_needed = TRUE;
|
||||
#endif
|
||||
}
|
||||
@@ -1953,6 +1952,8 @@ int main(int argc, char **argv)
|
||||
bool fill_used = FALSE;
|
||||
/* Was the fill option used on the command line? */
|
||||
#endif
|
||||
int hardwrap = -2;
|
||||
/* Becomes 0 when --nowrap and 1 when --breaklonglines is used. */
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
int quoterc;
|
||||
/* Whether the quoting regex was compiled successfully. */
|
||||
@@ -1985,7 +1986,6 @@ int main(int argc, char **argv)
|
||||
{"constantshow", 0, NULL, 'c'},
|
||||
{"rebinddelete", 0, NULL, 'd'},
|
||||
{"emptyline", 0, NULL, 'e'},
|
||||
{"finalnewline", 0, NULL, 'f'},
|
||||
#ifdef ENABLE_BROWSER
|
||||
{"showcursor", 0, NULL, 'g'},
|
||||
#endif
|
||||
@@ -2083,7 +2083,6 @@ int main(int argc, char **argv)
|
||||
|
||||
/* Set sensible defaults, different from what Pico does. */
|
||||
SET(NO_WRAP);
|
||||
SET(NO_NEWLINES);
|
||||
SET(SMOOTH_SCROLL);
|
||||
|
||||
/* Give a small visual hint that nano has changed. */
|
||||
@@ -2095,7 +2094,7 @@ int main(int argc, char **argv)
|
||||
|
||||
while ((optchr =
|
||||
getopt_long(argc, argv,
|
||||
"ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Zabcdefghijklmno:pr:s:tuvwxyz$",
|
||||
"ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Zabcdeghijklmno:pr:s:tuvwxyz$",
|
||||
long_options, NULL)) != -1) {
|
||||
switch (optchr) {
|
||||
#ifndef NANO_TINY
|
||||
@@ -2151,7 +2150,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
#ifndef NANO_TINY
|
||||
case 'L':
|
||||
UNSET(FINAL_NEWLINE);
|
||||
SET(NO_NEWLINES);
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
@@ -2223,7 +2222,7 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
#ifdef ENABLE_WRAPPING
|
||||
case 'b':
|
||||
SET(BREAK_LONG_LINES);
|
||||
hardwrap = 1;
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
@@ -2235,9 +2234,6 @@ int main(int argc, char **argv)
|
||||
case 'e':
|
||||
SET(EMPTY_LINE);
|
||||
break;
|
||||
case 'f':
|
||||
SET(FINAL_NEWLINE);
|
||||
break;
|
||||
case 'g':
|
||||
SET(SHOW_CURSOR);
|
||||
break;
|
||||
@@ -2308,7 +2304,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
#ifdef ENABLE_WRAPPING
|
||||
case 'w':
|
||||
UNSET(BREAK_LONG_LINES);
|
||||
hardwrap = 0;
|
||||
break;
|
||||
#endif
|
||||
case 'x':
|
||||
@@ -2426,8 +2422,6 @@ int main(int argc, char **argv)
|
||||
/* If an rcfile undid the default settings, copy it to the new flags. */
|
||||
if (!ISSET(NO_WRAP))
|
||||
SET(BREAK_LONG_LINES);
|
||||
if (!ISSET(NO_NEWLINES))
|
||||
SET(FINAL_NEWLINE);
|
||||
if (!ISSET(SMOOTH_SCROLL))
|
||||
SET(JUMPY_SCROLLING);
|
||||
if (!ISSET(MORE_SPACE))
|
||||
@@ -2439,6 +2433,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
if (hardwrap == 0)
|
||||
UNSET(BREAK_LONG_LINES);
|
||||
else if (hardwrap == 1)
|
||||
SET(BREAK_LONG_LINES);
|
||||
|
||||
/* If the user wants bold instead of reverse video for hilited text... */
|
||||
if (ISSET(BOLD_TEXT))
|
||||
hilite_attribute = A_BOLD;
|
||||
|
||||
23
src/nano.h
23
src/nano.h
@@ -383,6 +383,10 @@ typedef struct openfilestruct {
|
||||
/* Whether the file has been modified. */
|
||||
struct stat *current_stat;
|
||||
/* The file's current stat information. */
|
||||
#ifdef ENABLE_WRAPPING
|
||||
linestruct *spillage_line;
|
||||
/* The line for prepending stuff to during automatic hard-wrapping. */
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
linestruct *mark;
|
||||
/* The line in the file where the mark is set; NULL if not set. */
|
||||
@@ -426,17 +430,17 @@ typedef struct rcoption {
|
||||
} rcoption;
|
||||
#endif
|
||||
|
||||
typedef struct sc {
|
||||
typedef struct keystruct {
|
||||
const char *keystr;
|
||||
/* The string that describes a keystroke, like "^C" or "M-R". */
|
||||
/* The string that describes the keystroke, like "^C" or "M-R". */
|
||||
bool meta;
|
||||
/* Whether this is a Meta keystroke. */
|
||||
int keycode;
|
||||
/* The integer that, together with meta, identifies the keystroke. */
|
||||
int menus;
|
||||
/* Which menus this applies to. */
|
||||
/* The menus in which this keystroke is bound. */
|
||||
void (*func)(void);
|
||||
/* The function we're going to run. */
|
||||
/* The function to which this keystroke is bound. */
|
||||
#ifndef NANO_TINY
|
||||
int toggle;
|
||||
/* If a toggle, what we're toggling. */
|
||||
@@ -448,11 +452,11 @@ typedef struct sc {
|
||||
char *expansion;
|
||||
/* The string of keycodes to which this shortcut is expanded. */
|
||||
#endif
|
||||
struct sc *next;
|
||||
struct keystruct *next;
|
||||
/* Next in the list. */
|
||||
} sc;
|
||||
} keystruct;
|
||||
|
||||
typedef struct subnfunc {
|
||||
typedef struct funcstruct {
|
||||
void (*func)(void);
|
||||
/* The actual function to call. */
|
||||
int menus;
|
||||
@@ -470,9 +474,9 @@ typedef struct subnfunc {
|
||||
/* Is this function allowed when in view mode? */
|
||||
long toggle;
|
||||
/* If this is a toggle, which toggle to affect. */
|
||||
struct subnfunc *next;
|
||||
struct funcstruct *next;
|
||||
/* Next item in the list. */
|
||||
} subnfunc;
|
||||
} funcstruct;
|
||||
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
typedef struct completion_word {
|
||||
@@ -543,7 +547,6 @@ enum
|
||||
AFTER_ENDS,
|
||||
LET_THEM_ZAP,
|
||||
BREAK_LONG_LINES,
|
||||
FINAL_NEWLINE,
|
||||
JUMPY_SCROLLING,
|
||||
EMPTY_LINE
|
||||
};
|
||||
|
||||
18
src/prompt.c
18
src/prompt.c
@@ -37,13 +37,13 @@ int do_statusbar_mouse(void)
|
||||
|
||||
/* We can click on the statusbar window text to move the cursor. */
|
||||
if (retval == 0 && wmouse_trafo(bottomwin, &click_row, &click_col, FALSE)) {
|
||||
size_t start_col = strlenpt(prompt) + 2;
|
||||
size_t start_col = breadth(prompt) + 2;
|
||||
|
||||
/* Move to where the click occurred. */
|
||||
if (click_row == 0 && click_col >= start_col)
|
||||
typing_x = actual_x(answer,
|
||||
get_statusbar_page_start(start_col, start_col +
|
||||
strnlenpt(answer, typing_x)) + click_col - start_col);
|
||||
wideness(answer, typing_x)) + click_col - start_col);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -61,7 +61,7 @@ int do_statusbar_input(bool *finished)
|
||||
/* The input buffer. */
|
||||
static size_t kbinput_len = 0;
|
||||
/* The length of the input buffer. */
|
||||
const sc *shortcut;
|
||||
const keystruct *shortcut;
|
||||
|
||||
*finished = FALSE;
|
||||
|
||||
@@ -385,12 +385,12 @@ void put_cursor_at_end_of_answer(void)
|
||||
/* Redraw the promptbar and place the cursor at the right spot. */
|
||||
void draw_the_promptbar(void)
|
||||
{
|
||||
size_t base = strlenpt(prompt) + 2;
|
||||
size_t base = breadth(prompt) + 2;
|
||||
size_t the_page, end_page, column;
|
||||
char *expanded;
|
||||
|
||||
the_page = get_statusbar_page_start(base, base + strnlenpt(answer, typing_x));
|
||||
end_page = get_statusbar_page_start(base, base + strlenpt(answer) - 1);
|
||||
the_page = get_statusbar_page_start(base, base + wideness(answer, typing_x));
|
||||
end_page = get_statusbar_page_start(base, base + breadth(answer) - 1);
|
||||
|
||||
/* Color the promptbar over its full width. */
|
||||
wattron(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
@@ -404,7 +404,7 @@ void draw_the_promptbar(void)
|
||||
waddstr(bottomwin, expanded);
|
||||
free(expanded);
|
||||
|
||||
if (base + strlenpt(answer) != COLS && the_page < end_page)
|
||||
if (base + breadth(answer) != COLS && the_page < end_page)
|
||||
mvwaddch(bottomwin, 0, COLS - 1, '>');
|
||||
|
||||
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
@@ -414,7 +414,7 @@ void draw_the_promptbar(void)
|
||||
wrefresh(bottomwin);
|
||||
|
||||
/* Place the cursor at the right spot. */
|
||||
column = base + strnlenpt(answer, typing_x);
|
||||
column = base + wideness(answer, typing_x);
|
||||
wmove(bottomwin, 0, column - get_statusbar_page_start(base, column));
|
||||
wnoutrefresh(bottomwin);
|
||||
}
|
||||
@@ -667,7 +667,7 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
if (!ISSET(NO_HELP)) {
|
||||
char shortstr[MAXCHARLEN + 2];
|
||||
/* Temporary string for (translated) " Y", " N" and " A". */
|
||||
const sc *cancelshortcut = first_sc_for(MYESNO, do_cancel);
|
||||
const keystruct *cancelshortcut = first_sc_for(MYESNO, do_cancel);
|
||||
/* The keystroke that is bound to the Cancel function. */
|
||||
|
||||
if (COLS < 32)
|
||||
|
||||
33
src/proto.h
33
src/proto.h
@@ -98,7 +98,9 @@ extern bool keep_cutbuffer;
|
||||
|
||||
extern partition *filepart;
|
||||
extern openfilestruct *openfile;
|
||||
extern openfilestruct *firstfile;
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
extern openfilestruct *startfile;
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern char *matchbrackets;
|
||||
@@ -143,9 +145,9 @@ extern bool have_palette;
|
||||
extern bool refresh_needed;
|
||||
|
||||
extern int currmenu;
|
||||
extern sc *sclist;
|
||||
extern subnfunc *allfuncs;
|
||||
extern subnfunc *exitfunc;
|
||||
extern keystruct *sclist;
|
||||
extern funcstruct *allfuncs;
|
||||
extern funcstruct *exitfunc;
|
||||
|
||||
extern linestruct *search_history;
|
||||
extern linestruct *replace_history;
|
||||
@@ -315,17 +317,17 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
|
||||
/* Some functions in global.c. */
|
||||
size_t length_of_list(int menu);
|
||||
const sc *first_sc_for(int menu, void (*func)(void));
|
||||
const keystruct *first_sc_for(int menu, void (*func)(void));
|
||||
int the_code_for(void (*func)(void), int defaultval);
|
||||
functionptrtype func_from_key(int *kbinput);
|
||||
int keycode_from_string(const char *keystring);
|
||||
void assign_keyinfo(sc *s, const char *keystring, const int keycode);
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode);
|
||||
void print_sclist(void);
|
||||
void shortcut_init(void);
|
||||
const subnfunc *sctofunc(const sc *s);
|
||||
const funcstruct *sctofunc(const keystruct *s);
|
||||
const char *flagtostr(int flag);
|
||||
#ifdef ENABLE_NANORC
|
||||
sc *strtosc(const char *input);
|
||||
keystruct *strtosc(const char *input);
|
||||
int name_to_menu(const char *name);
|
||||
char *menu_to_name(int menu);
|
||||
#endif
|
||||
@@ -424,6 +426,9 @@ RETSIGTYPE handle_crash(int signal);
|
||||
#endif
|
||||
RETSIGTYPE do_suspend(int signal);
|
||||
RETSIGTYPE do_continue(int signal);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER)
|
||||
void block_sigwinch(bool blockit);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE handle_sigwinch(int signal);
|
||||
void regenerate_screen(void);
|
||||
@@ -437,7 +442,7 @@ void terminal_init(void);
|
||||
void confirm_margin(void);
|
||||
#endif
|
||||
void unbound_key(int code);
|
||||
bool okay_for_view(const sc *shortcut);
|
||||
bool okay_for_view(const keystruct *shortcut);
|
||||
void do_output(char *output, size_t output_len, bool allow_cntrls);
|
||||
|
||||
/* Most functions in prompt.c. */
|
||||
@@ -520,8 +525,7 @@ void update_multiline_undo(ssize_t lineno, char *indentation);
|
||||
void update_undo(undo_type action);
|
||||
#endif /* !NANO_TINY */
|
||||
#ifdef ENABLE_WRAPPING
|
||||
void wrap_reset(void);
|
||||
bool do_wrap(linestruct *line);
|
||||
bool do_wrap(void);
|
||||
#endif
|
||||
#if defined(ENABLE_HELP) || defined(ENABLED_WRAPORJUSTIFY)
|
||||
ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl);
|
||||
@@ -557,7 +561,6 @@ int digits(ssize_t n);
|
||||
#endif
|
||||
bool parse_num(const char *str, ssize_t *val);
|
||||
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column);
|
||||
void null_at(char **data, size_t index);
|
||||
void unsunder(char *str, size_t true_len);
|
||||
void sunder(char *str);
|
||||
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
|
||||
@@ -577,8 +580,8 @@ char *free_and_assign(char *dest, char *src);
|
||||
size_t get_page_start(size_t column);
|
||||
size_t xplustabs(void);
|
||||
size_t actual_x(const char *text, size_t column);
|
||||
size_t strnlenpt(const char *text, size_t maxlen);
|
||||
size_t strlenpt(const char *text);
|
||||
size_t wideness(const char *text, size_t maxlen);
|
||||
size_t breadth(const char *text);
|
||||
void new_magicline(void);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
void remove_magicline(void);
|
||||
@@ -613,7 +616,7 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count);
|
||||
#ifdef ENABLE_MOUSE
|
||||
int get_mouseinput(int *mouse_row, int *mouse_col, bool allow_shortcuts);
|
||||
#endif
|
||||
const sc *get_shortcut(int *kbinput);
|
||||
const keystruct *get_shortcut(int *kbinput);
|
||||
void blank_row(WINDOW *win, int y, int x, int n);
|
||||
void blank_edit(void);
|
||||
void blank_statusbar(void);
|
||||
|
||||
25
src/rcfile.c
25
src/rcfile.c
@@ -50,7 +50,6 @@ static const rcoption rcopts[] = {
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
{"fill", 0},
|
||||
#endif
|
||||
{"finalnewline", FINAL_NEWLINE},
|
||||
#ifdef ENABLE_HISTORIES
|
||||
{"historylog", HISTORYLOG},
|
||||
#endif
|
||||
@@ -66,7 +65,7 @@ static const rcoption rcopts[] = {
|
||||
{"multibuffer", MULTIBUFFER},
|
||||
#endif
|
||||
{"nohelp", NO_HELP},
|
||||
{"nonewlines", NO_NEWLINES}, /* Deprecated; remove in 2021. */
|
||||
{"nonewlines", NO_NEWLINES},
|
||||
{"nopauses", NO_PAUSES},
|
||||
#ifdef ENABLE_WRAPPING
|
||||
{"nowrap", NO_WRAP}, /* Deprecated; remove in 2021. */
|
||||
@@ -347,9 +346,9 @@ bool is_universal(void (*func)(void))
|
||||
void parse_binding(char *ptr, bool dobind)
|
||||
{
|
||||
char *keyptr = NULL, *keycopy = NULL, *funcptr = NULL, *menuptr = NULL;
|
||||
sc *s, *newsc = NULL;
|
||||
keystruct *s, *newsc = NULL;
|
||||
int menu, mask = 0;
|
||||
subnfunc *f;
|
||||
funcstruct *f;
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(N_("Missing key name"));
|
||||
@@ -413,7 +412,7 @@ void parse_binding(char *ptr, bool dobind)
|
||||
/* If the thing to bind starts with a double quote, it is a string,
|
||||
* otherwise it is the name of a function. */
|
||||
if (*funcptr == '"') {
|
||||
newsc = nmalloc(sizeof(sc));
|
||||
newsc = nmalloc(sizeof(keystruct));
|
||||
newsc->func = (functionptrtype)implant;
|
||||
newsc->expansion = mallocstrcpy(NULL, funcptr + 1);
|
||||
#ifndef NANO_TINY
|
||||
@@ -462,7 +461,7 @@ void parse_binding(char *ptr, bool dobind)
|
||||
menu = menu & (is_universal(newsc->func) ? MMOST : mask);
|
||||
|
||||
if (!menu) {
|
||||
if (!ISSET(RESTRICTED))
|
||||
if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE))
|
||||
rcfile_error(N_("Function '%s' does not exist in menu '%s'"),
|
||||
funcptr, menuptr);
|
||||
goto free_things;
|
||||
@@ -556,7 +555,7 @@ void parse_includes(char *ptr)
|
||||
|
||||
/* Expand a tilde first, then try to match the globbing pattern. */
|
||||
expanded = real_dir_from_tilde(pattern);
|
||||
result = glob(expanded, GLOB_ERR|GLOB_NOSORT, NULL, &files);
|
||||
result = glob(expanded, GLOB_ERR, NULL, &files);
|
||||
|
||||
/* If there are matches, process each of them. Otherwise, only
|
||||
* report an error if it's something other than zero matches. */
|
||||
@@ -884,7 +883,7 @@ void pick_up_name(const char *kind, char *ptr, char **storage)
|
||||
* function that we consider 'vital' (such as "Exit"). */
|
||||
static void check_vitals_mapped(void)
|
||||
{
|
||||
subnfunc *f;
|
||||
funcstruct *f;
|
||||
int v;
|
||||
#define VITALS 3
|
||||
void (*vitals[VITALS])(void) = { do_exit, do_exit, do_cancel };
|
||||
@@ -893,7 +892,7 @@ static void check_vitals_mapped(void)
|
||||
for (v = 0; v < VITALS; v++) {
|
||||
for (f = allfuncs; f != NULL; f = f->next) {
|
||||
if (f->func == vitals[v] && f->menus & inmenus[v]) {
|
||||
const sc *s = first_sc_for(inmenus[v], f->func);
|
||||
const keystruct *s = first_sc_for(inmenus[v], f->func);
|
||||
if (!s) {
|
||||
fprintf(stderr, _("No key is bound to function '%s' in "
|
||||
"menu '%s'. Exiting.\n"), f->desc,
|
||||
@@ -1126,15 +1125,17 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
|
||||
stripe_column = 0;
|
||||
}
|
||||
free(option);
|
||||
}
|
||||
if (strcasecmp(rcopts[i].name, "matchbrackets") == 0) {
|
||||
} else if (strcasecmp(rcopts[i].name, "matchbrackets") == 0) {
|
||||
if (has_blank_char(option)) {
|
||||
rcfile_error(N_("Non-blank characters required"));
|
||||
free(option);
|
||||
} else if (mbstrlen(option) % 2 != 0) {
|
||||
rcfile_error(N_("Even number of characters required"));
|
||||
free(option);
|
||||
} else
|
||||
matchbrackets = option;
|
||||
} else if (strcasecmp(rcopts[i].name, "whitespace") == 0) {
|
||||
if (mbstrlen(option) != 2 || strlenpt(option) != 2) {
|
||||
if (mbstrlen(option) != 2 || breadth(option) != 2) {
|
||||
rcfile_error(N_("Two single-column characters required"));
|
||||
free(option);
|
||||
} else {
|
||||
|
||||
152
src/search.c
152
src/search.c
@@ -88,7 +88,7 @@ void search_init(bool replacing, bool keep_the_answer)
|
||||
thedefault = charalloc(strlen(disp) + 7);
|
||||
/* We use (COLS / 3) here because we need to see more on the line. */
|
||||
sprintf(thedefault, " [%s%s]", disp,
|
||||
(strlenpt(last_search) > COLS / 3) ? "..." : "");
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
thedefault = mallocstrcpy(NULL, "");
|
||||
@@ -389,7 +389,7 @@ void do_findnext(void)
|
||||
void not_found_msg(const char *str)
|
||||
{
|
||||
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE, FALSE);
|
||||
size_t numchars = actual_x(disp, strnlenpt(disp, COLS / 2));
|
||||
size_t numchars = actual_x(disp, wideness(disp, COLS / 2));
|
||||
|
||||
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
|
||||
(disp[numchars] == '\0') ? "" : "...");
|
||||
@@ -577,7 +577,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
if (!replaceall) {
|
||||
spotlighted = TRUE;
|
||||
light_from_col = xplustabs();
|
||||
light_to_col = strnlenpt(openfile->current->data,
|
||||
light_to_col = wideness(openfile->current->data,
|
||||
openfile->current_x + match_len);
|
||||
|
||||
/* Refresh the edit window, scrolling it if necessary. */
|
||||
@@ -681,7 +681,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
|
||||
/* If "automatic newline" is enabled, and text has been added to the
|
||||
* magic line, make a new magic line. */
|
||||
if (ISSET(FINAL_NEWLINE) && openfile->filebot->data[0] != '\0')
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
|
||||
return numreplaced;
|
||||
@@ -810,7 +810,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
|
||||
/* Take a negative column number to mean: from the end of the line. */
|
||||
if (column < 0)
|
||||
column = strlenpt(openfile->current->data) + column + 2;
|
||||
column = breadth(openfile->current->data) + column + 2;
|
||||
if (column < 1)
|
||||
column = 1;
|
||||
|
||||
@@ -820,8 +820,8 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP) && openfile->placewewant / editwincols >
|
||||
strlenpt(openfile->current->data) / editwincols)
|
||||
openfile->placewewant = strlenpt(openfile->current->data);
|
||||
breadth(openfile->current->data) / editwincols)
|
||||
openfile->placewewant = breadth(openfile->current->data);
|
||||
#endif
|
||||
|
||||
/* When the position was manually given, center the target line. */
|
||||
@@ -862,58 +862,53 @@ void do_gotolinecolumn_void(void)
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Search for a match to one of the two characters in bracket_set. If
|
||||
* reverse is TRUE, search backwards for the leftmost bracket.
|
||||
* Otherwise, search forwards for the rightmost bracket. Return TRUE if
|
||||
* we found a match, and FALSE otherwise. */
|
||||
/* Search, starting from the current position, for any of the two characters
|
||||
* in bracket_set. If reverse is TRUE, search backwards, otherwise forwards.
|
||||
* Return TRUE when one of the brackets was found, and FALSE otherwise. */
|
||||
bool find_bracket_match(bool reverse, const char *bracket_set)
|
||||
{
|
||||
linestruct *fileptr = openfile->current;
|
||||
const char *rev_start = NULL, *found = NULL;
|
||||
linestruct *line = openfile->current;
|
||||
const char *pointer = line->data + openfile->current_x;
|
||||
const char *found = NULL;
|
||||
|
||||
assert(mbstrlen(bracket_set) == 2);
|
||||
/* Step away from the current bracket, either backwards or forwards. */
|
||||
if (reverse) {
|
||||
if (--pointer < line->data) {
|
||||
line = line->prev;
|
||||
if (line == NULL)
|
||||
return FALSE;
|
||||
pointer = line->data + strlen(line->data);
|
||||
}
|
||||
} else
|
||||
++pointer;
|
||||
|
||||
/* rev_start might end up 1 character before the start or after the
|
||||
* end of the line. This won't be a problem because we'll skip over
|
||||
* it below in that case, and rev_start will be properly set when
|
||||
* the search continues on the previous or next line. */
|
||||
if (reverse)
|
||||
rev_start = fileptr->data + (openfile->current_x - 1);
|
||||
else
|
||||
rev_start = fileptr->data + (openfile->current_x + 1);
|
||||
|
||||
/* Look for either of the two characters in bracket_set. rev_start
|
||||
* can be 1 character before the start or after the end of the line.
|
||||
* In either case, just act as though no match is found. */
|
||||
/* Now seek for any of the two brackets, either backwards or forwards. */
|
||||
while (TRUE) {
|
||||
if ((rev_start > fileptr->data && *(rev_start - 1) == '\0') ||
|
||||
rev_start < fileptr->data)
|
||||
found = NULL;
|
||||
else if (reverse)
|
||||
found = mbrevstrpbrk(fileptr->data, bracket_set, rev_start);
|
||||
if (reverse)
|
||||
found = mbrevstrpbrk(line->data, bracket_set, pointer);
|
||||
else
|
||||
found = mbstrpbrk(rev_start, bracket_set);
|
||||
found = mbstrpbrk(pointer, bracket_set);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
|
||||
if (reverse)
|
||||
fileptr = fileptr->prev;
|
||||
line = line->prev;
|
||||
else
|
||||
fileptr = fileptr->next;
|
||||
line = line->next;
|
||||
|
||||
/* If we've reached the start or end of the buffer, get out. */
|
||||
if (fileptr == NULL)
|
||||
if (line == NULL)
|
||||
return FALSE;
|
||||
|
||||
rev_start = fileptr->data;
|
||||
pointer = line->data;
|
||||
if (reverse)
|
||||
rev_start += strlen(fileptr->data);
|
||||
pointer += strlen(line->data);
|
||||
}
|
||||
|
||||
/* Set the current position to the found matching bracket. */
|
||||
openfile->current = fileptr;
|
||||
openfile->current_x = found - fileptr->data;
|
||||
/* Set the current position to the found bracket. */
|
||||
openfile->current = line;
|
||||
openfile->current_x = found - line->data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -922,73 +917,52 @@ bool find_bracket_match(bool reverse, const char *bracket_set)
|
||||
* there is one. */
|
||||
void do_find_bracket(void)
|
||||
{
|
||||
linestruct *current_save;
|
||||
size_t current_x_save;
|
||||
linestruct *was_current = openfile->current;
|
||||
size_t was_current_x = openfile->current_x;
|
||||
/* The current cursor position, in case we don't find a complement. */
|
||||
const char *ch;
|
||||
/* The location in matchbrackets of the bracket at the current
|
||||
* cursor position. */
|
||||
/* The location in matchbrackets of the bracket under the cursor. */
|
||||
int ch_len;
|
||||
/* The length of ch in bytes. */
|
||||
const char *wanted_ch;
|
||||
/* The location in matchbrackets of the bracket complementing
|
||||
* the bracket at the current cursor position. */
|
||||
/* The location in matchbrackets of the complementing bracket. */
|
||||
int wanted_ch_len;
|
||||
/* The length of wanted_ch in bytes. */
|
||||
char bracket_set[MAXCHARLEN * 2 + 1];
|
||||
/* The pair of characters in ch and wanted_ch. */
|
||||
size_t i;
|
||||
/* Generic loop variable. */
|
||||
size_t matchhalf;
|
||||
/* The number of single-byte characters in one half of
|
||||
* matchbrackets. */
|
||||
size_t mbmatchhalf;
|
||||
/* The number of multibyte characters in one half of
|
||||
* matchbrackets. */
|
||||
size_t count = 1;
|
||||
size_t halfway = 0;
|
||||
/* The index in matchbrackets where the closing brackets start. */
|
||||
size_t charcount = mbstrlen(matchbrackets) / 2;
|
||||
/* Half the number of characters in matchbrackets. */
|
||||
size_t balance = 1;
|
||||
/* The initial bracket count. */
|
||||
bool reverse;
|
||||
/* The direction we search. */
|
||||
|
||||
assert(mbstrlen(matchbrackets) % 2 == 0);
|
||||
ch = mbstrchr(matchbrackets, openfile->current->data + openfile->current_x);
|
||||
|
||||
ch = openfile->current->data + openfile->current_x;
|
||||
|
||||
if ((ch = mbstrchr(matchbrackets, ch)) == NULL) {
|
||||
if (ch == NULL) {
|
||||
statusbar(_("Not a bracket"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save where we are. */
|
||||
current_save = openfile->current;
|
||||
current_x_save = openfile->current_x;
|
||||
/* Find the halfway point in matchbrackets, where the closing ones start. */
|
||||
for (size_t i = 0; i < charcount; i++)
|
||||
halfway += parse_mbchar(matchbrackets + halfway, NULL, NULL);
|
||||
|
||||
/* If we're on an opening bracket, which must be in the first half
|
||||
* of matchbrackets, we want to search forwards for a closing
|
||||
* bracket. If we're on a closing bracket, which must be in the
|
||||
* second half of matchbrackets, we want to search backwards for an
|
||||
* opening bracket. */
|
||||
matchhalf = 0;
|
||||
mbmatchhalf = mbstrlen(matchbrackets) / 2;
|
||||
/* When on a closing bracket, we have to search backwards for a matching
|
||||
* opening bracket; otherwise, forward for a matching closing bracket. */
|
||||
reverse = (ch >= (matchbrackets + halfway));
|
||||
|
||||
for (i = 0; i < mbmatchhalf; i++)
|
||||
matchhalf += parse_mbchar(matchbrackets + matchhalf, NULL, NULL);
|
||||
|
||||
reverse = ((ch - matchbrackets) >= matchhalf);
|
||||
|
||||
/* If we're on an opening bracket, set wanted_ch to the character
|
||||
* that's matchhalf characters after ch. If we're on a closing
|
||||
* bracket, set wanted_ch to the character that's matchhalf
|
||||
* characters before ch. */
|
||||
/* Step half the number of total characters either backwards or forwards
|
||||
* through matchbrackets to find the wanted complementary bracket. */
|
||||
wanted_ch = ch;
|
||||
|
||||
while (mbmatchhalf > 0) {
|
||||
while (charcount-- > 0) {
|
||||
if (reverse)
|
||||
wanted_ch = matchbrackets + move_mbleft(matchbrackets,
|
||||
wanted_ch - matchbrackets);
|
||||
else
|
||||
wanted_ch += move_mbright(wanted_ch, 0);
|
||||
|
||||
mbmatchhalf--;
|
||||
}
|
||||
|
||||
ch_len = parse_mbchar(ch, NULL, NULL);
|
||||
@@ -1001,23 +975,23 @@ void do_find_bracket(void)
|
||||
|
||||
while (TRUE) {
|
||||
if (find_bracket_match(reverse, bracket_set)) {
|
||||
/* If we found an identical bracket, increment count. If we
|
||||
/* If we found an identical bracket, increment balance. If we
|
||||
* found a complementary bracket, decrement it. */
|
||||
count += (strncmp(openfile->current->data + openfile->current_x,
|
||||
balance += (strncmp(openfile->current->data + openfile->current_x,
|
||||
ch, ch_len) == 0) ? 1 : -1;
|
||||
|
||||
/* If count is zero, we've found a matching bracket. Update
|
||||
/* If balance is zero, we've found a matching bracket. Update
|
||||
* the screen and get out. */
|
||||
if (count == 0) {
|
||||
edit_redraw(current_save, FLOWING);
|
||||
if (balance == 0) {
|
||||
edit_redraw(was_current, FLOWING);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* We didn't find either an opening or closing bracket.
|
||||
* Indicate this, restore where we were, and get out. */
|
||||
statusbar(_("No matching bracket"));
|
||||
openfile->current = current_save;
|
||||
openfile->current_x = current_x_save;
|
||||
openfile->current = was_current;
|
||||
openfile->current_x = was_current_x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
466
src/text.c
466
src/text.c
@@ -35,11 +35,6 @@
|
||||
static pid_t pid_of_command = -1;
|
||||
/* The PID of the forked process -- needed when wanting to abort it. */
|
||||
#endif
|
||||
#ifdef ENABLE_WRAPPING
|
||||
static bool prepend_wrap = FALSE;
|
||||
/* Should we prepend wrapped text to the next line? */
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
static int pletion_x = 0;
|
||||
/* The x position in pletion_line of the last found completion. */
|
||||
@@ -65,8 +60,9 @@ void do_mark(void)
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#if defined(ENABLE_COLOR) || defined(ENABLE_SPELLER)
|
||||
/* Return an error message about invoking the given name. */
|
||||
char *invocation_error(const char *name)
|
||||
/* Return an error message about invoking the given name. The message
|
||||
* should not be freed; this leak is not worth the trouble avoiding. */
|
||||
const char *invocation_error(const char *name)
|
||||
{
|
||||
char *message, *invoke_error = _("Error invoking \"%s\"");
|
||||
|
||||
@@ -167,6 +163,7 @@ void do_indent(void)
|
||||
free(indentation);
|
||||
|
||||
set_modified();
|
||||
ensure_firstcolumn_is_aligned();
|
||||
refresh_needed = TRUE;
|
||||
shift_held = TRUE;
|
||||
}
|
||||
@@ -262,6 +259,7 @@ void do_unindent(void)
|
||||
}
|
||||
|
||||
set_modified();
|
||||
ensure_firstcolumn_is_aligned();
|
||||
refresh_needed = TRUE;
|
||||
shift_held = TRUE;
|
||||
}
|
||||
@@ -323,7 +321,7 @@ bool comment_line(undo_type action, linestruct *line, const char *comment_seq)
|
||||
/* Length of postfix. */
|
||||
size_t line_len = strlen(line->data);
|
||||
|
||||
if (ISSET(FINAL_NEWLINE) && line == openfile->filebot)
|
||||
if (!ISSET(NO_NEWLINES) && line == openfile->filebot)
|
||||
return FALSE;
|
||||
|
||||
if (action == COMMENT) {
|
||||
@@ -393,7 +391,7 @@ void do_comment(void)
|
||||
get_range((const linestruct **)&top, (const linestruct **)&bot);
|
||||
|
||||
/* If only the magic line is selected, don't do anything. */
|
||||
if (top == bot && bot == openfile->filebot && ISSET(FINAL_NEWLINE)) {
|
||||
if (top == bot && bot == openfile->filebot && !ISSET(NO_NEWLINES)) {
|
||||
statusbar(_("Cannot comment past end of file"));
|
||||
return;
|
||||
}
|
||||
@@ -427,6 +425,7 @@ void do_comment(void)
|
||||
}
|
||||
|
||||
set_modified();
|
||||
ensure_firstcolumn_is_aligned();
|
||||
refresh_needed = TRUE;
|
||||
shift_held = TRUE;
|
||||
}
|
||||
@@ -480,7 +479,7 @@ void undo_cut(undo *u)
|
||||
copy_from_buffer(u->cutbuffer);
|
||||
|
||||
/* If the final line was originally cut, remove the extra magic line. */
|
||||
if ((u->xflags & WAS_FINAL_LINE) && ISSET(FINAL_NEWLINE) &&
|
||||
if ((u->xflags & WAS_FINAL_LINE) && !ISSET(NO_NEWLINES) &&
|
||||
openfile->current != openfile->filebot)
|
||||
remove_magicline();
|
||||
|
||||
@@ -521,8 +520,8 @@ void do_undo(void)
|
||||
char *data, *undidmsg = NULL;
|
||||
size_t from_x, to_x;
|
||||
|
||||
if (!u) {
|
||||
statusbar(_("Nothing in undo buffer!"));
|
||||
if (u == NULL) {
|
||||
statusbar(_("Nothing to undo"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -538,7 +537,7 @@ void do_undo(void)
|
||||
/* TRANSLATORS: The next thirteen strings describe actions
|
||||
* that are undone or redone. They are all nouns, not verbs. */
|
||||
undidmsg = _("addition");
|
||||
if ((u->xflags & WAS_FINAL_LINE) && ISSET(FINAL_NEWLINE))
|
||||
if ((u->xflags & WAS_FINAL_LINE) && !ISSET(NO_NEWLINES))
|
||||
remove_magicline();
|
||||
data = charalloc(strlen(f->data) - strlen(u->strdata) + 1);
|
||||
strncpy(data, f->data, u->begin);
|
||||
@@ -548,10 +547,6 @@ void do_undo(void)
|
||||
goto_line_posx(u->lineno, u->begin);
|
||||
break;
|
||||
case ENTER:
|
||||
if (f->next == NULL) {
|
||||
statusline(ALERT, "Missing break line -- please report a bug");
|
||||
break;
|
||||
}
|
||||
undidmsg = _("line break");
|
||||
from_x = (u->begin == 0) ? 0 : u->mark_begin_x;
|
||||
to_x = (u->begin == 0) ? u->mark_begin_x : u->begin;
|
||||
@@ -578,7 +573,7 @@ void do_undo(void)
|
||||
/* When the join was done by a Backspace at the tail of the file,
|
||||
* and the nonewlines flag isn't set, do not re-add a newline that
|
||||
* wasn't actually deleted; just position the cursor. */
|
||||
if ((u->xflags & WAS_FINAL_BACKSPACE) && ISSET(FINAL_NEWLINE)) {
|
||||
if ((u->xflags & WAS_FINAL_BACKSPACE) && !ISSET(NO_NEWLINES)) {
|
||||
goto_line_posx(openfile->filebot->lineno, 0);
|
||||
break;
|
||||
}
|
||||
@@ -669,7 +664,6 @@ void do_undo(void)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
statusline(ALERT, "Wrong undo type -- please report a bug");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -699,19 +693,14 @@ void do_redo(void)
|
||||
undo *u = openfile->undotop;
|
||||
|
||||
if (u == NULL || u == openfile->current_undo) {
|
||||
statusbar(_("Nothing to re-do!"));
|
||||
statusbar(_("Nothing to redo"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the previous undo item. */
|
||||
while (u != NULL && u->next != openfile->current_undo)
|
||||
/* Find the item before the current one in the undo stack. */
|
||||
while (u->next != openfile->current_undo)
|
||||
u = u->next;
|
||||
|
||||
if (u == NULL) {
|
||||
statusline(ALERT, "Bad undo stack -- please report a bug");
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->type <= REPLACE) {
|
||||
f = fsfromline(u->mark_begin_lineno);
|
||||
if (f == NULL)
|
||||
@@ -721,7 +710,7 @@ void do_redo(void)
|
||||
switch (u->type) {
|
||||
case ADD:
|
||||
redidmsg = _("addition");
|
||||
if ((u->xflags & WAS_FINAL_LINE) && ISSET(FINAL_NEWLINE))
|
||||
if ((u->xflags & WAS_FINAL_LINE) && !ISSET(NO_NEWLINES))
|
||||
new_magicline();
|
||||
data = charalloc(strlen(f->data) + strlen(u->strdata) + 1);
|
||||
strncpy(data, f->data, u->begin);
|
||||
@@ -754,15 +743,11 @@ void do_redo(void)
|
||||
goto_line_posx(u->lineno, u->begin);
|
||||
break;
|
||||
case JOIN:
|
||||
if (f->next == NULL) {
|
||||
statusline(ALERT, "Missing join line -- please report a bug");
|
||||
break;
|
||||
}
|
||||
redidmsg = _("line join");
|
||||
/* When the join was done by a Backspace at the tail of the file,
|
||||
* and the nonewlines flag isn't set, do not join anything, as
|
||||
* nothing was actually deleted; just position the cursor. */
|
||||
if ((u->xflags & WAS_FINAL_BACKSPACE) && ISSET(FINAL_NEWLINE)) {
|
||||
if ((u->xflags & WAS_FINAL_BACKSPACE) && !ISSET(NO_NEWLINES)) {
|
||||
goto_line_posx(u->mark_begin_lineno, u->mark_begin_x);
|
||||
break;
|
||||
}
|
||||
@@ -840,7 +825,6 @@ void do_redo(void)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
statusline(ALERT, "Wrong redo type -- please report a bug");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -903,7 +887,8 @@ void do_enter(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
null_at(&openfile->current->data, openfile->current_x);
|
||||
/* Make the current line end at the cursor position. */
|
||||
openfile->current->data[openfile->current_x] = '\0';
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(ENTER);
|
||||
@@ -1019,6 +1004,8 @@ bool execute_command(const char *command)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
statusbar(_("Executing..."));
|
||||
|
||||
/* If the command starts with "|", pipe buffer or region to the command. */
|
||||
if (should_pipe) {
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
@@ -1263,7 +1250,6 @@ void add_undo(undo_type action)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
statusline(ALERT, "Wrong undo adding type -- please report a bug");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1402,7 +1388,7 @@ void update_undo(undo_type action)
|
||||
if (u->lineno == u->mark_begin_lineno)
|
||||
u->begin += u->mark_begin_x;
|
||||
} else if (openfile->current == openfile->filebot &&
|
||||
!ISSET(FINAL_NEWLINE))
|
||||
ISSET(NO_NEWLINES))
|
||||
u->begin = strlen(u->cutbottom->data);
|
||||
}
|
||||
break;
|
||||
@@ -1416,103 +1402,72 @@ void update_undo(undo_type action)
|
||||
u->begin = openfile->current_x;
|
||||
break;
|
||||
default:
|
||||
statusline(ALERT, "Wrong undo update type -- please report a bug");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifdef ENABLE_WRAPPING
|
||||
/* Unset the prepend_wrap flag. We need to do this as soon as we do
|
||||
* something other than type text. */
|
||||
void wrap_reset(void)
|
||||
{
|
||||
prepend_wrap = FALSE;
|
||||
}
|
||||
|
||||
/* Try wrapping the given line. Return TRUE if wrapped, FALSE otherwise. */
|
||||
bool do_wrap(linestruct *line)
|
||||
/* When the current line is overlong, hard-wrap it at the furthest possible
|
||||
* whitespace character, and (if possible) prepend the remainder of the line
|
||||
* to the next line. Return TRUE if wrapping occurred, and FALSE otherwise. */
|
||||
bool do_wrap(void)
|
||||
{
|
||||
linestruct *line = openfile->current;
|
||||
/* The line to be wrapped, if needed and possible. */
|
||||
size_t line_len = strlen(line->data);
|
||||
/* The length of the line we wrap. */
|
||||
/* The length of this line. */
|
||||
size_t cursor_x = openfile->current_x;
|
||||
/* The current cursor position, for comparison with the wrap point. */
|
||||
ssize_t wrap_loc;
|
||||
/* The index of line->data where we wrap. */
|
||||
/* The position in the line's text where we wrap. */
|
||||
const char *remainder;
|
||||
/* The text after the wrap point. */
|
||||
size_t rest_length;
|
||||
/* The length of the remainder. */
|
||||
|
||||
size_t old_x = openfile->current_x;
|
||||
linestruct *old_line = openfile->current;
|
||||
|
||||
/* There are three steps. First, we decide where to wrap. Then, we
|
||||
* create the new wrap line. Finally, we clean up. */
|
||||
|
||||
/* Step 1, finding where to wrap. We are going to add a new line
|
||||
* after a blank character. In this step, we call break_line() to
|
||||
* get the location of the last blank we can break the line at, and
|
||||
* set wrap_loc to the location of the character after it, so that
|
||||
* the blank is preserved at the end of the line.
|
||||
*
|
||||
* If there is no legal wrap point, or we reach the last character
|
||||
* of the line while trying to find one, we should return without
|
||||
* wrapping. Note that if autoindent is turned on, we don't break
|
||||
* at the end of it! */
|
||||
|
||||
/* Find the last blank where we can break the line. */
|
||||
/* First find the last blank character where we can break the line. */
|
||||
wrap_loc = break_line(line->data, wrap_at, FALSE);
|
||||
|
||||
/* If we couldn't break the line, or we've reached the end of it, we
|
||||
* don't wrap. */
|
||||
/* If no wrapping point was found before end-of-line, we don't wrap. */
|
||||
if (wrap_loc == -1 || line->data[wrap_loc] == '\0')
|
||||
return FALSE;
|
||||
|
||||
/* Otherwise, move forward to the character just after the blank. */
|
||||
/* Step forward to the character just after the blank. */
|
||||
wrap_loc += move_mbright(line->data + wrap_loc, 0);
|
||||
|
||||
/* If we've reached the end of the line, we don't wrap. */
|
||||
/* When now at end-of-line, no need to wrap. */
|
||||
if (line->data[wrap_loc] == '\0')
|
||||
return FALSE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If autoindent is turned on, and we're on the character just after
|
||||
* the indentation, we don't wrap. */
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
openfile->current = line;
|
||||
|
||||
/* Step 2, making the new wrap line. It will consist of indentation
|
||||
* followed by the text after the wrap point, optionally followed by
|
||||
* a space (if the text after the wrap point doesn't end in a blank)
|
||||
* and the text of the next line, if they can fit without wrapping,
|
||||
* the next line exists, and the prepend_wrap flag is set. */
|
||||
|
||||
/* The remainder is the text that will be wrapped to the next line. */
|
||||
remainder = line->data + wrap_loc;
|
||||
rest_length = line_len - wrap_loc;
|
||||
|
||||
/* We prepend the wrapped text to the next line, if the prepend_wrap
|
||||
* flag is set, there is a next line, and prepending would not make
|
||||
* the line too long. */
|
||||
if (prepend_wrap && line != openfile->filebot) {
|
||||
const char *tail = remainder + move_mbleft(remainder, rest_length);
|
||||
|
||||
/* Go to the end of the line. */
|
||||
/* When prepending and the remainder of this line will not make the next
|
||||
* line too long, then join the two lines, so that, after the line wrap,
|
||||
* the remainder will effectively have been prefixed to the next line. */
|
||||
if (openfile->spillage_line && openfile->spillage_line == line->next &&
|
||||
rest_length + breadth(line->next->data) <= wrap_at) {
|
||||
/* Go to the end of this line. */
|
||||
openfile->current_x = line_len;
|
||||
|
||||
/* If the remainder doesn't end in a blank, add a space. */
|
||||
if (!is_blank_mbchar(tail)) {
|
||||
if (!is_blank_mbchar(remainder + move_mbleft(remainder, rest_length))) {
|
||||
#ifndef NANO_TINY
|
||||
add_undo(ADD);
|
||||
#endif
|
||||
line->data = charealloc(line->data, line_len + 2);
|
||||
line->data[line_len] = ' ';
|
||||
line->data[line_len + 1] = '\0';
|
||||
remainder = line->data + wrap_loc;
|
||||
rest_length++;
|
||||
openfile->totsize++;
|
||||
openfile->current_x++;
|
||||
@@ -1521,13 +1476,10 @@ bool do_wrap(linestruct *line)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (rest_length + strlen(line->next->data) <= wrap_at) {
|
||||
/* Delete the LF to join the two lines. */
|
||||
/* Join the next line to this one, and delete any extra blanks. */
|
||||
do {
|
||||
do_delete();
|
||||
/* Delete any leading blanks from the joined-on line. */
|
||||
while (is_blank_mbchar(&line->data[openfile->current_x]))
|
||||
do_delete();
|
||||
}
|
||||
} while (is_blank_mbchar(&line->data[openfile->current_x]));
|
||||
}
|
||||
|
||||
/* Go to the wrap location. */
|
||||
@@ -1536,9 +1488,10 @@ bool do_wrap(linestruct *line)
|
||||
/* When requested, snip trailing blanks off the wrapped line. */
|
||||
if (ISSET(TRIM_BLANKS)) {
|
||||
size_t tail_x = move_mbleft(line->data, wrap_loc);
|
||||
size_t typed_x = move_mbleft(line->data, old_x);
|
||||
size_t typed_x = move_mbleft(line->data, cursor_x);
|
||||
|
||||
while (tail_x != typed_x && is_blank_mbchar(line->data + tail_x)) {
|
||||
while ((tail_x != typed_x || cursor_x >= wrap_loc) &&
|
||||
is_blank_mbchar(line->data + tail_x)) {
|
||||
openfile->current_x = tail_x;
|
||||
do_delete();
|
||||
tail_x = move_mbleft(line->data, tail_x);
|
||||
@@ -1548,14 +1501,13 @@ bool do_wrap(linestruct *line)
|
||||
/* Now split the line. */
|
||||
do_enter();
|
||||
|
||||
if (old_x < wrap_loc) {
|
||||
openfile->current_x = old_x;
|
||||
openfile->current = old_line;
|
||||
prepend_wrap = TRUE;
|
||||
} else {
|
||||
openfile->current_x += (old_x - wrap_loc);
|
||||
prepend_wrap = FALSE;
|
||||
}
|
||||
openfile->spillage_line = openfile->current;
|
||||
|
||||
if (cursor_x < wrap_loc) {
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_x = cursor_x;
|
||||
} else
|
||||
openfile->current_x += (cursor_x - wrap_loc);
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
@@ -1671,101 +1623,80 @@ size_t indent_length(const char *line)
|
||||
* number of characters untreated. */
|
||||
void squeeze(linestruct *line, size_t skip)
|
||||
{
|
||||
char *end, *new_end, *newdata;
|
||||
size_t shift = 0;
|
||||
char *from, *to, *newdata;
|
||||
size_t shrunk = 0;
|
||||
int charlen;
|
||||
|
||||
end = line->data + skip;
|
||||
newdata = charalloc(strlen(line->data) + 1);
|
||||
strncpy(newdata, line->data, skip);
|
||||
new_end = newdata + skip;
|
||||
|
||||
while (*end != '\0') {
|
||||
int end_len;
|
||||
from = line->data + skip;
|
||||
to = newdata + skip;
|
||||
|
||||
while (*from != '\0') {
|
||||
/* If this character is blank, change it to a space,
|
||||
* and pass over all blanks after it. */
|
||||
if (is_blank_mbchar(end)) {
|
||||
end_len = parse_mbchar(end, NULL, NULL);
|
||||
if (is_blank_mbchar(from)) {
|
||||
from += parse_mbchar(from, NULL, NULL);
|
||||
*(to++) = ' ';
|
||||
|
||||
*new_end = ' ';
|
||||
new_end++;
|
||||
end += end_len;
|
||||
|
||||
while (*end != '\0' && is_blank_mbchar(end)) {
|
||||
end_len = parse_mbchar(end, NULL, NULL);
|
||||
|
||||
end += end_len;
|
||||
shift += end_len;
|
||||
while (*from != '\0' && is_blank_mbchar(from)) {
|
||||
charlen = parse_mbchar(from, NULL, NULL);
|
||||
from += charlen;
|
||||
shrunk += charlen;
|
||||
}
|
||||
/* If this character is punctuation optionally followed by a bracket
|
||||
* and then followed by blanks, change no more than two of the blanks
|
||||
* to spaces if necessary, and pass over all blanks after them. */
|
||||
} else if (mbstrchr(punct, end) != NULL) {
|
||||
end_len = parse_mbchar(end, NULL, NULL);
|
||||
/* If this character is punctuation, then copy it plus a possible
|
||||
* bracket, and change at most two of subsequent blanks to spaces,
|
||||
* and pass over all blanks after these. */
|
||||
} else if (mbstrchr(punct, from) != NULL) {
|
||||
charlen = parse_mbchar(from, NULL, NULL);
|
||||
|
||||
while (end_len > 0) {
|
||||
*new_end = *end;
|
||||
new_end++;
|
||||
end++;
|
||||
end_len--;
|
||||
while (charlen > 0) {
|
||||
*(to++) = *(from++);
|
||||
charlen--;
|
||||
}
|
||||
|
||||
if (*end != '\0' && mbstrchr(brackets, end) != NULL) {
|
||||
end_len = parse_mbchar(end, NULL, NULL);
|
||||
if (*from != '\0' && mbstrchr(brackets, from) != NULL) {
|
||||
charlen = parse_mbchar(from, NULL, NULL);
|
||||
|
||||
while (end_len > 0) {
|
||||
*new_end = *end;
|
||||
new_end++;
|
||||
end++;
|
||||
end_len--;
|
||||
while (charlen > 0) {
|
||||
*(to++) = *(from++);
|
||||
charlen--;
|
||||
}
|
||||
}
|
||||
|
||||
if (*end != '\0' && is_blank_mbchar(end)) {
|
||||
end_len = parse_mbchar(end, NULL, NULL);
|
||||
|
||||
*new_end = ' ';
|
||||
new_end++;
|
||||
end += end_len;
|
||||
if (*from != '\0' && is_blank_mbchar(from)) {
|
||||
from += parse_mbchar(from, NULL, NULL);
|
||||
*(to++) = ' ';
|
||||
}
|
||||
if (*from != '\0' && is_blank_mbchar(from)) {
|
||||
from += parse_mbchar(from, NULL, NULL);
|
||||
*(to++) = ' ';
|
||||
}
|
||||
|
||||
if (*end != '\0' && is_blank_mbchar(end)) {
|
||||
end_len = parse_mbchar(end, NULL, NULL);
|
||||
|
||||
*new_end = ' ';
|
||||
new_end++;
|
||||
end += end_len;
|
||||
}
|
||||
|
||||
while (*end != '\0' && is_blank_mbchar(end)) {
|
||||
end_len = parse_mbchar(end, NULL, NULL);
|
||||
|
||||
end += end_len;
|
||||
shift += end_len;
|
||||
while (*from != '\0' && is_blank_mbchar(from)) {
|
||||
charlen = parse_mbchar(from, NULL, NULL);
|
||||
from += charlen;
|
||||
shrunk += charlen;
|
||||
}
|
||||
/* Leave unchanged anything that is neither blank nor punctuation. */
|
||||
} else {
|
||||
end_len = parse_mbchar(end, NULL, NULL);
|
||||
charlen = parse_mbchar(from, NULL, NULL);
|
||||
|
||||
while (end_len > 0) {
|
||||
*new_end = *end;
|
||||
new_end++;
|
||||
end++;
|
||||
end_len--;
|
||||
while (charlen > 0) {
|
||||
*(to++) = *(from++);
|
||||
charlen--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*new_end = *end;
|
||||
|
||||
/* If there are spaces at the end of the line, remove them. */
|
||||
while (new_end > newdata + skip && *(new_end - 1) == ' ') {
|
||||
new_end--;
|
||||
shift++;
|
||||
while (to > newdata + skip && *(to - 1) == ' ') {
|
||||
to--;
|
||||
shrunk++;
|
||||
}
|
||||
|
||||
if (shift > 0) {
|
||||
null_at(&newdata, new_end - newdata);
|
||||
if (shrunk > 0) {
|
||||
*to = '\0';
|
||||
free(line->data);
|
||||
line->data = newdata;
|
||||
} else
|
||||
@@ -1905,12 +1836,12 @@ void rewrap_paragraph(linestruct **line, char *lead_string, size_t lead_len)
|
||||
ssize_t break_pos;
|
||||
/* The x-coordinate where the current line is to be broken. */
|
||||
|
||||
while (strlenpt((*line)->data) > wrap_at) {
|
||||
while (breadth((*line)->data) > wrap_at) {
|
||||
size_t line_len = strlen((*line)->data);
|
||||
|
||||
/* Find a point in the line where it can be broken. */
|
||||
break_pos = break_line((*line)->data + lead_len,
|
||||
wrap_at - strnlenpt((*line)->data, lead_len), FALSE);
|
||||
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)
|
||||
@@ -1935,7 +1866,7 @@ void rewrap_paragraph(linestruct **line, char *lead_string, size_t lead_len)
|
||||
}
|
||||
|
||||
/* Now actually break the current line, and go to the next. */
|
||||
null_at(&(*line)->data, break_pos);
|
||||
(*line)->data[break_pos] = '\0';
|
||||
*line = (*line)->next;
|
||||
}
|
||||
|
||||
@@ -2027,32 +1958,6 @@ void do_justify(bool full_justify)
|
||||
size_t second_lead_len = 0;
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Do normal justification only when the mark is off. */
|
||||
if (!openfile->mark)
|
||||
#endif
|
||||
{
|
||||
/* When justifying the entire buffer, start at the top. Otherwise, when
|
||||
* in a paragraph but not at its beginning, move back to its first line. */
|
||||
if (full_justify)
|
||||
openfile->current = openfile->filetop;
|
||||
else if (inpar(openfile->current) && !begpar(openfile->current, 0))
|
||||
do_para_begin(&openfile->current);
|
||||
|
||||
/* Find the first line of the paragraph(s) to be justified. If the
|
||||
* search fails, there is nothing to justify, and we will be on the
|
||||
* last line of the file, so put the cursor at the end of it. */
|
||||
if (!find_paragraph(&openfile->current, &par_len)) {
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
refresh_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare to put the text we want to justify in the cutbuffer. */
|
||||
cutbuffer = NULL;
|
||||
cutbottom = NULL;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If the mark is on, do as Pico: treat all marked text as one paragraph. */
|
||||
if (openfile->mark) {
|
||||
@@ -2099,19 +2004,33 @@ void do_justify(bool full_justify)
|
||||
size_t jus_len;
|
||||
/* The number of lines we're storing in the current cutbuffer. */
|
||||
|
||||
/* Start out at the first line of the paragraph. */
|
||||
/* When justifying the entire buffer, start at the top. Otherwise, when
|
||||
* in a paragraph but not at its beginning, move back to its first line. */
|
||||
if (full_justify)
|
||||
openfile->current = openfile->filetop;
|
||||
else if (inpar(openfile->current) && !begpar(openfile->current, 0))
|
||||
do_para_begin(&openfile->current);
|
||||
|
||||
/* Find the first line of the paragraph(s) to be justified. If the
|
||||
* search fails, there is nothing to justify, and we will be on the
|
||||
* last line of the file, so put the cursor at the end of it. */
|
||||
if (!find_paragraph(&openfile->current, &par_len)) {
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
refresh_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
first_par_line = openfile->current;
|
||||
last_par_line = openfile->current;
|
||||
top_x = 0;
|
||||
|
||||
/* Set the number of lines to be pulled into the cutbuffer. */
|
||||
if (full_justify)
|
||||
jus_len = openfile->filebot->lineno;
|
||||
jus_len = openfile->filebot->lineno - first_par_line->lineno + 1;
|
||||
else
|
||||
jus_len = par_len;
|
||||
|
||||
/* Move down to the last line to be extracted. */
|
||||
for (; jus_len > 1; jus_len--)
|
||||
for (last_par_line = openfile->current; jus_len > 1; jus_len--)
|
||||
last_par_line = last_par_line->next;
|
||||
|
||||
/* When possible, step one line further; otherwise, to line's end. */
|
||||
@@ -2132,7 +2051,10 @@ void do_justify(bool full_justify)
|
||||
|
||||
add_undo(CUT);
|
||||
#endif
|
||||
/* Do the equivalent of a marked cut. */
|
||||
|
||||
/* Do the equivalent of a marked cut into an empty cutbuffer. */
|
||||
cutbuffer = NULL;
|
||||
cutbottom = NULL;
|
||||
extract_buffer(&cutbuffer, &cutbottom, first_par_line, top_x,
|
||||
last_par_line, bot_x);
|
||||
#ifndef NANO_TINY
|
||||
@@ -2374,7 +2296,7 @@ bool fix_spello(const char *word)
|
||||
} else if (result == 1) {
|
||||
spotlighted = TRUE;
|
||||
light_from_col = xplustabs();
|
||||
light_to_col = light_from_col + strlenpt(word);
|
||||
light_to_col = light_from_col + breadth(word);
|
||||
#ifndef NANO_TINY
|
||||
linestruct *saved_mark = openfile->mark;
|
||||
openfile->mark = NULL;
|
||||
@@ -2437,8 +2359,9 @@ bool fix_spello(const char *word)
|
||||
* termination, and the error string otherwise. */
|
||||
const char *do_int_speller(const char *tempfile_name)
|
||||
{
|
||||
char *read_buff, *read_buff_ptr, *read_buff_word;
|
||||
size_t pipe_buff_size, read_buff_size, read_buff_read, bytesread;
|
||||
char *misspellings, *pointer, *oneword;
|
||||
long pipesize;
|
||||
size_t buffersize, bytesread, totalread;
|
||||
int spell_fd[2], sort_fd[2], uniq_fd[2], tempfile_fd = -1;
|
||||
pid_t pid_spell, pid_sort, pid_uniq;
|
||||
int spell_status, sort_status, uniq_status;
|
||||
@@ -2538,53 +2461,61 @@ const char *do_int_speller(const char *tempfile_name)
|
||||
}
|
||||
|
||||
/* Get the system pipe buffer size. */
|
||||
if ((pipe_buff_size = fpathconf(uniq_fd[0], _PC_PIPE_BUF)) < 1) {
|
||||
pipesize = fpathconf(uniq_fd[0], _PC_PIPE_BUF);
|
||||
|
||||
if (pipesize < 1) {
|
||||
close(uniq_fd[0]);
|
||||
return _("Could not get size of pipe buffer");
|
||||
}
|
||||
|
||||
/* Read in the returned spelling errors. */
|
||||
read_buff_read = 0;
|
||||
read_buff_size = pipe_buff_size + 1;
|
||||
read_buff = read_buff_ptr = charalloc(read_buff_size);
|
||||
/* Block SIGWINCHes while reading misspelled words from the pipe. */
|
||||
block_sigwinch(TRUE);
|
||||
|
||||
while ((bytesread = read(uniq_fd[0], read_buff_ptr, pipe_buff_size)) > 0) {
|
||||
read_buff_read += bytesread;
|
||||
read_buff_size += pipe_buff_size;
|
||||
read_buff = read_buff_ptr = charealloc(read_buff, read_buff_size);
|
||||
read_buff_ptr += read_buff_read;
|
||||
totalread = 0;
|
||||
buffersize = pipesize + 1;
|
||||
misspellings = charalloc(buffersize);
|
||||
pointer = misspellings;
|
||||
|
||||
while ((bytesread = read(uniq_fd[0], pointer, pipesize)) > 0) {
|
||||
totalread += bytesread;
|
||||
buffersize += pipesize;
|
||||
misspellings = charealloc(misspellings, buffersize);
|
||||
pointer = misspellings + totalread;
|
||||
}
|
||||
|
||||
*read_buff_ptr = '\0';
|
||||
*pointer = '\0';
|
||||
close(uniq_fd[0]);
|
||||
|
||||
block_sigwinch(FALSE);
|
||||
|
||||
/* Do any replacements case sensitive, forward, and without regexes. */
|
||||
SET(CASE_SENSITIVE);
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
UNSET(USE_REGEXP);
|
||||
|
||||
read_buff_word = read_buff_ptr = read_buff;
|
||||
pointer = misspellings;
|
||||
oneword = misspellings;
|
||||
|
||||
/* Process each of the misspelled words. */
|
||||
while (*read_buff_ptr != '\0') {
|
||||
if ((*read_buff_ptr == '\r') || (*read_buff_ptr == '\n')) {
|
||||
*read_buff_ptr = '\0';
|
||||
if (read_buff_word != read_buff_ptr) {
|
||||
if (!fix_spello(read_buff_word)) {
|
||||
read_buff_word = read_buff_ptr;
|
||||
while (*pointer != '\0') {
|
||||
if ((*pointer == '\r') || (*pointer == '\n')) {
|
||||
*pointer = '\0';
|
||||
if (oneword != pointer) {
|
||||
if (!fix_spello(oneword)) {
|
||||
oneword = pointer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
read_buff_word = read_buff_ptr + 1;
|
||||
oneword = pointer + 1;
|
||||
}
|
||||
read_buff_ptr++;
|
||||
pointer++;
|
||||
}
|
||||
|
||||
/* Special case: the last word doesn't end with '\r' or '\n'. */
|
||||
if (read_buff_word != read_buff_ptr)
|
||||
fix_spello(read_buff_word);
|
||||
if (oneword != pointer)
|
||||
fix_spello(oneword);
|
||||
|
||||
free(read_buff);
|
||||
free(misspellings);
|
||||
tidy_up_after_search();
|
||||
refresh_needed = TRUE;
|
||||
|
||||
@@ -2652,8 +2583,11 @@ const char *do_alt_speller(char *tempfile_name)
|
||||
} else if (pid_spell < 0)
|
||||
return _("Could not fork");
|
||||
|
||||
/* Wait for the alternate spell checker to finish. */
|
||||
/* Block SIGWINCHes while waiting for the alternate spell checker's end,
|
||||
* so nano doesn't get pushed past the wait(). */
|
||||
block_sigwinch(TRUE);
|
||||
wait(&alt_spell_status);
|
||||
block_sigwinch(FALSE);
|
||||
|
||||
/* Reenter curses mode. */
|
||||
doupdate();
|
||||
@@ -2736,7 +2670,7 @@ void do_spell(void)
|
||||
memcpy(stash, flags, sizeof(flags));
|
||||
|
||||
/* Don't add an extra newline when writing out the (selected) text. */
|
||||
UNSET(FINAL_NEWLINE);
|
||||
SET(NO_NEWLINES);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->mark)
|
||||
@@ -2782,8 +2716,9 @@ void do_spell(void)
|
||||
* termination, and the error string otherwise. */
|
||||
void do_linter(void)
|
||||
{
|
||||
char *read_buff, *read_buff_ptr, *read_buff_word;
|
||||
size_t pipe_buff_size, read_buff_size, read_buff_read, bytesread;
|
||||
char *lintings, *pointer, *onelint;
|
||||
long pipesize;
|
||||
size_t buffersize, bytesread, totalread;
|
||||
size_t parsesuccess = 0;
|
||||
int lint_status, lint_fd[2];
|
||||
pid_t pid_lint;
|
||||
@@ -2861,36 +2796,40 @@ void do_linter(void)
|
||||
}
|
||||
|
||||
/* Get the system pipe buffer size. */
|
||||
if ((pipe_buff_size = fpathconf(lint_fd[0], _PC_PIPE_BUF)) < 1) {
|
||||
pipesize = fpathconf(lint_fd[0], _PC_PIPE_BUF);
|
||||
|
||||
if (pipesize < 1) {
|
||||
close(lint_fd[0]);
|
||||
statusbar(_("Could not get size of pipe buffer"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read in the returned syntax errors. */
|
||||
read_buff_read = 0;
|
||||
read_buff_size = pipe_buff_size + 1;
|
||||
read_buff = read_buff_ptr = charalloc(read_buff_size);
|
||||
totalread = 0;
|
||||
buffersize = pipesize + 1;
|
||||
lintings = charalloc(buffersize);
|
||||
pointer = lintings;
|
||||
|
||||
while ((bytesread = read(lint_fd[0], read_buff_ptr, pipe_buff_size)) > 0) {
|
||||
read_buff_read += bytesread;
|
||||
read_buff_size += pipe_buff_size;
|
||||
read_buff = read_buff_ptr = charealloc(read_buff, read_buff_size);
|
||||
read_buff_ptr += read_buff_read;
|
||||
while ((bytesread = read(lint_fd[0], pointer, pipesize)) > 0) {
|
||||
totalread += bytesread;
|
||||
buffersize += pipesize;
|
||||
lintings = charealloc(lintings, buffersize);
|
||||
pointer = lintings + totalread;
|
||||
}
|
||||
|
||||
*read_buff_ptr = '\0';
|
||||
*pointer = '\0';
|
||||
close(lint_fd[0]);
|
||||
|
||||
/* Process the linter output. */
|
||||
read_buff_word = read_buff_ptr = read_buff;
|
||||
pointer = lintings;
|
||||
onelint = lintings;
|
||||
|
||||
while (*read_buff_ptr != '\0') {
|
||||
if ((*read_buff_ptr == '\r') || (*read_buff_ptr == '\n')) {
|
||||
*read_buff_ptr = '\0';
|
||||
if (read_buff_word != read_buff_ptr) {
|
||||
while (*pointer != '\0') {
|
||||
if ((*pointer == '\r') || (*pointer == '\n')) {
|
||||
*pointer = '\0';
|
||||
if (onelint != pointer) {
|
||||
char *filename = NULL, *linestr = NULL, *maybecol = NULL;
|
||||
char *message = mallocstrcpy(NULL, read_buff_word);
|
||||
char *message = mallocstrcpy(NULL, onelint);
|
||||
|
||||
/* At the moment we handle the following formats:
|
||||
*
|
||||
@@ -2898,7 +2837,7 @@ void do_linter(void)
|
||||
* filenameorcategory:line,column:message (e.g. pylint)
|
||||
* filenameorcategory:line:message (e.g. pyflakes) */
|
||||
if (strstr(message, ": ") != NULL) {
|
||||
filename = strtok(read_buff_word, ":");
|
||||
filename = strtok(onelint, ":");
|
||||
if ((linestr = strtok(NULL, ":")) != NULL) {
|
||||
if ((maybecol = strtok(NULL, ":")) != NULL) {
|
||||
ssize_t tmplineno = 0, tmpcolno = 0;
|
||||
@@ -2906,7 +2845,7 @@ void do_linter(void)
|
||||
|
||||
tmplineno = strtol(linestr, NULL, 10);
|
||||
if (tmplineno <= 0) {
|
||||
read_buff_ptr++;
|
||||
pointer++;
|
||||
free(message);
|
||||
continue;
|
||||
}
|
||||
@@ -2938,14 +2877,16 @@ void do_linter(void)
|
||||
lints = curlint;
|
||||
}
|
||||
}
|
||||
} else
|
||||
free(message);
|
||||
}
|
||||
free(message);
|
||||
}
|
||||
read_buff_word = read_buff_ptr + 1;
|
||||
onelint = pointer + 1;
|
||||
}
|
||||
read_buff_ptr++;
|
||||
pointer++;
|
||||
}
|
||||
|
||||
free(lintings);
|
||||
|
||||
/* Process the end of the linting process. */
|
||||
waitpid(pid_lint, &lint_status, 0);
|
||||
|
||||
@@ -2954,8 +2895,6 @@ void do_linter(void)
|
||||
return;
|
||||
}
|
||||
|
||||
free(read_buff);
|
||||
|
||||
if (parsesuccess == 0) {
|
||||
statusline(HUSH, _("Got 0 parsable lines from command: %s"),
|
||||
openfile->syntax->linter);
|
||||
@@ -3125,7 +3064,6 @@ void do_wordlinechar_count(void)
|
||||
size_t words = 0, chars = 0;
|
||||
ssize_t nlines = 0;
|
||||
size_t current_x_save = openfile->current_x;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
linestruct *current_save = openfile->current;
|
||||
linestruct *was_mark = openfile->mark;
|
||||
linestruct *top, *bot;
|
||||
@@ -3143,7 +3081,6 @@ void do_wordlinechar_count(void)
|
||||
/* Start at the top of the file. */
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
|
||||
/* Keep moving to the next word (counting punctuation characters as
|
||||
* part of a word, as "wc -w" does), without updating the screen,
|
||||
@@ -3173,7 +3110,6 @@ void do_wordlinechar_count(void)
|
||||
/* Restore where we were. */
|
||||
openfile->current = current_save;
|
||||
openfile->current_x = current_x_save;
|
||||
openfile->placewewant = pww_save;
|
||||
|
||||
/* Display the total word, line, and character counts on the statusbar. */
|
||||
statusline(HUSH, _("%sWords: %zu Lines: %zd Chars: %zu"), was_mark ?
|
||||
@@ -3363,7 +3299,7 @@ void complete_a_word(void)
|
||||
/* If needed, reenable wrapping and wrap the current line. */
|
||||
if (was_set_wrapping) {
|
||||
SET(BREAK_LONG_LINES);
|
||||
do_wrap(openfile->current);
|
||||
do_wrap();
|
||||
}
|
||||
#endif
|
||||
/* Set the position for a possible next search attempt. */
|
||||
|
||||
26
src/utils.c
26
src/utils.c
@@ -159,13 +159,6 @@ bool parse_line_column(const char *str, ssize_t *line, ssize_t *column)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Null a string at a certain index and align it. */
|
||||
void null_at(char **data, size_t index)
|
||||
{
|
||||
*data = charealloc(*data, index + 1);
|
||||
(*data)[index] = '\0';
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so encode its nulls as newlines. */
|
||||
void unsunder(char *str, size_t true_len)
|
||||
@@ -336,10 +329,6 @@ char *mallocstrncpy(char *dest, const char *src, size_t n)
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (src == dest)
|
||||
fprintf(stderr, "\r*** Copying a string to itself -- please report a bug ***");
|
||||
#endif
|
||||
dest = charealloc(dest, n);
|
||||
strncpy(dest, src, n);
|
||||
|
||||
@@ -379,7 +368,7 @@ size_t get_page_start(size_t column)
|
||||
* column position of the cursor. */
|
||||
size_t xplustabs(void)
|
||||
{
|
||||
return strnlenpt(openfile->current->data, openfile->current_x);
|
||||
return wideness(openfile->current->data, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Return the index in text of the character that (when displayed) will
|
||||
@@ -405,10 +394,9 @@ size_t actual_x(const char *text, size_t column)
|
||||
|
||||
/* A strnlen() with tabs and multicolumn characters factored in:
|
||||
* how many columns wide are the first maxlen bytes of text? */
|
||||
size_t strnlenpt(const char *text, size_t maxlen)
|
||||
size_t wideness(const char *text, size_t maxlen)
|
||||
{
|
||||
size_t width = 0;
|
||||
/* The screen display width to text[maxlen]. */
|
||||
|
||||
if (maxlen == 0)
|
||||
return 0;
|
||||
@@ -427,7 +415,7 @@ size_t strnlenpt(const char *text, size_t maxlen)
|
||||
}
|
||||
|
||||
/* Return the number of columns that the given text occupies. */
|
||||
size_t strlenpt(const char *text)
|
||||
size_t breadth(const char *text)
|
||||
{
|
||||
size_t span = 0;
|
||||
|
||||
@@ -519,12 +507,10 @@ linestruct *fsfromline(ssize_t lineno)
|
||||
while (f->lineno != lineno && f->next != NULL)
|
||||
f = f->next;
|
||||
|
||||
if (f->lineno != lineno) {
|
||||
statusline(ALERT, "Gone undo line -- please report a bug");
|
||||
if (f->lineno == lineno)
|
||||
return f;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
|
||||
89
src/winio.c
89
src/winio.c
@@ -656,7 +656,7 @@ 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) {
|
||||
const sc *command = first_sc_for(MMAIN, do_indent);
|
||||
const keystruct *command = first_sc_for(MMAIN, do_indent);
|
||||
|
||||
meta_key = command->meta;
|
||||
return command->keycode;
|
||||
@@ -1654,7 +1654,7 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
{
|
||||
MEVENT mevent;
|
||||
bool in_bottomwin;
|
||||
subnfunc *f;
|
||||
funcstruct *f;
|
||||
|
||||
/* First, get the actual mouse event. */
|
||||
if (getmouse(&mevent) == ERR)
|
||||
@@ -1729,7 +1729,7 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
|
||||
/* And put the corresponding key into the keyboard buffer. */
|
||||
if (f != NULL) {
|
||||
const sc *s = first_sc_for(currmenu, f->func);
|
||||
const keystruct *s = first_sc_for(currmenu, f->func);
|
||||
unget_kbinput(s->keycode, s->meta);
|
||||
}
|
||||
return 1;
|
||||
@@ -1769,9 +1769,9 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
* key itself) and meta_key (whether the key is a meta sequence). The
|
||||
* returned shortcut will be the first in the list that corresponds to
|
||||
* the given sequence. */
|
||||
const sc *get_shortcut(int *kbinput)
|
||||
const keystruct *get_shortcut(int *kbinput)
|
||||
{
|
||||
sc *s;
|
||||
keystruct *s;
|
||||
|
||||
/* Plain characters cannot be shortcuts, so just skip those. */
|
||||
if (!meta_key && ((*kbinput >= 0x20 && *kbinput < 0x7F) ||
|
||||
@@ -1871,7 +1871,7 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
{
|
||||
size_t start_index = actual_x(buf, column);
|
||||
/* The index of the first character that the caller wishes to show. */
|
||||
size_t start_col = strnlenpt(buf, start_index);
|
||||
size_t start_col = wideness(buf, start_index);
|
||||
/* The actual column where that first character starts. */
|
||||
char *converted;
|
||||
/* The expanded string we will return. */
|
||||
@@ -1888,6 +1888,13 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
/* Allocate enough space for converting the relevant part of the line. */
|
||||
converted = charalloc(strlen(buf) * (MAXCHARLEN + tabsize) + 1);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (span > HIGHEST_POSITIVE) {
|
||||
statusline(ALERT, "Span has underflowed -- please report a bug");
|
||||
converted[0] = '\0';
|
||||
return converted;
|
||||
}
|
||||
#endif
|
||||
/* If the first character starts before the left edge, or would be
|
||||
* overwritten by a "<" token, then show placeholders instead. */
|
||||
if (*buf != '\0' && *buf != '\t' && (start_col < column ||
|
||||
@@ -2016,7 +2023,7 @@ int buffer_number(openfilestruct *buffer)
|
||||
{
|
||||
int count = 1;
|
||||
|
||||
while (buffer != firstfile) {
|
||||
while (buffer != startfile) {
|
||||
buffer = buffer->prev;
|
||||
count++;
|
||||
}
|
||||
@@ -2081,7 +2088,7 @@ void titlebar(const char *path)
|
||||
if (more_than_one) {
|
||||
indicator = charalloc(24);
|
||||
sprintf(indicator, "[%i/%i]", buffer_number(openfile),
|
||||
buffer_number(firstfile->prev));
|
||||
buffer_number(startfile->prev));
|
||||
upperleft = indicator;
|
||||
} else
|
||||
#endif
|
||||
@@ -2099,16 +2106,16 @@ void titlebar(const char *path)
|
||||
else if (ISSET(RESTRICTED))
|
||||
state = _("Restricted");
|
||||
|
||||
pluglen = strlenpt(_("Modified")) + 1;
|
||||
pluglen = breadth(_("Modified")) + 1;
|
||||
}
|
||||
|
||||
/* Determine the widths of the four elements, including their padding. */
|
||||
verlen = strlenpt(upperleft) + 3;
|
||||
prefixlen = strlenpt(prefix);
|
||||
verlen = breadth(upperleft) + 3;
|
||||
prefixlen = breadth(prefix);
|
||||
if (prefixlen > 0)
|
||||
prefixlen++;
|
||||
pathlen = strlenpt(path);
|
||||
statelen = strlenpt(state) + 2;
|
||||
pathlen = breadth(path);
|
||||
statelen = breadth(state) + 2;
|
||||
if (statelen > 2) {
|
||||
pathlen++;
|
||||
pluglen = 0;
|
||||
@@ -2246,7 +2253,7 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
message = display_string(compound, 0, COLS, FALSE, FALSE);
|
||||
free(compound);
|
||||
|
||||
start_col = (COLS - strlenpt(message)) / 2;
|
||||
start_col = (COLS - breadth(message)) / 2;
|
||||
bracketed = (start_col > 1);
|
||||
|
||||
wmove(bottomwin, 0, (bracketed ? start_col - 2 : start_col));
|
||||
@@ -2286,8 +2293,8 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
void bottombars(int menu)
|
||||
{
|
||||
size_t number, itemwidth, i;
|
||||
subnfunc *f;
|
||||
const sc *s;
|
||||
funcstruct *f;
|
||||
const keystruct *s;
|
||||
|
||||
/* Set the global variable to the given menu. */
|
||||
currmenu = menu;
|
||||
@@ -2341,7 +2348,7 @@ void post_one_key(const char *keystroke, const char *tag, int width)
|
||||
wattroff(bottomwin, interface_color_pair[KEY_COMBO]);
|
||||
|
||||
/* If the remaning space is too small, skip the description. */
|
||||
width -= strlenpt(keystroke);
|
||||
width -= breadth(keystroke);
|
||||
if (width < 2)
|
||||
return;
|
||||
|
||||
@@ -2502,12 +2509,12 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
continue;
|
||||
|
||||
start_col = (match.rm_so <= from_x) ?
|
||||
0 : strnlenpt(fileptr->data,
|
||||
0 : wideness(fileptr->data,
|
||||
match.rm_so) - from_col;
|
||||
|
||||
thetext = converted + actual_x(converted, start_col);
|
||||
|
||||
paintlen = actual_x(thetext, strnlenpt(fileptr->data,
|
||||
paintlen = actual_x(thetext, wideness(fileptr->data,
|
||||
match.rm_eo) - from_col - start_col);
|
||||
|
||||
mvwaddnstr(edit, row, margin + start_col,
|
||||
@@ -2606,7 +2613,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
|
||||
/* Only if it is visible, paint the part to be coloured. */
|
||||
if (endmatch.rm_eo > from_x) {
|
||||
paintlen = actual_x(converted, strnlenpt(fileptr->data,
|
||||
paintlen = actual_x(converted, wideness(fileptr->data,
|
||||
endmatch.rm_eo) - from_col);
|
||||
mvwaddnstr(edit, row, margin, converted, paintlen);
|
||||
}
|
||||
@@ -2626,7 +2633,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
startmatch.rm_eo += index;
|
||||
|
||||
start_col = (startmatch.rm_so <= from_x) ?
|
||||
0 : strnlenpt(fileptr->data,
|
||||
0 : wideness(fileptr->data,
|
||||
startmatch.rm_so) - from_col;
|
||||
|
||||
thetext = converted + actual_x(converted, start_col);
|
||||
@@ -2642,7 +2649,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
* it is more than zero characters long. */
|
||||
if (endmatch.rm_eo > from_x &&
|
||||
endmatch.rm_eo > startmatch.rm_so) {
|
||||
paintlen = actual_x(thetext, strnlenpt(fileptr->data,
|
||||
paintlen = actual_x(thetext, wideness(fileptr->data,
|
||||
endmatch.rm_eo) - from_col - start_col);
|
||||
|
||||
mvwaddnstr(edit, row, margin + start_col,
|
||||
@@ -2695,7 +2702,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
|
||||
if (*(converted + target_x) != '\0') {
|
||||
charlen = parse_mbchar(converted + target_x, striped_char, NULL);
|
||||
target_column = strnlenpt(converted, target_x);
|
||||
target_column = wideness(converted, target_x);
|
||||
} else if (target_column + 1 == editwincols) {
|
||||
/* Defeat a VTE bug -- see https://sv.gnu.org/bugs/?55896. */
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -2742,7 +2749,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
/* Only paint if the marked part of the line is on this page. */
|
||||
if (top_x < till_x && bot_x > from_x) {
|
||||
/* Compute on which screen column to start painting. */
|
||||
start_col = strnlenpt(fileptr->data, top_x) - from_col;
|
||||
start_col = wideness(fileptr->data, top_x) - from_col;
|
||||
|
||||
if (start_col < 0)
|
||||
start_col = 0;
|
||||
@@ -2752,7 +2759,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
/* If the end of the mark is onscreen, compute how many
|
||||
* characters to paint. Otherwise, just paint all. */
|
||||
if (bot_x < till_x) {
|
||||
size_t end_col = strnlenpt(fileptr->data, bot_x) - from_col;
|
||||
size_t end_col = wideness(fileptr->data, bot_x) - from_col;
|
||||
paintlen = actual_x(thetext, end_col - start_col);
|
||||
}
|
||||
|
||||
@@ -2786,20 +2793,11 @@ int update_line(linestruct *fileptr, size_t index)
|
||||
|
||||
row = fileptr->lineno - openfile->edittop->lineno;
|
||||
|
||||
/* If the line is offscreen, don't even try to display it. */
|
||||
if (row < 0 || row >= editwinrows) {
|
||||
#ifndef NANO_TINY
|
||||
statusline(ALERT, "Badness: tried to display a line on row %i"
|
||||
" -- please report a bug", row);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* First, blank out the row. */
|
||||
blank_row(edit, row, 0, COLS);
|
||||
|
||||
/* Next, find out from which column to start displaying the line. */
|
||||
from_col = get_page_start(strnlenpt(fileptr->data, index));
|
||||
from_col = get_page_start(wideness(fileptr->data, index));
|
||||
|
||||
/* Expand the line, replacing tabs with spaces, and control
|
||||
* characters with their displayed forms. */
|
||||
@@ -2814,7 +2812,7 @@ int update_line(linestruct *fileptr, size_t index)
|
||||
mvwaddch(edit, row, margin, '<');
|
||||
wattroff(edit, hilite_attribute);
|
||||
}
|
||||
if (strlenpt(fileptr->data) > from_col + editwincols) {
|
||||
if (breadth(fileptr->data) > from_col + editwincols) {
|
||||
wattron(edit, hilite_attribute);
|
||||
mvwaddch(edit, row, COLS - 1, '>');
|
||||
wattroff(edit, hilite_attribute);
|
||||
@@ -3010,20 +3008,13 @@ void edit_scroll(bool direction)
|
||||
{
|
||||
linestruct *line;
|
||||
size_t leftedge;
|
||||
int remainder = 0, nrows = 1;
|
||||
int nrows = 1;
|
||||
|
||||
/* Move the top line of the edit window one row up or down. */
|
||||
if (direction == BACKWARD)
|
||||
remainder = go_back_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
go_back_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
else
|
||||
remainder = go_forward_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
|
||||
if (remainder > 0) {
|
||||
#ifndef NANO_TINY
|
||||
statusline(ALERT, "Could not scroll -- please report a bug");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
go_forward_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
|
||||
/* Actually scroll the text of the edit window one row up or down. */
|
||||
scrollok(edit, TRUE);
|
||||
@@ -3197,7 +3188,7 @@ size_t actual_last_column(size_t leftedge, size_t column)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
bool last_chunk;
|
||||
bool last_chunk = FALSE;
|
||||
size_t end_col = get_softwrap_breakpoint(openfile->current->data,
|
||||
leftedge, &last_chunk) - leftedge;
|
||||
|
||||
@@ -3401,7 +3392,7 @@ void do_cursorpos(bool force)
|
||||
{
|
||||
char saved_byte;
|
||||
size_t sum, cur_xpt = xplustabs() + 1;
|
||||
size_t cur_lenpt = strlenpt(openfile->current->data) + 1;
|
||||
size_t cur_lenpt = breadth(openfile->current->data) + 1;
|
||||
int linepct, colpct, charpct;
|
||||
|
||||
/* If the showing needs to be suppressed, don't suppress it next time. */
|
||||
@@ -3661,7 +3652,7 @@ void do_credits(void)
|
||||
else
|
||||
what = credits[crpos];
|
||||
|
||||
start_col = COLS / 2 - strlenpt(what) / 2 - 1;
|
||||
start_col = COLS / 2 - breadth(what) / 2 - 1;
|
||||
mvwaddstr(edit, editwinrows - 1 - (editwinrows % 2),
|
||||
start_col, what);
|
||||
}
|
||||
|
||||
@@ -10,12 +10,11 @@ color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
||||
color brightmagenta "^[[:space:]]*[A-Z_a-z]+:[[:space:]]*$"
|
||||
|
||||
color green "\<(float|double|bool|char|int|short|long|sizeof|enum|void|auto|static|const|struct|union|typedef|extern|(un)?signed|inline)\>"
|
||||
color green "\<((s?size)|((u_?)?int(8|16|32|64|ptr)))_t\>"
|
||||
color green "\<([[:lower:]]+|(u_?)?int(8|16|32|64|ptr))_t\>"
|
||||
color green "\<(class|namespace|template|public|protected|private|typename|this|friend|virtual|override|using|mutable|volatile|register|explicit)\>"
|
||||
color brightyellow "\<(for|if|while|do|else|case|default|switch)\>"
|
||||
color brightyellow "\<(try|throw|catch|operator|new|delete)\>"
|
||||
color magenta "\<(goto|continue|break|return)\>"
|
||||
color brightcyan "^[[:space:]]*#[[:space:]]*(define|include(_next)?|(un|ifn?)def|endif|el(if|se)|if|warning|error|pragma)"
|
||||
color brightmagenta "'([^'\]|(\\["'abfnrtv\\]))'" "'\\(([0-3]?[0-7]{1,2}))'" "'\\x[0-9A-Fa-f]{1,2}'"
|
||||
|
||||
# GCC builtins.
|
||||
@@ -23,11 +22,15 @@ color cyan "__attribute__[[:space:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidd
|
||||
|
||||
# Strings. In general you will want your strings and comments to come last,
|
||||
# because highlighting rules are applied in the order they are read in.
|
||||
color brightyellow ""([^"]|\\")*"" "<[^[:blank:]=]*>"
|
||||
color brightyellow ""([^"]|\\")*"" "#[[:space:]]*include[[:space:]]+<[^[:blank:]=]*>"
|
||||
# Multiline strings. This regex is VERY resource intensive,
|
||||
# and sometimes colours things that shouldn't be coloured.
|
||||
###color brightyellow start=""(\\.|[^"])*\\[[:space:]]*$" end="^(\\.|[^"])*""
|
||||
|
||||
# Preprocessor directives.
|
||||
color brightcyan start="^[[:space:]]*#[[:space:]]*(if(n?def)?|elif|warning|error|pragma)\>" end="(\`|[^\\])$"
|
||||
color brightcyan "^[[:space:]]*#[[:space:]]*(define|else|endif|include(_next)?|undef)\>"
|
||||
|
||||
# Comments.
|
||||
color brightblue "//.*"
|
||||
color brightblue start="/\*" end="\*/"
|
||||
|
||||
@@ -11,7 +11,7 @@ color cyan "^[[:space:]]*#.*"
|
||||
color ,red " + +"
|
||||
|
||||
# Nano's name, including version.
|
||||
color brightred "(GNU )?[Nn]ano [1-3]\.[0-9][-.[:alnum:]]*\>"
|
||||
color brightred "(GNU )?[Nn]ano [1-4]\.[0-9][-.[:alnum:]]*\>"
|
||||
|
||||
# Email addresses.
|
||||
color magenta "<[[:alnum:].%_+-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}>"
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
## Here is an example for manpages.
|
||||
## Syntax highlighting for man pages.
|
||||
|
||||
syntax man "\.[1-9]x?$"
|
||||
magic "troff or preprocessor input"
|
||||
comment ".\""
|
||||
|
||||
color green "\.(SH|SS|TH) .*"
|
||||
color brightgreen "\.(SH|SS|TH) " "\.([HIT]P)"
|
||||
color brightred "\.(B[IR]?|I[BR]?|R[BI]|S[BM]) .*"
|
||||
color brightblue "\.(B[IR]?|I[BR]?|R[BI]|S[BM]) " "\.([LP]?P)$"
|
||||
# Section headers, title line, and indented paragraphs.
|
||||
color green "^\.(SH|SS|TH) .*"
|
||||
color brightgreen "^\.(SH|SS|TH) " "^\.([HIT]P)"
|
||||
# Type faces, and normal paragraphs.
|
||||
color brightred "^\.(B[IR]?|I[BR]?|R[BI]|S[BM]) .*"
|
||||
color brightblue "^\.(B[IR]?|I[BR]?|R[BI]|S[BM]) " "^\.([LP]?P)$"
|
||||
# Inline type faces.
|
||||
color magenta "\\f[BIPR]"
|
||||
color yellow "\.(br|DT|RS|RE|PD)"
|
||||
# Relative margins, hyperlinks, and various other stuff.
|
||||
color yellow "^\.(RS|RE|UR|UE|PD|DT)"
|
||||
color yellow "^\.(ad|bp|br|ce|de|ds|el|ie|if|fi|ft|hy|ig|in|na|ne|nf|nh|ps|so|sp|ti|tr)"
|
||||
|
||||
# Comments.
|
||||
color cyan "\.?\\\".*"
|
||||
color cyan "(^\.)?\\\".*"
|
||||
|
||||
# Trailing whitespace.
|
||||
color ,green "[[:space:]]+$"
|
||||
|
||||
@@ -18,7 +18,7 @@ icolor brightgreen "^[[:space:]]*(syntax|linter)[[:space:]]+[^[:blank:]]+"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|extendsyntax)\>"
|
||||
|
||||
# Strings
|
||||
color brightmagenta "".+"([[:space:]]|$)"
|
||||
color brightmagenta "([[:space:]]|(start|end)=)".+"([[:space:]]|$)"
|
||||
|
||||
# Colors
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
|
||||
Reference in New Issue
Block a user