Compare commits

...

299 Commits
v5.3 ... v5.8

Author SHA1 Message Date
Benno Schulenberg
4f981cd5d9 po: update translations and regenerate POT file and PO files 2021-06-15 10:28:23 +02:00
Benno Schulenberg
44a6c4963b tweaks: avoid a compiler warning when configured with --enable-tiny 2021-06-15 10:20:28 +02:00
Benno Schulenberg
622bfb5b83 build: commit the LINGUAS file too while rolling a release 2021-06-15 10:11:19 +02:00
Benno Schulenberg
a2cb22faab bump version numbers and add a news item for the 5.8 release 2021-06-15 09:52:45 +02:00
Benno Schulenberg
9f8309fba8 help: use smaller triangles for the arrows
In Dejavu Sans Mono the old pointing triangles had a decent size,
but in Noto Mono and in Ubuntu Mono (fonts that handle combining
diacritics better) those triangles were massive, visually taking
up more than a single cell, overlapping the closing parenthesis
when they are displayed in the second column.  Not nice.

The new pointing small triangles look good in the Noto and Ubuntu
fonts, but are real tiny in Dejavu.  :|  Oh well, one can't have
everything.

(Other triangles are not an option, because they don't degrade to
actual arrows when on a Linux console.)
2021-06-14 09:29:27 +02:00
Benno Schulenberg
bf7954bdb7 tweaks: rename a variable, for contrast with the function name 2021-06-13 16:57:54 +02:00
Benno Schulenberg
0371dd1bde tweaks: rename two functions, to get rid of an ugly _void suffix
Also drop an unneeded prototype.
2021-06-13 12:17:33 +02:00
Benno Schulenberg
7c53b133a1 tweaks: use two symbolic names instead of TRUE and FALSE, for clarity 2021-06-13 12:06:24 +02:00
Benno Schulenberg
b1e5f9d9a8 docs: add a relevant item to the news for the 4.3 release
It's a low-level thing, but for the people affected it's a big deal.
2021-06-13 11:18:03 +02:00
Benno Schulenberg
424969258a docs: say thanks to the Icelandic and Slovak translators
(The Slovak file will arrive from the TP upon rolling the next release.)
2021-06-12 16:38:18 +02:00
Benno Schulenberg
6d0fc38285 gnulib: update to its current upstream state 2021-06-12 11:06:06 +02:00
Benno Schulenberg
984c9e1078 tweaks: redraw only the affected line instead of doing a full refresh
When the spotlighting needs to be cancelled, there is no need to do a
full refresh of the edit window -- redrawing just the relevant line is
enough.  (And when there is just one row, it is enough too.)
2021-06-11 16:52:56 +02:00
Benno Schulenberg
101dc4e805 docs: make ^E access the Execute menu in the example CUA bindings
Also, add the normal CUA bindings for Undo (^Z) and Redo (^Y),
and drop the M-X thinko.

With these more "usual" alternative bindings, ^X will now do a Cut
(putting the cut text into the cutbuffer) only when in the main menu
-- in the other places it did not put anything into the cutbuffer,
so it's better to have only the default ^K ("kill") for that.

Suspension is now accessible with ^E^Z, and the Speller with ^E^S.

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

Bug existed since version 3.2, commit 33d67d5c,
since the more usual example bindings were introduced.
2021-06-11 11:10:28 +02:00
Benno Schulenberg
d7e3226158 memory: move the correct number of bytes, and not one too many
We want to reduce the size of the answer by one byte,
not keep the full answer (plus terminating NUL).

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

Bug existed since version 2.9.8, commit f304b9ae,
since piping text to an external command was introduced.
2021-06-10 11:34:04 +02:00
Benno Schulenberg
74c6bdac9f docs: add example bindings for uppercasing and lowercasing a word
(The diff looks weird in 'less' -- the "c" before the "^T" hides
two escape sequences.)
2021-06-10 10:40:49 +02:00
Benno Schulenberg
73168bb1b9 docs: improve the contact info and some line spacing in the PDF 2021-06-08 11:31:18 +02:00
Benno Schulenberg
f895f1beba docs: mention the new 'set minicolor' option 2021-06-08 10:51:19 +02:00
Benno Schulenberg
e2e8bf0a3e options: accept 'set minicolor' for setting the color of the minibar
When it is not specified, it defaults to the value for 'titlecolor'.

When not using --minibar, I want the title bar to be blue (as that is
how I've always had it), but with --minibar, I want this mini bar to
be grey, as otherwise it reminds me too much of the prompt bar.

Also, colorize 'set minicolor' as valid in a nanorc file.
2021-06-08 09:25:02 +02:00
Benno Schulenberg
3f340836a6 search: automatically drop the spotlighting after a few moments
Even though I know that spotlighted text is not selected, I still
regularly think for a fleeting instant that the spotlighted text
can be cut with a ^K.  Mitigate this by dropping the spotlighting
after 1.5 seconds (or 0.8 seconds when using --quick).
2021-06-03 12:02:04 +02:00
Hussam al-Homsi
092c62ccb8 bindings: allow copying text (with M-6) also when in view mode
This can be useful when wanting to search for the other occurrences
of some (long) string in the buffer: select, M-6, ^W, ^U, <Enter>.

Signed-off-by: Hussam al-Homsi <sawuare@gmail.com>
2021-06-02 11:09:24 +02:00
Benno Schulenberg
97dd505647 linter: strip filename and line plus column number from the message
Nano already opens the relevant file (when needed) and puts the cursor
at the relevant spot -- including this information in the message shown
on the bottom bar is just clutter and makes the message harder to read.
2021-05-30 11:30:32 +02:00
Benno Schulenberg
635977fe33 syntax: nanohelp: avoid colorizing M-) in (M-) and M-" in "M-"
Instead of quoting M- as 'M-', some translations use «M-» (Catalan),
(M-) (Croat), "M-" (Italian), „M-” (Romanian), or „М-“ (Serbian).
Those occurrences of M- nor its quotation marks should be colored.

Achieve this by excluding those quotation marks from the M- regex,
and then colorizing M-) and M-" only when at start of line (first
column of shortcuts) or when between parentheses (second column).
2021-05-30 10:44:03 +02:00
Benno Schulenberg
6ab70c2b0a tweaks: improve a comment, remove unneeded braces, reshuffle some lines 2021-05-28 16:42:56 +02:00
Benno Schulenberg
3a86b24a3e tweaks: remove a check that is not needed
The die() has been there for more than a year and no one reported a
problem.  And anyway, indenting does not create more than one group
-- this check was just to be certain.
2021-05-28 16:20:59 +02:00
Benno Schulenberg
77ca8735ab syntax: nanorc: colorize "light" as valid only for the eight basic colors
Only the basic colors (like red, blue and yellow) can take the prefix
"light" or "bright", not the extra colors (like pink, lagoon and lime).

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

Bug existed since version 5.0, since the extra colors were introduced.
2021-05-26 15:53:07 +02:00
Benno Schulenberg
3a0922799d tweaks: reshuffle the coloring of color names, to remove some duplication 2021-05-26 15:39:14 +02:00
Benno Schulenberg
b27efce732 docs: mention that "grey"/"gray" may be used as a synonym of "lightblack"
Also, colorize "grey" and "gray" as valid names in a nanorc file.
2021-05-26 15:31:04 +02:00
Benno Schulenberg
8974430c11 rcfile: allow using "grey" or "gray" as a synonym for "lightblack"
Because "lightblack" sounds strange and will not occur to many people
as a possible color name.
2021-05-26 15:31:04 +02:00
Benno Schulenberg
e044284998 rcfile: do not allow color name "normal" to have a prefix
Because "lightnormal" sounds strange, and can have unexpected effects.

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

Bug existed since version 2.9.5, since the name "normal" was introduced.
2021-05-25 15:43:06 +02:00
Benno Schulenberg
4f9d55bb15 tweaks: normalize the indentation after the previous change 2021-05-25 15:31:54 +02:00
Benno Schulenberg
89adacff3d tweaks: condense some code by putting all color names in a single array 2021-05-25 15:28:02 +02:00
Benno Schulenberg
2314a1932f tweaks: use a symbol instead of a hard-coded number 2021-05-25 15:14:10 +02:00
Benno Schulenberg
fb5eb4856b tweaks: drop an assignment that is already part of the called function 2021-05-25 15:11:33 +02:00
Benno Schulenberg
f857959b8e startup: suppress "Search Wrapped" when using +? to search from EOF
When using +/ or +?, any minor feedback should be cleared,
to not distract from the highligted search result.

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

Bug existed since version 5.5, commit b86f7868,
since the manner of grading status-bar messages changed.
2021-05-25 14:51:03 +02:00
Benno Schulenberg
405c2162b5 startup: allow using a bare "+" to mean put-cursor-on-last-line
Editors like 'vim' and 'ne' and 'uemacs' know this shorthand too.

This fulfills https://savannah.gnu.org/bugs/?60663.
2021-05-25 12:18:48 +02:00
Benno Schulenberg
8797ada815 startup: do not accept stray characters after a "+" on the command line
After a "+" only c, r, C, and R are valid characters,
and only when immediately followed by / or ?.

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

Bug existed since version 4.4, commit 2326bf6,
since searching at startup with +/ or +? was introduced.
2021-05-25 12:15:52 +02:00
Benno Schulenberg
30bafc70cc tweaks: prevent two more size_t subtractions from going negative
This fully fixes https://savannah.gnu.org/bugs/?60658.

Found by compiling with -fsanitize=undefined.
2021-05-24 11:00:29 +02:00
Benno Schulenberg
b38f0cbaf4 feedback: ensure that the reporting of DOS/Mac format is truthful
This fixes https://savannah.gnu.org/bugs/?60660.

Bug existed since version 5.7, commit 77da54c6.
2021-05-23 18:55:41 +02:00
Benno Schulenberg
ceaae49b2d tweaks: avoid the subtraction of two size_t variables becoming negative
This fixes https://savannah.gnu.org/bugs/?60658.

Found by compiling with -fsanitize=undefined.
2021-05-23 11:46:37 +02:00
Benno Schulenberg
d1957819c4 bindings: show either "^/" or "^-" in the help lines, instead of "^_"
The "^_" has always been poorly legible (the underscore melting into
the bottom of the terminal) and difficult to type (Shift+Ctrl+minus).
The "^/" is both more readable and easier to type.

In terminal emulators, "^/" is shown, but on a Linux console "^-",
as ^/ does a backspace in the default console key mapping.

Also, allow using "^-" when rebinding ^_ in a nanorc file.

This addresses https://savannah.gnu.org/bugs/?57393.
2021-05-22 16:52:56 +02:00
Benno Schulenberg
7993fc8b12 syntax: nanorc: colorize literal control codes, to make them stand out
This makes it easier to read string binds that contain control codes.
2021-05-14 15:05:05 +02:00
Benno Schulenberg
51adf02d34 wrapping: when copying the quoting part, adjust the file size accordingly
Simply adding the number of bytes in the quoting part is not entirely
correct, but... currently the indenting and commenting routines also
assume that the whitespace and commenting characters that are added or
removed are single-byte characters...  It will require another patch
to make this all fully correct, but for the default configuration
(and probably most other cases) the current fix will work fine.

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

Bug existed since version 4.4, commit 8fce33af from two years ago,
since this automatic copying of the quoting part was introduced.
2021-05-14 10:24:07 +02:00
Benno Schulenberg
f23e98dd3a memory: prevent a leak when copying the leading quoting to the next line
This fixes https://savannah.gnu.org/bugs/?60596.

Bug existed since version 4.4, commit 8fce33af from two years ago,
since this automatic copying of the quoting part was introduced.
2021-05-14 09:56:45 +02:00
Benno Schulenberg
6472a6b828 display: when a message gets overwritten, note that it is cleared
When on a one-row terminal a message gets automatically "dropped"
after a few moments, the subsequent waiting for a keystroke should
not think that there is still a message on the status bar.

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

Bug existed since commit 8d974cd2 from two days ago.
2021-05-12 16:00:11 +02:00
Benno Schulenberg
b741b1c985 startup: skip drawing edit window when having message on one-row terminal
When there is just one row and there is a message, it is not a good idea
to draw the contents of the buffer as it would overwrite the message.

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

Bug existed since version 2.7.0, since nano allows very flat terminals,
and was made worse by commit 2cf28f9d from yesterday.
2021-05-12 15:47:21 +02:00
Benno Schulenberg
5f87ed5644 statusbar: ensure that "No further matches" does not get overwritten
Redraw the content of the edit window (for the undone final completion)
before pushing out the "No further matches" message, so that the latter
will not get overwritten by the buffer content -- in case the terminal
has just one row.

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

Bug existed since commit 2cf28f9d from yesterday.
2021-05-11 15:58:21 +02:00
Benno Schulenberg
8d974cd292 statusbar: on a one-row terminal, drop light messages after a few moments
Only important error messages (ALERT) and information that the user
requested (^C, M-D) should stay put until the next keystroke.  Other
messages should be overwritten by the text of the buffer after just
a few moments, to make a one-row terminal slightly more friendly.

This addresses https://savannah.gnu.org/bugs/?60570.
2021-05-10 20:08:49 +02:00
Benno Schulenberg
2cf28f9db7 statusbar: suppress the cursor when the terminal has just one row
When showing a message on the status bar, the cursor should be off.

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

Bug existed since version 2.7.0, since nano allows very flat terminals.
2021-05-10 12:27:56 +02:00
Benno Schulenberg
36ffb5f0ac statusbar: suppress --constantshow when the terminal has just one row
When there is just one row, the text to be edited needs to be shown
there, not some meta information about the cursor position.

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

Bug existed since version 2.7.0, since nano allows very flat terminals.
2021-05-09 19:16:03 +02:00
Benno Schulenberg
07fd4c4598 tweaks: condense and correct a comment, and move another
Since commit 5dcf375f from four years ago, a linter message must
contain a colon followed by a space for it to be recognized as a
linter message.
2021-05-07 12:40:25 +02:00
Benno Schulenberg
44fb3e9991 tweaks: frob some whitespace, and rewrap a line 2021-05-07 12:33:22 +02:00
Benno Schulenberg
088557c516 tweaks: remove a check that has become superfluous
Since version 5.6, commit 76742cc1, nano highlights the search match,
which means that the screen gets refreshed anyhow, so this specific
refresh for a one-row terminal is no longer needed.
2021-05-07 12:20:50 +02:00
Benno Schulenberg
4712d46462 linter: block the resizing signal while reading output from the linter
This prevents read() from returning unexpectedly and causing a crash.

This fixes https://savannah.gnu.org/bugs/?60537.
Reported-by: Filips Romāns <frfilips@gmail.com>

Bug existed since version 2.4.2, since the handling of SIGWINCH changed.
2021-05-06 13:30:41 +02:00
Benno Schulenberg
c01b13a32c syntax: php: colorize the full short tag for echo (<?=) 2021-05-05 12:09:17 +02:00
Benno Schulenberg
b368faf11c replacing: report the number of replacements also on a one-row terminal
That is: call edit_refresh() right away, to prevent the edit_refresh()
in the main loop from overwriting the status-bar message.

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

Bug existed since version 2.7.2, commit f920e0d3.
2021-05-05 10:41:55 +02:00
Benno Schulenberg
7303f0c7b4 search: show "This is the only occurrence" also on a one-row terminal
That is: call edit_refresh() right away, to prevent the edit_refresh()
in the main loop from overwriting the status-bar message.

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

Bug existed since version 5.6, commit 76742cc1.
2021-05-05 10:36:18 +02:00
Benno Schulenberg
eb3cc3a32d minibar: stay out of sight when the terminal has just one row
When there is just one row, the user wants to see text on this row,
not a bar with some meta info.

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

Bug existed since version 5.5, since the minibar was introduced
with commit d31cc373.
2021-05-03 15:52:15 +02:00
Benno Schulenberg
02df950240 po: update translations and regenerate POT file and PO files 2021-04-29 12:57:17 +02:00
Benno Schulenberg
a69a8ce3ca bump version numbers and add a news item for the 5.7 release 2021-04-29 11:28:21 +02:00
Benno Schulenberg
8a03d55c53 gnulib: pull in the fix for a build problem on older Debian
The issue was reported here:
  https://lists.gnu.org/archive/html/bug-gnulib/2021-04/msg00198.html
2021-04-28 09:49:14 +02:00
Benno Schulenberg
544351f3be syntaxes: replace [[:space:]] with [[:blank:]] to exclude carriage return
In many places a carriage return is not valid whitespace and should
thus not be colored as such.  In some of these places a vertical tab
or form feed is maybe valid whitespace, but it would be ugly or even
wrong to color them because they are not part of the subsequent
comment or keyword.

This fixes https://savannah.gnu.org/bugs/?60456.
2021-04-27 11:18:41 +02:00
Hussam al-Homsi
96ebaf8ab4 syntax: c: make the highlighting of '#include <...>' more compliant
Changes:
  1. There may be zero spaces between 'include' and '<...>'.
  2. Blanks and '=' may occur inside '<...>' but '>' may not.
  3. There must be at least one character inside '<...>'.

References:
  Change 1:
    C:   www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf#subsection.6.10.2
    C++: www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf#section.19.2

  Changes 2 and 3:
    C:   www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf#subsection.6.4.7
    C++: www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf#section.5.8

Signed-off-by: Hussam al-Homsi <sawuare@gmail.com>
2021-04-26 12:14:44 +02:00
Benno Schulenberg
6b7c661fb7 syntax: po: improve the coloring of format specifiers
This now handles most of the things listed in 'man 3 printf'.
2021-04-26 11:29:05 +02:00
Benno Schulenberg
6823831c06 build: drop the check for two functions that we don't use any more
Since commits b0209374 and 1c010d8e from a month ago, nano does not use
mblen() and mbtowc() any more, so there is no need to check for their
presence.

Instead, add a check for iswalpha(), which we do use.
2021-04-25 11:55:04 +02:00
Benno Schulenberg
ec82530125 gnulib: update to its current upstream state 2021-04-25 10:48:56 +02:00
Benno Schulenberg
a45e1f89c0 oops: that doesn't work -- you can't break out of two for loops at once
This effectively reverts the previous commit.
2021-04-24 13:56:36 +02:00
Benno Schulenberg
c1cd813dcb tweaks: elide a function that is now basically just two lines 2021-04-24 11:48:04 +02:00
Benno Schulenberg
c96e62e33a startup: save the compiled file-matching regexes, to avoid recompiling
This reduces startup time by seven percent (when using the standard set
of syntaxes) when opening just one file that doesn't match any syntax,
and more than ten percent when opening multiple files.  It takes some
extra memory, but... not wasting CPU cycles is more important.

This addresses https://savannah.gnu.org/bugs/?56433.
2021-04-24 10:54:04 +02:00
Benno Schulenberg
6283557d2f memory: prevent a use-after-free when the user respects a lock file
This fixes https://savannah.gnu.org/bugs/?60447.

Bug existed since commit 2f718e11 from a month ago.
2021-04-23 12:20:45 +02:00
Benno Schulenberg
af90f03ac5 tweaks: condense three comments, drop another, and rewrap a line 2021-04-23 12:04:19 +02:00
Benno Schulenberg
588022ab8c editing: prevent the pointer for the top row from becoming dangling
When undoing several actions, it is possible for the line at the top
of the screen to be removed, leaving 'edittop' pointing to a structure
that has been freed.  Soon after, 'edittop' is referenced to determine
whether the cursor is offscreen...  Prevent this invalid reference by
stepping 'edittop' one line back in that special case.  This changes
the normal centering behavior of Undo when the cursor goes offscreen,
but... so be it.

When a single node is deleted, it is always possible to step one line
back, because a buffer contains always at least one line (even though
maybe empty), so if the current line could be deleted, there must be
one before it (when at the top of the screen).

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

Bug existed since version 2.3.3, commit 60815461,
since undoing does not always center the cursor.
2021-04-23 09:35:12 +02:00
Benno Schulenberg
cf0820549b tweaks: avoid calling extra_chunks_in() when not softwrapping
The function is somewhat costly; better avoid it whenever possible.
2021-04-22 12:19:09 +02:00
Benno Schulenberg
f54bc6c7d6 indicator: adjust the size to the number of visible lines, not chunks
Since two commits ago, the position of the indicator shows the position
of the viewport relative to the full buffer in terms of actual lines,
not of visual chunks (to avoid excessive computation).  But the size of
the indicator stayed constant, as if it always covered as many lines as
the edit window has rows.  But the latter will not be the case when
softwrapping occurs.  Therefore, when softwrapping, compute how many
actual lines are visible in the viewport, and adjust the size of the
indicator accordingly.
2021-04-22 11:52:57 +02:00
Benno Schulenberg
2cdff6c32c tweaks: adjust two comments, and reshuffle two fragments
Also rename two variables, to be more fitting.
2021-04-21 16:52:35 +02:00
Benno Schulenberg
49d8b99e4f softwrap: avoid time-consuming computations, to burden large files less
Whenever softwrap was toggled on or line numbers were toggled on/off or
the window was resized, the extra rows per line needed to be recomputed
for ALL the lines.  For large files with many long lines this was too
costly.

(This change causes the indicator to have an incorrect size when there
are many softwrapped chunks onscreen, but that will be addressed later.)

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

Problem existed since version 5.0, since the indicator was introduced.
2021-04-21 16:40:20 +02:00
Benno Schulenberg
bb81932422 chars: work around the wrong private-use-character widths on OpenBSD
This fixes https://savannah.gnu.org/bugs/?60393.
2021-04-20 11:13:08 +02:00
Benno Schulenberg
5efb6836a8 options: retire the obsolete 'smooth', 'morespace', and 'nopauses' 2021-04-15 11:43:39 +02:00
Benno Schulenberg
48fa14acc0 tweaks: simplify two fragments of code
This makes the handling of plain ASCII a tiny bit slower, but it
affects only the users of --constantshow without --minibar, so...

All other uses of mbstrlen() and collect_char() are not in speed-
critical code paths.
2021-04-13 11:19:32 +02:00
Benno Schulenberg
eb7181b35e tweaks: adjust and improve one comment, and frob another 2021-04-12 15:14:05 +02:00
Benno Schulenberg
8db42023bb files: when Mac format has been detected, stay with it
This fixes https://savannah.gnu.org/bugs/?60382.

Bug existed since commit 09b919a6 from three weeks ago.
2021-04-12 14:50:04 +02:00
Benno Schulenberg
018a8e12ca build: fix compilation for --enable-tiny plus --enable-multibuffer
This will not show the error messages for other buffers when using
a tiny build, but... one cannot have everything.
2021-04-10 12:01:34 +02:00
Benno Schulenberg
b4a5aedc6c tweaks: remove a misplaced (and nested) #ifdef
It was accidentally introduced two weeks ago by commit 1c010d8e.
2021-04-09 16:55:07 +02:00
Benno Schulenberg
d6ed174d09 tweaks: morph a function into what it is actually used for
Since the previous commit, mbwidth() is used only to determine whether
a character is either double width or zero width.  There is no need to
return the actual width of the character; a simple yes or no is enough.

Transforming mbwidth() into is_doublewidth() also allows streamlining
it and is_zerowidth() a bit, so that they become slightly faster.
2021-04-09 16:38:23 +02:00
Benno Schulenberg
78f92e044a tweaks: avoid parsing a multibyte character twice
The number of bytes in the character were determined twice: first in
mbwidth() and then in char_length().  Do it just once, in mbtowide().

Also, avoid calling is_cntrl_char(), because it does unneeded checks
when we already know that the high bit is set.

This duplicates some code, but advance_over() is called a lot, so it
is important that it is as fast as possible.

This shouldn't slow down plain ASCII, as the extra checks (use_utf8
and *string < 0xA0) are done only for non-ASCII (apart from DEL).
2021-04-09 11:32:15 +02:00
Benno Schulenberg
f11931a0dd tweaks: rename a variable, for contrast with another
The 'start_index' was in index in the given text, while 'index' is an
index in the displayable string.  Having both of them using 'index' in
their name was somewhat confusing.
2021-04-08 12:19:34 +02:00
Benno Schulenberg
31a6931be9 tweaks: elide a call of strlen() for every row
For a normal file (without overlong lines) the strlen() wasn't much
of a problem.  But when there are very long lines, it wasted time
counting stuff that wouldn't be displayed on the current row anyway,
and reserved *far* too much memory for the displayable string.

Problem existed since commit cf0eed6c from five years ago that traded
a continuous comparison (of the used space with the reserved space)
against a one-time big reservation up front involving a strlen().
In retrospect that was not a good trade-off when softwrapping.

The extra check (charwidth == 0) is incurred only by characters that
have their high bit set, so the average file (with only ASCII) is not
affected by this -- it just loses an unneeded call of strlen().
2021-04-08 12:15:12 +02:00
Benno Schulenberg
debb288115 tweaks: reduce the maximum character length from six bytes to four
In UTF-8 valid multibyte characters are at most four bytes long,
and now that we no longer make use of mblen() and mbtowc() from
the underlying system, we won't get five- or six-byte sequences
mistakenly reported as valid (by glibc).  So it is always enough
to reserve space for just four bytes per character.
2021-04-07 17:21:25 +02:00
Benno Schulenberg
c75a3839da tweaks: elide a small function that is used just once 2021-04-07 17:08:05 +02:00
Benno Schulenberg
b6a32fbd5f tweaks: elide an unneeded resetting NULL call to wctomb()
Calling wctomb() with NULL as the first parameter returns zero in a
UTF-8 locale, meaning that there is no state, so there is no point
in resetting it either.
2021-04-07 16:11:40 +02:00
Benno Schulenberg
09e4c86606 tweaks: improve a couple of comments 2021-04-07 12:28:48 +02:00
Benno Schulenberg
20eb422829 tweaks: avoid converting a file name for more than will fit on screen 2021-04-07 12:12:06 +02:00
Benno Schulenberg
90c6b572d0 display: avoid determining twice from and until where to draw each row
The two calls of draw_row() are each immediately preceded by a call to
display_string(), which has already determined from which x position
and until which x position in the relevant line the current row will
be drawn -- doing this again in draw_row() is a waste of time.  Even
though it is ugly, pass the two data points from one function to the
other via global variables.

For normal files (without overlong lines), this saves on average some
fifty calls of advance_over() per row.  When softwrapping a file with
overlong lines, the savings for each softwrapped chunk are much higher.
2021-04-07 11:27:10 +02:00
Benno Schulenberg
712b574fb7 tweaks: rename a variable, away from an abbreviation 2021-04-06 16:27:46 +02:00
Benno Schulenberg
fd023d6dcf tweaks: put the most likely condition first, for a quicker return
Also condense a comment.
2021-04-06 11:32:25 +02:00
Benno Schulenberg
9c16be32d7 tweaks: reshuffle two conditions, to have the most unlikely one first
This also better fits the preceding comment.
2021-04-05 16:10:44 +02:00
Benno Schulenberg
c3cdb099da tweaks: reshuffle a comment, and put the main extension first
And add some air to the compact file.
2021-04-05 16:06:54 +02:00
Mike Frysinger
682a088fb8 syntax: tcl: support Expect scripts too 2021-04-05 16:02:44 +02:00
Benno Schulenberg
8c25bd0e94 tweaks: elide two more instances of useless character copying
Just point at the relevant characters directly
instead of first copying them out.
2021-04-02 16:39:10 +02:00
Benno Schulenberg
20e122ef41 startup: show the helpful message only when ^G has not been rebound
(Well, it now checks that ^G is still the first shortcut that is bound
to 'do_help', but that is good enough: if the user did any rebinding,
they probably do not need any reminder about how to invoke 'Help'.)

This fixes https://savannah.gnu.org/bugs/?60315.
Reported-by: Robert Goulding <goulding.2@nd.edu>
2021-04-01 10:09:28 +02:00
Benno Schulenberg
0dcac9188f tweaks: simplify two fragments of code, eliding useless character copying 2021-03-29 20:06:05 +02:00
Benno Schulenberg
1c010d8ec9 chars: implement mbtowc() ourselves, for more efficiency
This saves a function call, and the passing and checking of the
MAXCHARLEN parameter, and the checking whether wc is maybe NULL
(which for nano is never the case), and who knows what other
overheads mbtowc() has, and our workaround for glibc.

Code was written after looking at gnulib/lib/mbrtowc-impl-utf8.h.
2021-03-29 12:36:10 +02:00
Benno Schulenberg
b020937475 chars: implement mblen() ourselves, for efficiency
Most implementations of mblen() do a call to mbtowc(), which is
a waste of time when all we want to know is the number of bytes
(and when we already know that we're using UTF-8 and that the
first byte is at least 0xC2).

(This also avoids burdening correct implementations with the
workaround that was needed only for glibc.)

Code was written after looking at gnulib/lib/mbrtowc-impl-utf8.h.
2021-03-27 14:38:28 +01:00
Benno Schulenberg
e3f46b066a build: fix compilation when configured with --disable-multibuffer 2021-03-26 12:21:44 +01:00
Benno Schulenberg
df7fe1280d tweaks: drop unneeded braces and adjust indentation after previous change 2021-03-26 12:17:44 +01:00
Benno Schulenberg
929770191e chars: work around a UTF-8 bug in glibc, to display invalid codes right
The mblen() and mbtowc() functions will happily return 4 or 5 or 6
for byte sequences that start with 0xF4 0x90 or higher.  But those
sequences encode for U+110000 or higher, which are not valid Unicode
code points.  The libc of FreeBSD and OpenBSD and Alpine correctly
return -1 for such sequences.  Make nano behave correctly also when
linked against glibc, so that invalid sequences are always presented
as a series of invalid bytes and never as a single invalid code.

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

Bug existed since before version 2.0.0.
2021-03-26 11:07:05 +01:00
Benno Schulenberg
66d9d6c6d2 tweaks: elide the pointless is_valid_unicode() function
The call of this function in make_mbchar() does not add anything,
because wctomb() already returns -1 for codes U+D800 to U+DFFF,
and parse_verbatim_kbinput() already rejects anything that starts
with U+11.... or higher, so make_mbchar() is never called for codes
beyond U+10FFFF.

And the call in display_string() just needs to check for wc <= 0x10FFFF
because mbtowc() already returns -1 for codes U+D800 to U+DFFF.
2021-03-25 11:24:41 +01:00
Benno Schulenberg
de816840cb input: accept Unicode codes for non-characters as valid, since they are
That is, accept U+FDD0 to U+FDEF, and accept U+xxFFFE and U+xxFFFF
for xx from 00 to 10 hex, being the 66 reserved "non-characters".

It may not be wise of the user to input these "things" (by typing
their code after M-V), but the codes are valid Unicode code points
and should not be rejected.

See https://www.unicode.org/faq/private_use.html#nonchar8 et al.

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

Bug existed since before version 2.0.0.
2021-03-24 17:11:05 +01:00
Benno Schulenberg
74fcc3be79 tweaks: normalize the indentation after an earlier change
(Should have been done yesterday, right after commit 2f718e11.)
2021-03-24 12:29:50 +01:00
Benno Schulenberg
b6909d3737 build: fix compilation when configured with --enable-tiny
Commit 0c1bf429 from last week added two calls to digits()
for --constantshow.
2021-03-24 12:21:50 +01:00
Benno Schulenberg
823d79b36c tweaks: shorten a comment and trim an #ifdef 2021-03-24 12:16:10 +01:00
Benno Schulenberg
735757b0c1 tweaks: set the file format only when unset, so it doesn't need saving
When inserting a file into the current buffer, the 'fmt' element will
already be set.  When we avoid overwriting the current value of 'fmt'
(when it's other than UNSPECIFIED), we don't need to save and restore
the value when inserting a file.
2021-03-24 12:00:34 +01:00
Benno Schulenberg
09b919a68f files: always register the format, also when the file is unwritable
When saving the buffer under a different name, it should by default
have the same format as the original file.

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

Bug existed since version 2.6.0, commit 0293eac1.
2021-03-24 11:53:56 +01:00
Benno Schulenberg
2f718e11a7 files: create a new buffer earlier, so that error messages can be stored
This improves the fix for https://savannah.gnu.org/bugs/?60269,
by not dropping error messages that happen before a buffer is opened.

This basically reverts commit b63c90bf from a year ago, except that
it now always deletes the created buffer when the user does not want
to override the lock file, also when it is the only buffer.
2021-03-23 16:46:37 +01:00
Benno Schulenberg
77da54c6c6 startup: do not store an error message in the record of another buffer
Set the 'format' of a file only when it has been fully read in,
so that this field can be used to indicate that any later error
message cannot be meant for this buffer.

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

Bug existed since commit 6bf52dcc from yesterday.
2021-03-23 16:19:07 +01:00
Benno Schulenberg
6bf52dcc8d startup: do not crash when trying to open a device or directory
Make sure there is an 'openfile' record before trying to save an
error message in this record.

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

Bug existed since commit ede64d7e from yesterday.
2021-03-22 15:50:31 +01:00
Benno Schulenberg
3d9e803aed syntax: c: colorize also labels that contain digits, and uncolorize colon
Labels may contain digits (after the first character).
And the colon after "default" should not be colored.

Inspired-by: Hussam al-Homsi <sawuare@gmail.com>
2021-03-22 11:41:08 +01:00
Benno Schulenberg
ede64d7ea0 feedback: upon first switch to a buffer, show its error message (if any)
When opening multiple files and some of them had an error, only the
first message was shown and the others were lost -- indicated only
by three dots.  Improve upon this by storing the first error message
for each buffer and showing this message when the buffer is first
switched to.

Requested-by: Mike Frysinger <vapier@gentoo.org>
2021-03-21 16:52:29 +01:00
Benno Schulenberg
e8db390d6f tweaks: reshuffle a fragment of code, to prepare for the next change
Also, don't reserve MAXCHARLEN bytes for the terminating NUL byte.
2021-03-21 16:52:29 +01:00
Benno Schulenberg
0c1bf429e8 display: make the output of --constantshow less jittery
That is: reserve for the current line and current character the number
of positions needed for the total number of lines and characters, and
reserve two positions for both the current column and the total number
of columns.  This will keep all nine numbers in the output in the same
place -- as long as there are no lines with more than 99 columns.  In
this latter case there will still be some jitter, but all-in-all the
output is much stabler than it was.

Suggested-by: Mike Frysinger <vapier@gentoo.org>
2021-03-18 16:20:04 +01:00
Benno Schulenberg
f6357a73f0 memory: fix an off-by-one error to free also the last line in a group
The number of lines in a group is the difference in line numbers
between the last line and the first line *plus one*.

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

Bug existed since version 2.9.0, since indenting and unindenting
became undoable, and commit f722c532 formed a part of that.
2021-03-05 18:50:34 +01:00
Benno Schulenberg
49ca7e5aa8 memory: do not allocate space for multidata when it's already allocated
Allocating it again would leak the existing space.

This fixes https://savannah.gnu.org/bugs/?60172.
Reported-by: Mike Frysinger <vapier@gentoo.org>

Bug existed since version 5.6, commit 1fdd23d3.
2021-03-05 11:25:14 +01:00
Benno Schulenberg
be9b1a1887 tweaks: avoid a warning on newer compilers, by writing an extra byte
When the version number is a trio, the version string will occupy
ten bytes and the terminating NUL byte would not be written (which
was not a problem as byte 12 of the lock data is zero anyway).
But it's better to not have the compiler complain, so allow writing
the terminating NUL byte outside of the ten bytes reserved for the
version string.
2021-03-03 10:47:41 +01:00
Benno Schulenberg
bb74aacf2d po: update translations and regenerate POT file and PO files 2021-03-03 10:11:58 +01:00
Benno Schulenberg
b72d9af52c bump version numbers and add a news item for the 5.6.1 release 2021-03-03 09:47:41 +01:00
Benno Schulenberg
a9ccd99b90 tweaks: rename a symbol, to better match the corresponding option 2021-03-03 09:39:49 +01:00
Benno Schulenberg
ac5e5179fb options: rename 'highlightcolor' to the more distinct 'spotlightcolor'
This way there cannot be any confusion with syntax highlighting,
and it indicates better that a single place will be highlighted.
2021-03-03 09:31:46 +01:00
Benno Schulenberg
a543f8cd8f search: correctly colorize a match also when softwrapping is active
This fixes https://savannah.gnu.org/bugs/?60149.
Reported-by: Peter Passchier <peter@passchier.net>
Reported-by: Liu Hao <lh_mouse@126.com>

Bug existed since version 5.6, since a special color for highlighting
search matches was introduced in commit 87fe73dd.
2021-03-01 10:43:28 +01:00
Benno Schulenberg
d7853df8b6 po: update translations and regenerate POT file and PO files 2021-02-24 11:09:56 +01:00
Benno Schulenberg
1e9d12abc5 bump version numbers and add a news item for the 5.6 release 2021-02-24 09:23:50 +01:00
Benno Schulenberg
3bce9fb755 gnulib: update to its current upstream state 2021-02-23 09:53:17 +01:00
Benno Schulenberg
0a57da42e0 docs: correct the description of --quickblank for the changed base value
And mention that --minibar overrides the option too.
2021-02-22 12:24:06 +01:00
Benno Schulenberg
73067e0e16 build: include a workaround only for versions of ncurses that need it
The cursor-misplacement bug has been fixed in ncurses-6.2-20210220:

  https://lists.gnu.org/archive/html/bug-ncurses/2021-02/msg00010.html

See also https://savannah.gnu.org/bugs/?59808.
2021-02-21 12:00:28 +01:00
Benno Schulenberg
b9328d0eac feedback: make Full Justify show a message also when using --minibar
Full justification (like justification of a selection) is probably
a rather rare action -- and possibly even an unintended action --
so it's good to give feedback about what happened also when using
the minibar.
2021-02-20 12:11:43 +01:00
Benno Schulenberg
0596b875f0 painting: trigger a refresh when a second start match appears on a line
When a line is marked as JUSTONTHIS, there should be no second start
match on that line, because otherwise the line would have been marked
as STARTSHERE (unless there is also a second end match -- but it's
fine to do unnecessary refreshes in this unlikely case, as long as
the necessary refreshes are made).

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

Bug existed since version 2.5.0, but has been masked (for the C syntax)
by unnecessary refreshes since version 4.1, commit c9605e73.
2021-02-18 17:15:24 +01:00
Benno Schulenberg
b94dcfd34b painting: trigger fewer unneeded full-screen refreshes
When a line is marked as NOTHING, then the existence or the appearance
of an end match is irrelevant: there is no unpaired start match, so no
recoloring would occur, so there is no need to refresh.

When a line is marked as WOULDBE, then the existence or the appearance
of a start match is irrelevant (for the lines after the first WOULDBE
line): there already is an unpaired start match, so another one will
not change anything, so no refresh is needed.  Only the appearance of
an end match would recolor things and thus require a refresh.  However,
start and end regexes could match the same thing, so an end might get
misinterpreted as a start.  So the rule has to check for the absence
of both a start and an end match, like for WHOLELINE.

This addresses https://savannah.gnu.org/bugs/?60072.
2021-02-18 12:21:37 +01:00
Benno Schulenberg
4238564673 tweaks: rewrap two lines, for esthetics 2021-02-16 16:52:41 +01:00
Benno Schulenberg
764ab96bda tweaks: make a skipping condition more precise
A step forward needs to be forced not when both start match and
end match have zero length, but when the "full match" (all text
from the start of the start match to the end of the end match)
covers zero bytes.  In other words: the start and end match are
both of zero length AND are at the same spot.
2021-02-16 16:12:41 +01:00
Benno Schulenberg
f0cc59bead color: use inverse video for highlighting when there are no colors
When a terminal has no colors but has the ability to hide the cursor
(like a VT320), then using --bold would make a search match too hard
to see.
2021-02-16 11:28:22 +01:00
Benno Schulenberg
282f438967 color: use bright yellow to highlight a search match
Plain yellow is too dark (more like brown) on some machines.
Lightyellow is a bit loud, but... very visible.
2021-02-15 12:29:15 +01:00
Benno Schulenberg
1b01adfa9f docs: mention the new 'set highlightcolor' option 2021-02-14 12:51:09 +01:00
Benno Schulenberg
87fe73ddaa color: give highlighted text its own color, to not look like marked text
Now that a search match gets highlighted, the unsuspecting user might
think that the text is selected, because it is colorized the same way
as selected text.  Avoid this by colorizing a highlighted search match
with its own specific color, black on yellow by default.
2021-02-14 12:51:09 +01:00
Benno Schulenberg
c2746c0bb2 tweaks: reshuffle some code, and reduce the scope of a variable 2021-02-08 12:33:10 +01:00
Benno Schulenberg
399a024857 minibar: suppress the toggling feedback for M-C, but show it for M-Y/M-P
In addition, suppress the feedback for M-C also when --minibar
isn't used, as the feedback obscures the effect of the toggle:
showing information about the cursor position on the status bar.

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

Bug existed since commit 7545eb5b from one week ago.
2021-02-08 10:27:29 +01:00
Benno Schulenberg
d131c2d438 minibar: show a message a little longer when --quickblank isn't used
The --minibar option made --quickblank a no-op.  Now the use of the
latter together with --minibar still has some effect.
2021-02-07 12:09:38 +01:00
Benno Schulenberg
eb0962fb06 docs: remove all mentions of --markmatch and 'set markmatch' 2021-02-07 09:18:15 +01:00
Benno Schulenberg
7bf253702e options: remove --markmatch and 'set markmatch', as the behavior is gone 2021-02-07 09:18:15 +01:00
Benno Schulenberg
76742cc193 search: make highlighting the standard, non-changeable behavior
Highlighting an occurrence is so much clearer than just putting the
cursor on it.  People seem to like it.  So let's make this how nano
behaves by default.
2021-02-07 09:18:15 +01:00
Benno Schulenberg
37717baeed search: just highlight the found occurrence, instead of marking it
Requested-by: Peter Passchier <peter@passchier.net>
2021-02-07 09:18:15 +01:00
Benno Schulenberg
ade2fafbd3 tweaks: remove a strangely placed warning
(After some trying, I haven't seen the warning displayed, but...
I'm not yet sure that it could never occur, so I keep the 'if'.)
2021-02-06 19:12:43 +01:00
Benno Schulenberg
53fe7ba26a tweaks: be slightly more efficient in marking lines as WOULDBE
Take two conditions that are relevant only for a rather unlikely case
(a start match without a corresponding end match) out of an inner loop.
Give the case its own, dedicated loop.
2021-02-06 17:01:02 +01:00
Benno Schulenberg
7e04fea92b painting: when finding an end match, set its multidata right away
When leaving the multidata unset (as was done until now) and the
end match is offscreen, then this could lead to miscolorings later
when jumping over this end match instead of scrolling past it.

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

Bug existed since before version 2.1.10.
2021-02-05 17:25:03 +01:00
Benno Schulenberg
1fdd23d347 display: for a large paste or insertion, recalculate the multiline cache
When a large piece of text or code is pasted or inserted, it could
contain matches for start= and end= regexes, and backtracking from
the current screen could mistake an end for a start and could thus
miscolor things.  Avoid this by recalculating the multiline cache
for pastes and insertions that cover more than a screenful.

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

Bug existed since version 2.6.0, but existed also before 2.4.3.
2021-02-03 17:00:28 +01:00
Benno Schulenberg
5ea930e25f build: detect a build from git also when building out of tree
Reported-by: Hans-Bernhard Bröker <HBBroeker@t-online.de>

Bug existed since version 2.6.0, commit ec295f5e.
2021-02-02 12:00:24 +01:00
Benno Schulenberg
45defd25f3 build: avoid a warning about duplicate symbol when building from tarball
Reported-by: Hans-Bernhard Bröker <HBBroeker@t-online.de>

Bug existed since commit 3ea2694d from last week.
2021-02-02 11:39:26 +01:00
Benno Schulenberg
0d11964503 docs: say that --minibar is modified by --constantshow and --stateflags
The previous two commits reduced what is shown by default on the minibar.
Mention which extra options are needed to show the extra information.
2021-02-02 11:10:09 +01:00
Benno Schulenberg
7545eb5bbf minibar: show the state flags only when --stateflags is used
For users who always have auto-indent or hardwrap or softwrap on
and do not need to see this continuously advertised at the bottom.
2021-02-02 11:10:09 +01:00
Benno Schulenberg
878bd53d11 minibar: show cursor position + character code only with --constantshow
This allows having an even leaner interface, and gives the M-C toggle
an appropriate function (instead of leaving it a "dead" keystroke).

Suggested-by: Sébastien Desreux <seb@h-k.fr>
2021-02-02 11:10:09 +01:00
Benno Schulenberg
e0a4ee0148 scrolling: keep centering after large paste, also when line numbers widen
If a paste (or insertion) is more than a screenful, it will not set
'focusing' to FALSE.  In that case, and when line numbers are already
active, then 'focusing' should be kept set to TRUE, despite it getting
set to FALSE by ensure_firstcolumn_is_aligned().  That latter action
is meant to cushion size changes of the edit window, but in this case
the large paste (or insertion) should trump the size change.

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

Bug existed since version 2.8.3, commit 2b385478.
2021-02-01 12:42:55 +01:00
Benno Schulenberg
d3fbc4d498 tweaks: remove an old fix that was made superfluous by a recent fix
Commit 43d94692 fixed a miscoloring bug [1] by doing proper backtracking
for multiline regexes.  But this change also solves an older miscoloring
issue [2] without needing to recalculate all the multiline data.  So...
just drop the old fix.  (This isn't perfect: it's probably possible to
cook up a replacement scheme where things get miscolored, but... until
then, this is good enough.)

  [1] https://savannah.gnu.org/bugs/?59948
  [2] https://savannah.gnu.org/bugs/?58481

Also, there is no need to set 'refresh_needed' in do_replace_loop(),
because each replacement prompt will call edit_refresh() anyway, and
the functions that call do_replace_loop() will set it afterward.
2021-01-29 16:57:11 +01:00
Benno Schulenberg
a8e2a24f60 tweaks: frob a condition, to be more concise, and reshuffle another 2021-01-29 10:58:09 +01:00
Benno Schulenberg
36855544d1 tweaks: rewrap and reindent a few lines 2021-01-29 10:52:40 +01:00
Benno Schulenberg
dc745c0b77 tweaks: elide a function that is now just one line 2021-01-29 10:30:05 +01:00
Benno Schulenberg
a8ed1d7a9a tweaks: don't bother wiping the multidata before recomputing it
The precalc_multicolorinfo() routine will assign a value to every
element for every line without looking at any current value, so
wiping the data first is a waste of time.
2021-01-29 10:25:27 +01:00
Benno Schulenberg
94c371a38f tweaks: don't bother initializing freshly allocated multidata
After having been allocated, the multidata will get computed
immediately, in precalc_multicolorinfo() and draw_row(), so
first setting each element to -1 is a small waste of time.
2021-01-29 10:18:39 +01:00
Benno Schulenberg
36618f1dca tweaks: don't bother comparing virgin multidata with current situation
The initialization of -1 cannot possibly match with NOTHING or
WHOLELINE or the other available values.

(Also, put in a warning, as I don't think an onscreen line without
a multidata cache can occur at all.)
2021-01-29 10:06:03 +01:00
Benno Schulenberg
3ea2694d9c tweaks: rename six symbols, to be more straightforward 2021-01-28 16:11:57 +01:00
Benno Schulenberg
85cc99a2a3 tweaks: frob some comments, and reshuffle two fragments of code 2021-01-28 15:44:54 +01:00
Benno Schulenberg
befe4ea5de tweaks: frob some comments, and adjust indentation after previous change 2021-01-28 11:57:33 +01:00
Benno Schulenberg
43d94692ce painting: always do backtracking for the first row of the screen
Backtracking from the first row is needed in case a start match was
added recently somewhere offscreen and the user jumped to the current
location (instead of scrolling) so that the CWOULDBE markings did not
reach the current lines.

Also, search for an end match only for the first screen row.  For the
other rows, rely on the CENDAFTER, CWHOLELINE, and CWOULDBE values to
indicate whether there *is* an end match (the first two values) or not.
This saves considerable time when there is no end match in the large
remainder of a buffer: it will search in vain for the end match just
once, instead of for every row of the screen.

This fixes https://savannah.gnu.org/bugs/?59948,
and addresses https://savannah.gnu.org/bugs/?59945.

Bug existed since version 2.7.5, commit b3bcc8ee.
2021-01-27 17:01:17 +01:00
Benno Schulenberg
1364b41dc9 debug: add timing instruments to cache precalculation and screen refresh 2021-01-26 16:06:31 +01:00
Benno Schulenberg
7d3a555464 tweaks: avoid the vague possibility of advancing beyond end-of-line
Like the other two fragments that advance over a zero-length match,
also this fragment should avoid the possibility of stepping beyond
the end of the line.
2021-01-24 17:19:44 +01:00
Benno Schulenberg
0508520b47 tweaks: reshuffle three conditions into a better order
When a zero-length match is beyond the width of the screen, there
is no point in continuing evaluating the rule, so the check for
"offscreen to the right" needs to come first.  The check for a
zero-width match needs to come second because otherwise we would
get stuck on such a match when it is offscreen to the left.
2021-01-24 17:19:37 +01:00
Benno Schulenberg
6cbb7bc443 tweaks: frob two fragments of code, to be more readable 2021-01-24 16:44:38 +01:00
Benno Schulenberg
055e262b56 tweaks: stop evaluating a rule when the match is offscreen to the right
When the match of a coloring regex is beyond the width of the screen,
there is no point in continuing to evaluate the regex for the rest of
the line, because any other matches will be offscreen too.

This will save some time when there are several overlong lines.
2021-01-24 12:40:34 +01:00
Benno Schulenberg
9d8388e836 tweaks: call wattron()/wattroff() only when actually painting something
A syntax has on average a dozen coloring rules, but on average maybe
three or four pieces of text (rough estimate) in a line get painted.
So, on average, it is cheaper to call wattron() and wattroff() only
when actually coloring a piece of text, instead of calling wattron()
before starting to evaluate each rule and wattroff() after finishing
its evaluation.
2021-01-23 19:28:08 +01:00
Benno Schulenberg
895de17a58 color: do not look for another 'end' match after already finding one
When reaching end-of-line after having found a zero-width end match,
nano should not continue at 'seek-an-end' but instead at 'step_two':
going on to seek a start match in the current line.

(There is no bug report, because I cannot figure out how to trigger
this issue and cause nano to misbehave.  The problem was found while
reviewing the comments.)

Bug existed since commit 9a4a5454 from four years ago,
but the behavior was poorer before that commit.
2021-01-22 16:40:53 +01:00
Benno Schulenberg
b202966d30 tweaks: correct a comment, improve another, and trim some verbosity 2021-01-22 11:58:53 +01:00
Benno Schulenberg
a19a7820f9 color: recompile the file-probing regexes a little faster with REG_NOSUB
When the filename, header-line, and magic regexes are first compiled
while reading in the rc files (to check their validity), REG_NOSUB is
used, but for some reason this wasn't done when each of these regexes
gets recompiled in order to be used.  Fix this oversight.  It shaves
some twenty percent off of each of these regexes' compiling time.
2021-01-21 12:35:16 +01:00
Benno Schulenberg
0122119a44 docs: correct the word order for Alt+D in the cheat sheet -- it changed 2021-01-20 19:25:29 +01:00
Benno Schulenberg
64bf03b0d9 docs: correct the formatting of a comment in the sample nanorc 2021-01-15 10:05:04 +01:00
Benno Schulenberg
4bc6d67052 po: update translations and regenerate POT file and PO files 2021-01-14 11:21:21 +01:00
Benno Schulenberg
7519a458b2 bump version numbers and add a news item for the 5.5 release 2021-01-14 11:08:05 +01:00
Benno Schulenberg
bc36813349 memory: avoid leaking the speller or linter command string, when invoked
This fixes https://savannah.gnu.org/bugs/?59854.
Reported-by: Mike Frysinger <vapier@gentoo.org>

Bug existed probably since version 2.9.6, commit 94347f08.
2021-01-11 19:36:34 +01:00
Benno Schulenberg
9bd7d62c10 tweaks: do not change the pointer, but move the content of the string 2021-01-11 19:22:40 +01:00
Benno Schulenberg
735a608e80 speller: strip leading whitespace from command, to avoid a sneaky crash
This completes the fix for https://savannah.gnu.org/bugs/?59855.
2021-01-11 19:15:35 +01:00
Benno Schulenberg
71402bb7e9 feedback: wipe the status bar by default after 20 keystrokes
The 26 keystrokes inherited from Pico is a weird number, and too long.
2021-01-11 16:18:35 +01:00
Benno Schulenberg
9266fa6657 speller: do an internal spell check when --speller is an empty string
This fixes https://savannah.gnu.org/bugs/?59855.
Indirectly-reported-by: Mike Frysinger <vapier@gentoo.org>

Bug existed since version 2.9.6, commit 94347f08.
2021-01-11 16:05:54 +01:00
Benno Schulenberg
6360e4170a copyright: update the years for the FSF 2021-01-11 14:22:51 +01:00
Benno Schulenberg
dcb072d04b build: fix compilation for --enable-{tiny,help,multibuffer}
The mark is not available in the tiny version,
nor can the cursor get hidden by --markmatch.
2021-01-11 13:24:10 +01:00
Benno Schulenberg
4c6ce3c39d minibar: when the overnext character has zero width too, show its code
Requested-by: Peter Passchier <peter@passchier.net>
2021-01-09 12:44:10 +01:00
Benno Schulenberg
41fd09706d minibar: when the next character has zero width, show its code too
This allows seeing that an accented character is not a single code point
but composed from a base character plus a combining character.
2021-01-09 12:44:10 +01:00
Benno Schulenberg
24e5f956d0 build: fix compilation when configured with --disable-utf8
This fixes https://savannah.gnu.org/bugs/?59842.
Reported-by: Ruben van Wyk <admin@knwip.com>

Bug existed since commit 5129e718 from two days ago.
2021-01-08 12:05:55 +01:00
Benno Schulenberg
f602613a9a tweaks: avoid compilation warnings on 32-bit machine plus newer compiler 2021-01-07 16:17:17 +01:00
Benno Schulenberg
ba124ffa5d gnulib: update to its current upstream state 2021-01-07 15:20:45 +01:00
Benno Schulenberg
d30ddf0add tweaks: correct a translator hint 2021-01-07 15:18:57 +01:00
Benno Schulenberg
e66c7d0f8d tweaks: put the new options in a consistent order in the code 2021-01-07 14:27:49 +01:00
Benno Schulenberg
7b9567719c tweaks: reshuffle an option, to have two related ones grouped together
Options --stateflags and --minibar are slightly related; it looks
better to not have them separated by an unrelated option.
2021-01-07 14:27:49 +01:00
Benno Schulenberg
04d33e7981 tweaks: reword the description of an option
Avoid using the word "state" in the description of --minibar,
as it could cause confusion with the --stateflags option.
2021-01-07 14:27:49 +01:00
Benno Schulenberg
c62d12ca93 tweaks: drop a small optimization for invalid UTF-8 starter bytes 2021-01-07 10:37:35 +01:00
Benno Schulenberg
297633d086 minibar: show Unicode codes when in a UTF-8 locale
The only exception is 0x00.  But that code should really not occur
in a normal text.  And if it does, it is fine that it stands out.
2021-01-07 10:36:14 +01:00
Benno Schulenberg
10b99d8ac0 chars: short-circuit determining the width of characters under U+0300
The combining characters (that are zero-width) start at U+0300.
After that it's pretty much chaos, width-wise.

The mbwidth() function is not called for control characters (whose
representation takes up two columns), as they are handled separately.

The calls of mbwidth() that *can* happen with a control character as
argument are only to determine whether the character is zero-width,
and then it doesn't matter whether the exact width is 1 or 2.
2021-01-06 20:15:14 +01:00
Benno Schulenberg
0693d6974a minibar: represent bytes as 0xNN and valid Unicode code points as U+NNNN
An invalid UTF-8 starter byte should not be represented in the same way
as a valid Unicode character.

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

Bug existed since two weeks ago, since the mini-bar code was merged.
2021-01-06 15:10:11 +01:00
Benno Schulenberg
5129e718d7 chars: speed up the handling of invalid UTF-8 starter bytes
The first byte of a multi-byte UTF-8 sequence must be in the range
0xC2...0xFF.  Any other byte cannot be a starter byte and can thus
immediately be treated as a single byte.
2021-01-06 12:41:49 +01:00
Benno Schulenberg
8c406bc875 tweaks: change an intermediate variable to a better one 2021-01-06 10:05:35 +01:00
Benno Schulenberg
c53da9aa5b tweaks: fold some conditions into bitwise masks, for efficiency 2021-01-05 11:49:03 +01:00
Benno Schulenberg
e7a420eca7 prompt: suppress the ">" character always when exactly at the right edge
When the tail of the answer still fits exactly on the screen, the ">"
continuation character should not be shown -- also when the start of
the answer is "scrolled off" to the left.

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

Bug existed in this form since version 4.0, commit 56181896.
2021-01-04 15:39:29 +01:00
Benno Schulenberg
1236341746 tweaks: reshuffle a condition, to probably avoid an unneeded calculation
Also frob three comments.
2021-01-04 11:37:47 +01:00
Benno Schulenberg
c96c343fac tweaks: avoid computing the cursor column twice, and the "page" too 2021-01-04 11:31:07 +01:00
Benno Schulenberg
02f1fec497 prompt: restore a workaround for a cursor misplacement bug in ncurses
When making small movements in the lower right corner, ncurses can
get confused about where the cursor actually is -- a double-width
character seems to throw its calculations off.

This addresses https://savannah.gnu.org/bugs/?59808.

Bug existed since version 5.4, commit 39705c60.
2021-01-03 13:52:31 +01:00
Benno Schulenberg
a102e45e90 tweaks: elide a variable, by using a reallocation instead
Also unwrap a line.
2021-01-03 11:35:11 +01:00
Benno Schulenberg
86c9b9b54e files: when truncating a file name, give an indication of this
Show leading dots for the truncated part, or (if there is no room
at all) show just an underscore instead of the file name.

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

Bug existed since version 2.9.3, commit 97cbbb0c.
2021-01-03 11:32:14 +01:00
Benno Schulenberg
e14127b843 rcfile: rename 'nowrap' toggle to 'breaklonglines', to match the option
Now all toggle functions have the same name as their corresponding
long command-line option.  Also, all names now indicate the effect
of the toggle when it is invoked from a default setting.
2021-01-02 17:14:07 +01:00
Benno Schulenberg
67cdd71352 tweaks: push back the deprecation of the 'set nowrap' option
It is probably the most used option in a .nanorc file.
Keep accepting it for three more years.
2021-01-02 16:55:17 +01:00
Benno Schulenberg
6a88fe8807 tweaks: fold two similar and three identical cases together 2021-01-01 20:27:30 +01:00
Benno Schulenberg
90f6f25e31 oops: use the correct condition for checking the last line will change
Only when the replacement string (in 'answer') is non-empty will the
last line be changed and thus possibly a magic lined added.
2021-01-01 20:09:42 +01:00
Benno Schulenberg
0f4bb64eaf undo: remove the added magic line when a replacement caused one
This fixes https://savannah.gnu.org/bugs/?59796.

Bug existed since before version 2.2.4.
2021-01-01 19:48:03 +01:00
Benno Schulenberg
45efe28f05 minibar: drop the side spaces before suppressing the state flags
Also, consistently keep the right-side elements at least two spaces
away from the modification asterisk.
2020-12-30 19:03:27 +01:00
Benno Schulenberg
c8c7986f65 minibar: allow the number-of-lines to overrule also the state flags 2020-12-30 16:14:38 +01:00
Benno Schulenberg
f437117bf2 tweaks: avoid hitting negative values when using size_t 2020-12-30 16:07:29 +01:00
Benno Schulenberg
33e882e6f8 minibar: allow the number-of-lines to overrule location + character code
When space is too tight to show all three elements, show the report on
the number of lines in preference to the current location and character
code.  The latter two will be shown again upon the next keystroke, so
there is little harm in hiding them for a moment.
2020-12-29 20:10:18 +01:00
Benno Schulenberg
bad591d43d tweaks: adjust the indentation after the previous change
Also, reduce the scope of a variable, and rehuffle two lines.
2020-12-29 15:55:14 +01:00
Benno Schulenberg
7b48458380 minibar: suppress some elements when there is no room to show them
This fixes https://savannah.gnu.org/bugs/?59767.

Bug existed since last week, since the mini-bar code was merged.
2020-12-29 15:54:28 +01:00
Benno Schulenberg
1e16a3f411 syntax: nanorc: colorize 'bookstyle' as a valid option
This fixes https://savannah.gnu.org/bugs/?59769.
Reported-by: Tiago Almeida <tjamadeira@gmail.com>

Bug existed since version 5.0, since --bookstyle was introduced.
2020-12-29 09:36:42 +01:00
Benno Schulenberg
6a3ba2ab50 syntax: sh: recognize shebangs with any shell after 'env', not just 'sh'
(Inspired by a complaint seen somewhere on Stackoverflow.)
2020-12-25 17:05:02 +01:00
Benno Schulenberg
1878168ae3 tweaks: condense the description of how to report a bug
The list of bugs is quite short these days, and most of them are
feature requests, so asking the user to check whether a particular
problem has already been reported doesn't make much sense.
2020-12-25 16:45:31 +01:00
Benno Schulenberg
545709a165 weeding: remove some obsolete information from the README
The distinction between a stable series (even minor number) and
a development series (uneven) was abandonned five years ago.
This information is no longer helpful.
2020-12-25 16:34:08 +01:00
Benno Schulenberg
ca398fdfdf docs: explain the purpose of --markmatch / -^ / 'set markmatch'
Also, colorize 'set markmatch' as a valid option in a nanorc file.
2020-12-24 11:49:49 +01:00
Benno Schulenberg
d0bceb1449 options: add --markmatch and -^ for activating the select-match behavior
And add, of course, the 'set markmatch' nanorc option.
2020-12-24 11:49:22 +01:00
Benno Schulenberg
caef3128eb search: suppress the cursor when highlighting a match
Having a block cursor present when highlighting a match...
does not look nice.  So... hide the cursor until the next
keystroke, unless --showcursor or 'set showcursor' is used.
2020-12-24 11:49:22 +01:00
Benno Schulenberg
856a6ecde3 search: set the mark at the end of a found match so it gets highlighted
Not only does the match get highlighted (for better visibility), but
this also allows deleting the match with a single keystroke (^K, or
<Del> or <Bsp> when --zap is used) and then type something else.

This https://savannah.gnu.org/bugs/?59655.
Requested-by: Noam Sondak <noamso@gmail.com>
2020-12-24 11:49:22 +01:00
Benno Schulenberg
e353203010 docs: explain the effect of --minibar / -_ / 'set minibar'
Also, colorize 'set minibar' as valid option in a nanorc file.
2020-12-23 17:15:06 +01:00
Benno Schulenberg
f1fc66060f minibar: add a percentage that shows how far the cursor is into the file
Requested-by: Peter Passchier <peter@passchier.net>
2020-12-23 12:17:06 +01:00
Benno Schulenberg
ba4f4bdc64 minibar: show the line count in the bar (at startup and when saving)
Show the line count too when switching between buffers.
2020-12-23 12:17:06 +01:00
Benno Schulenberg
2b6c08b955 minibar: add an [x/y] "counter" when multiple files are open 2020-12-23 12:17:06 +01:00
Benno Schulenberg
b86f7868d1 feedback: differentiate between remarks, mistakes, and information
Remarks are about unsurprising things but it's good to give feedback
on them; "mistakes" are unexpected things, and get colored like an
error; and information is something that the user requested and thus
needs to stay on the status bar until the next keystroke.
2020-12-23 12:17:06 +01:00
Benno Schulenberg
54995defd2 input: intercept ^Z also when --minibar is active
For some reason, calling halfdelay() undoes the ISIG mask.
So, mask keyboard interrupts again immediately after the call.

Reported-by: Peter Passchier <peter@passchier.net>
2020-12-23 12:17:06 +01:00
Benno Schulenberg
b89bc2cce6 minibar: show the info bar again some 0.8 seconds after a message
Instead of redisplaying the minibar only upon the next keystroke
(when some feedback message is shown on the status bar), time the
waiting for the keystroke out after four fifths of a second, then
redisplay the minibar and continue the wait.
2020-12-23 12:17:06 +01:00
Benno Schulenberg
8f24ffaaef options: add --minibar and -_ for activating basic state-information bar 2020-12-23 12:17:05 +01:00
Benno Schulenberg
d31cc373de display: add code for showing minimal state-information bar at the bottom
When activated, it suppresses the title bar, and suppresses feedback
on the status bar for toggles whose effect is obvious or whose state
is already shown in the minibar.

This addresses https://savannah.gnu.org/bugs/?58152,
and addresses https://savannah.gnu.org/bugs/?58789.
2020-12-23 12:17:05 +01:00
Benno Schulenberg
f52f503c38 tweaks: move the displaying of the state letters into a separate function 2020-12-23 12:17:05 +01:00
Benno Schulenberg
8939163659 tweaks: reshuffle two lines, and rename a variable to a plain word 2020-12-22 19:23:40 +01:00
Benno Schulenberg
265bdd94f1 mouse: do not offset the shortcuts by 'margin' when using --linenumbers
The bottom window (the prompt bar and the shortcuts) does not shift
its position when line numbers are active, so mouse clicks in this
window should be not be compensated for the line-numbers margin.

This fixes https://savannah.gnu.org/bugs/?59749.
Indirectly-reported-by: ObeliX <ObeliX-@gmx.de>

Bug existed since version 2.7.0, since line numbers were introduced.
2020-12-22 19:15:32 +01:00
OIX
d1c412d200 mouse: update title bar (the M flag) when the click is on the cursor
Clicking on the cursor toggles the mark, meaning that the flags in
the title bar should be updated when --stateflags is active.

This fixes https://savannah.gnu.org/bugs/?59747.
Indirectly-reported-by: ObeliX <ObeliX-@gmx.de>

Signed-off-by: OIX <ObeliX-@gmx.de>
2020-12-22 14:21:28 +01:00
Benno Schulenberg
5c4c30e26b display: do not show the state flags in the help viewer or file browser
The state flags are relevant only when editing.

This fixes https://savannah.gnu.org/bugs/?59744.
Indirectly-reported-by: ObeliX <ObeliX-@gmx.de>

Bug existed since version 5.3, since --stateflags was introduced.
2020-12-21 14:59:18 +01:00
Benno Schulenberg
1b65d39722 docs: insert links to the mailing-list archives into the README
To make those archives easier to find.
2020-12-21 12:29:41 +01:00
Benno Schulenberg
96e4fec31c tweaks: use a boolean instead of an enumeration of two values 2020-12-19 16:40:21 +01:00
Benno Schulenberg
208146f2f2 syntax: go: add author and license line
In the original submission (https://savannah.gnu.org/patch/?8189)
the submitter said: "I hereby put it into the public domain."

Public-domain license: https://directory.fsf.org/wiki/License:CC0

Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2020-12-10 15:48:28 +01:00
Benno Schulenberg
89e84e76c3 build: fix compilation when configured with --enable-tiny
The BACK and DEL symbols are used as parameters for do_deletion().
2020-12-09 16:27:34 +01:00
Benno Schulenberg
c44a5e960e syntax: nanorc: colorize 'set promptcolor' as valid 2020-12-07 11:19:48 +01:00
Benno Schulenberg
c1bd54dd47 tweaks: move 'set indicator' to its alphabetical place in the manual
Also, reword some option descriptions, to mention the effect of the
option instead of what the user should give as argument.
2020-12-06 16:34:42 +01:00
Benno Schulenberg
3efb9c3a2e docs: mention the new 'set promptcolor' option 2020-12-06 16:34:42 +01:00
Benno Schulenberg
b87d7f69fc options: accept 'set promptcolor' for setting the color of the prompt bar
When it is not specified, it defaults to the value for 'titlecolor'.
2020-12-06 16:34:42 +01:00
Benno Schulenberg
8ba653f395 docs: mention in NEWS that some workarounds were removed
It would have been good to mention this for the 5.4 release,
but when all is well, no one should be affected by it.
2020-12-06 16:34:18 +01:00
Benno Schulenberg
c6501beba7 tweaks: reshuffle some more lines, to have most #defines together 2020-12-06 12:30:52 +01:00
Benno Schulenberg
dbf522b750 tweaks: reshuffle some lines, to have most #includes near the beginning 2020-12-06 11:49:37 +01:00
Benno Schulenberg
651e97ceef tweaks: reshuffle some lines, to group things better 2020-12-06 11:40:25 +01:00
Benno Schulenberg
d8500f0467 tweaks: remove some #ifdefs that were there only for Slang 2020-12-05 12:34:17 +01:00
Benno Schulenberg
a9bc118178 docs: remove all mentions of Slang 2020-12-05 12:23:06 +01:00
Benno Schulenberg
903942b4f0 build: remove the '--with-slang' configure option 2020-12-05 12:17:48 +01:00
Benno Schulenberg
7ebf5f52b8 tweaks: clean up after the previous change 2020-12-05 12:12:11 +01:00
Benno Schulenberg
4f7593b704 general: remove support for Slang
Slang has too many bugs to be useful.

This addresses https://savannah.gnu.org/bugs/?59210.
2020-12-05 11:57:08 +01:00
Benno Schulenberg
2157738a18 tweaks: correct two comments after the previous changes 2020-12-04 17:03:10 +01:00
Benno Schulenberg
681d11c0cf tweaks: rename a variable, to be similar to its sister 2020-12-04 16:57:17 +01:00
Benno Schulenberg
d96f296b8e input: interpret a keystroke as Meta only when an earlier escape was solo
This allows using <Esc> <Esc> <letter> in a macro as an alternative
for <Ctrl+letter>, but it does require that one does not type <Esc>
by accident when recording a macro as it might modify the subsequent
keystroke when the macro is replayed.

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

Bug existed since version 3.0, commit ecc9211a.
2020-12-04 16:35:28 +01:00
Benno Schulenberg
048ab0ee0b tweaks: reduce the scope of a static variable 2020-12-04 16:30:28 +01:00
Benno Schulenberg
16dff06a4c tweaks: simplify a bit of logic 2020-12-04 16:27:34 +01:00
Benno Schulenberg
c3900e90f0 po: update translations and regenerate POT file and PO files 2020-12-02 11:49:28 +01:00
Benno Schulenberg
0f334f8ee4 bump the version number in configure.ac too 2020-12-02 11:39:51 +01:00
Benno Schulenberg
587e6e2c88 bump version numbers and add a news item for the 5.4 release 2020-12-02 11:15:31 +01:00
Benno Schulenberg
a3a1391a51 tweaks: rename two variables, one for contrast, another for visibility
Also normalize two bits of whitespace.
2020-11-30 13:32:22 +01:00
Benno Schulenberg
a4675acdba copyright: update to the current year for significantly changed files 2020-11-30 12:01:47 +01:00
Benno Schulenberg
00ac41f632 weeding: remove another unneeded workaround for VTE
The issue is only reproducible when lying about the width
of the terminal.

It was a workaround for https://savannah.gnu.org/bugs/?49106.
2020-11-28 16:12:20 +01:00
Benno Schulenberg
fe22da6b2a build: exclude a workaround for VTE/Konsole when using a recent ncurses
The workaround was for https://savannah.gnu.org/bugs/?51335
(a cursor-misplacement bug), but both an recent Xfce Terminal
and a recent Konsole appear unaffected by the issue.  So, drop
the workaround for modern systems.
2020-11-27 14:15:42 +01:00
Benno Schulenberg
0c87a4ba41 build: include a workaround for VTE only when using an older libvte
Checking for the actual version of libvte is too complicated, so
assume that libvte is 0.58 or newer (where the problem is fixed)
when ncurses is 6.2 or newer.
2020-11-27 12:31:41 +01:00
Benno Schulenberg
39705c60df weeding: remove a workaround for VTE that is not needed
It was only ever needed when the user lied about the size
of the terminal, which should be considered a user error.

It was a workaround for https://savannah.gnu.org/bugs/?48852.
2020-11-26 20:09:23 +01:00
Benno Schulenberg
9da23799ff tweaks: reshuffle a fragment of code, for clarity 2020-11-26 17:32:30 +01:00
Benno Schulenberg
29276d1d3a help: allow the penultimate item extra space when the number is uneven
This avoids unnecessarily truncating the last help item on the
very bottom row when there is still plenty of room.

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

Bug has been visible since at least version 2.5.1.
2020-11-26 17:12:09 +01:00
Benno Schulenberg
13b839734f hellp: show all valid help items also in the Write-Out menu
Subtract one from the count only if all possible items in the menu
have been counted (item == NULL), meaning that the last item in the
Write-Out menu (the 'discard_buffer' function) has been counted too.

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

Bug existed since version 4.5, commit b3ace4d8.
2020-11-26 15:37:21 +01:00
Benno Schulenberg
63bb1b62b7 gnulib: update to its current upstream state 2020-11-25 11:22:46 +01:00
Benno Schulenberg
743100feab options: do not spew out the help text when an option is not recognized
When getopt() does not recognize an option, it returns '?', which means
that '-?' cannot be used as a valid option because any invalid option
would be treated the same way as '-?'.

Spewing out the full help text drowns the "invalid option" message at
the beginning.

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

Bug existed since version 5.3, commit 5bd92d4c.
2020-11-24 10:09:41 +01:00
Benno Schulenberg
d3d2d324d2 statusbar: properly pluralize the line+word+character count report
This avoids poor wordings such as "Words: 1  Lines: 1  Chars: 1".

Also, display the numbers in a more logical, ascending order: lines
first, words second, characters third.  This is what 'wc' uses, too.
2020-11-21 15:25:23 +01:00
Benno Schulenberg
925a1a11f9 feedback: abort when user tries to open multiple files in tiny version
This fixes https://savannah.gnu.org/bugs/?56227.
2020-11-17 19:08:12 +01:00
Benno Schulenberg
5918ca6cab tweaks: normalize the formatting after the previous two changes 2020-11-17 10:28:28 +01:00
Benno Schulenberg
dc907bfe43 prompt: skip over combining characters also when editing a search string 2020-11-17 10:27:47 +01:00
Benno Schulenberg
687efd210c moving: skip combining characters and other zero-width characters
This makes the cursor move smoothly left and right -- instead of
"stuttering" when passing over a zero-width character.

Pressing <Delete> on a normal (spacing) character also deletes
any zero-width characters after it.  But pressing <Backspace>
while the cursor is placed after a zero-width character, just
deletes that zero-width character.  The latter behavior allows
deleting and retyping just the combining diacritic of a character
instead of the whole character.

This addresses https://savannah.gnu.org/bugs/?50773.
Requested-by: Mike Frysinger <vapier@gentoo.org>
2020-11-17 10:21:50 +01:00
Benno Schulenberg
b7539ea985 weeding: remove a workaround for versions of ncurses before 5.9
(Yes, the test is for 6.0, but the bug was actually fixed in 5.9,
as far as I remember -- I just wasn't sure and didn't want to bother
building different versions of ncurses myself.)
2020-11-15 10:27:22 +01:00
Benno Schulenberg
7d35f71c87 weeding: remove a workaround for early versions of ncurses-6.0
Those versions are more than five years old.  If there are still
machines with those versions, people should upgrade ncurses too
if they want the newest version of nano.
2020-11-15 10:27:22 +01:00
Benno Schulenberg
7f184ee2ba linting: avoid putting the cursor beyond the end of the line
Some linters report a column position (assuming a TAB to be 8 spaces)
instead of a byte index, so make sure that the cursor is not placed
out of bounds when interpreting such a column number as an index.

This fixes https://savannah.gnu.org/bugs/?59419.
Reported-by: Ava McWhorter <qwerty0s.e.m@gmail.com>

Bug existed since version 2.8.1, commit 2439e1e4.
2020-11-06 10:36:08 +01:00
Benno Schulenberg
ec9fc5d320 utils: die when trying to allocate zero bytes
This shouldn't occur, so go down when it does.
2020-10-29 16:18:03 +01:00
Benno Schulenberg
3c2eb96243 tweaks: rename two variables and improve two comments 2020-10-21 12:24:52 +02:00
Benno Schulenberg
de313586ab tweaks: reshuffle three lines and elide braces after the previous change 2020-10-21 11:39:56 +02:00
Benno Schulenberg
e96bda4b9f tweaks: avoid copying an option's argument when there is no need
This takes eight extra calls of copy_of(), but saves ten calls of
free().  But more importantly: it avoids an unneeded copying and
then freeing again of the argument after 'titlecolor' and friends.
2020-10-21 11:37:21 +02:00
Benno Schulenberg
d9944c03c4 docs: adjust for the changed name of the header-file package on Debian
Also, be more complete, reword a few things, and stop mentioning Slang.
2020-10-11 16:44:40 +02:00
Benno Schulenberg
b9d6d547b8 bindings: accept b for scrolling back up in help viewer and file browser
Like in Dillo, and because it could be mnemonic for "Back" and
is directly above the space bar (in a QWERTY layout, at least).
2020-10-11 16:11:21 +02:00
Benno Schulenberg
622b031e27 docs: use standard-compliant HTML entities for the four arrows
HTML 4 knows only the four-letter abbreviations for the arrows.
Use those, so that also browsers with very limited knowledge
(like Dillo) will show the arrows correctly.
2020-10-11 15:58:40 +02:00
Benno Schulenberg
26f5c8b9d5 rcfile: stop accepting 'set view' in a nanorc file, and undocument it
Like --restricted, --view really only makes sense on the command line.
2020-10-10 12:42:20 +02:00
Benno Schulenberg
e1601d2eb5 tweaks: use the standard symbols for the three standard file descriptors
Also, take into account (as elsewhere) that dup2() could fail,
and harmonize their error checks.
2020-10-10 12:32:02 +02:00
Benno Schulenberg
bc14fc35d7 tweaks: reshuffle a line, elide two braces, and adjust the indentation
And improve a comment.
2020-10-08 15:07:03 +02:00
Benno Schulenberg
f660f22623 tweaks: slightly shorten a loop, to place the actual action outside of it
And in the bargain elide a variable, and make it clearer
what the return value is at two early exit points.

[This change makes use of the fact that TRUE (successful write) == 1
and FALSE (failed write) == 0.  But this is already used twenty lines
earlier, for the other call of write_file().]
2020-10-08 15:07:03 +02:00
98 changed files with 31839 additions and 23849 deletions

334
ChangeLog
View File

@@ -1,3 +1,337 @@
Changes between v5.7 and v5.8:
------------------------------
Benno Schulenberg (53):
bindings: show either "^/" or "^-" in the help lines, instead of "^_"
bump version numbers and add a news item for the 5.8 release
display: when a message gets overwritten, note that it is cleared
docs: add a relevant item to the news for the 4.3 release
docs: add example bindings for uppercasing and lowercasing a word
docs: improve the contact info and some line spacing in the PDF
docs: make ^E access the Execute menu in the example CUA bindings
docs: mention that "grey"/"gray" may be used as a synonym of "lightblack"
docs: mention the new 'set minicolor' option
docs: say thanks to the Icelandic and Slovak translators
feedback: ensure that the reporting of DOS/Mac format is truthful
gnulib: update to its current upstream state
help: use smaller triangles for the arrows
linter: block the resizing signal while reading output from the linter
linter: strip filename and line plus column number from the message
memory: move the correct number of bytes, and not one too many
memory: prevent a leak when copying the leading quoting to the next line
minibar: stay out of sight when the terminal has just one row
options: accept 'set minicolor' for setting the color of the minibar
rcfile: allow using "grey" or "gray" as a synonym for "lightblack"
rcfile: do not allow color name "normal" to have a prefix
replacing: report the number of replacements also on a one-row terminal
search: automatically drop the spotlighting after a few moments
search: show "This is the only occurrence" also on a one-row terminal
startup: allow using a bare "+" to mean put-cursor-on-last-line
startup: do not accept stray characters after a "+" on the command line
startup: skip drawing edit window when having message on one-row terminal
startup: suppress "Search Wrapped" when using +? to search from EOF
statusbar: ensure that "No further matches" does not get overwritten
statusbar: on a one-row terminal, drop light messages after a few moments
statusbar: suppress --constantshow when the terminal has just one row
statusbar: suppress the cursor when the terminal has just one row
syntax: nanohelp: avoid colorizing M-) in (M-) and M-" in "M-"
syntax: nanorc: colorize "light" as valid only for the eight basic colors
syntax: nanorc: colorize literal control codes, to make them stand out
syntax: php: colorize the full short tag for echo (<?=)
tweaks: avoid the subtraction of two size_t variables becoming negative
tweaks: condense and correct a comment, and move another
tweaks: condense some code by putting all color names in a single array
tweaks: drop an assignment that is already part of the called function
tweaks: frob some whitespace, and rewrap a line
tweaks: improve a comment, remove unneeded braces, reshuffle some lines
tweaks: normalize the indentation after the previous change
tweaks: prevent two more size_t subtractions from going negative
tweaks: redraw only the affected line instead of doing a full refresh
tweaks: remove a check that has become superfluous
tweaks: remove a check that is not needed
tweaks: rename a variable, for contrast with the function name
tweaks: rename two functions, to get rid of an ugly _void suffix
tweaks: reshuffle the coloring of color names, to remove some duplication
tweaks: use a symbol instead of a hard-coded number
tweaks: use two symbolic names instead of TRUE and FALSE, for clarity
wrapping: when copying the quoting part, adjust the file size accordingly
Hussam al-Homsi (1):
bindings: allow copying text (with M-6) also when in view mode
Changes between v5.6.1 and v5.7:
--------------------------------
Benno Schulenberg (62):
build: drop the check for two functions that we don't use any more
build: fix compilation for --enable-tiny plus --enable-multibuffer
build: fix compilation when configured with --disable-multibuffer
build: fix compilation when configured with --enable-tiny
bump version numbers and add a news item for the 5.7 release
chars: implement mblen() ourselves, for efficiency
chars: implement mbtowc() ourselves, for more efficiency
chars: work around a UTF-8 bug in glibc, to display invalid codes right
chars: work around the wrong private-use-character widths on OpenBSD
display: avoid determining twice from and until where to draw each row
display: make the output of --constantshow less jittery
editing: prevent the pointer for the top row from becoming dangling
feedback: upon first switch to a buffer, show its error message (if any)
files: always register the format, also when the file is unwritable
files: create a new buffer earlier, so that error messages can be stored
files: when Mac format has been detected, stay with it
gnulib: pull in the fix for a build problem on older Debian
gnulib: update to its current upstream state
indicator: adjust the size to the number of visible lines, not chunks
input: accept Unicode codes for non-characters as valid, since they are
memory: do not allocate space for multidata when it's already allocated
memory: fix an off-by-one error to free also the last line in a group
memory: prevent a use-after-free when the user respects a lock file
oops: that doesn't work -- you can't break out of two for loops at once
options: retire the obsolete 'smooth', 'morespace', and 'nopauses'
softwrap: avoid time-consuming computations, to burden large files less
startup: do not crash when trying to open a device or directory
startup: do not store an error message in the record of another buffer
startup: save the compiled file-matching regexes, to avoid recompiling
startup: show the helpful message only when ^G has not been rebound
syntax: c: colorize also labels that contain digits, and uncolorize colon
syntax: po: improve the coloring of format specifiers
syntaxes: replace [[:space:]] with [[:blank:]] to exclude carriage return
tweaks: adjust and improve one comment, and frob another
tweaks: adjust two comments, and reshuffle two fragments
tweaks: avoid a warning on newer compilers, by writing an extra byte
tweaks: avoid calling extra_chunks_in() when not softwrapping
tweaks: avoid converting a file name for more than will fit on screen
tweaks: avoid parsing a multibyte character twice
tweaks: condense three comments, drop another, and rewrap a line
tweaks: drop unneeded braces and adjust indentation after previous change
tweaks: elide a call of strlen() for every row
tweaks: elide a function that is now basically just two lines
tweaks: elide an unneeded resetting NULL call to wctomb()
tweaks: elide a small function that is used just once
tweaks: elide the pointless is_valid_unicode() function
tweaks: elide two more instances of useless character copying
tweaks: improve a couple of comments
tweaks: morph a function into what it is actually used for
tweaks: normalize the indentation after an earlier change
tweaks: put the most likely condition first, for a quicker return
tweaks: reduce the maximum character length from six bytes to four
tweaks: remove a misplaced (and nested) #ifdef
tweaks: rename a variable, away from an abbreviation
tweaks: rename a variable, for contrast with another
tweaks: reshuffle a comment, and put the main extension first
tweaks: reshuffle a fragment of code, to prepare for the next change
tweaks: reshuffle two conditions, to have the most unlikely one first
tweaks: set the file format only when unset, so it doesn't need saving
tweaks: shorten a comment and trim an #ifdef
tweaks: simplify two fragments of code
tweaks: simplify two fragments of code, eliding useless character copying
Hussam al-Homsi (1):
syntax: c: make the highlighting of '#include <...>' more compliant
Mike Frysinger (1):
syntax: tcl: support Expect scripts too
Changes between v5.6 and v5.6.1:
--------------------------------
Benno Schulenberg (4):
bump version numbers and add a news item for the 5.6.1 release
options: rename 'highlightcolor' to the more distinct 'spotlightcolor'
search: correctly colorize a match also when softwrapping is active
tweaks: rename a symbol, to better match the corresponding option
Changes between v5.5 and v5.6:
------------------------------
Benno Schulenberg (52):
build: avoid a warning about duplicate symbol when building from tarball
build: detect a build from git also when building out of tree
build: include a workaround only for versions of ncurses that need it
bump version numbers and add a news item for the 5.6 release
color: do not look for another 'end' match after already finding one
color: give highlighted text its own color, to not look like marked text
color: recompile the file-probing regexes a little faster with REG_NOSUB
color: use bright yellow to highlight a search match
color: use inverse video for highlighting when there are no colors
debug: add timing instruments to cache precalculation and screen refresh
display: for a large paste or insertion, recalculate the multiline cache
docs: correct the description of --quickblank for the changed base value
docs: correct the formatting of a comment in the sample nanorc
docs: correct the word order for Alt+D in the cheat sheet -- it changed
docs: mention the new 'set highlightcolor' option
docs: remove all mentions of --markmatch and 'set markmatch'
docs: say that --minibar is modified by --constantshow and --stateflags
feedback: make Full Justify show a message also when using --minibar
gnulib: update to its current upstream state
minibar: show a message a little longer when --quickblank isn't used
minibar: show cursor position + character code only with --constantshow
minibar: show the state flags only when --stateflags is used
minibar: suppress the toggling feedback for M-C, but show it for M-Y/M-P
options: remove --markmatch and 'set markmatch', as the behavior is gone
painting: always do backtracking for the first row of the screen
painting: trigger a refresh when a second start match appears on a line
painting: trigger fewer unneeded full-screen refreshes
painting: when finding an end match, set its multidata right away
scrolling: keep centering after large paste, also when line numbers widen
search: just highlight the found occurrence, instead of marking it
search: make highlighting the standard, non-changeable behavior
tweaks: avoid the vague possibility of advancing beyond end-of-line
tweaks: be slightly more efficient in marking lines as WOULDBE
tweaks: call wattron()/wattroff() only when actually painting something
tweaks: correct a comment, improve another, and trim some verbosity
tweaks: don't bother comparing virgin multidata with current situation
tweaks: don't bother initializing freshly allocated multidata
tweaks: don't bother wiping the multidata before recomputing it
tweaks: elide a function that is now just one line
tweaks: frob a condition, to be more concise, and reshuffle another
tweaks: frob some comments, and adjust indentation after previous change
tweaks: frob some comments, and reshuffle two fragments of code
tweaks: frob two fragments of code, to be more readable
tweaks: make a skipping condition more precise
tweaks: remove an old fix that was made superfluous by a recent fix
tweaks: remove a strangely placed warning
tweaks: rename six symbols, to be more straightforward
tweaks: reshuffle some code, and reduce the scope of a variable
tweaks: reshuffle three conditions into a better order
tweaks: rewrap and reindent a few lines
tweaks: rewrap two lines, for esthetics
tweaks: stop evaluating a rule when the match is offscreen to the right
Changes between v5.4 and v5.5:
------------------------------
Benno Schulenberg (84):
build: fix compilation for --enable-{tiny,help,multibuffer}
build: fix compilation when configured with --disable-utf8
build: fix compilation when configured with --enable-tiny
build: remove the '--with-slang' configure option
bump version numbers and add a news item for the 5.5 release
chars: short-circuit determining the width of characters under U+0300
chars: speed up the handling of invalid UTF-8 starter bytes
copyright: update the years for the FSF
display: add code for showing minimal state-information bar at the bottom
display: do not show the state flags in the help viewer or file browser
docs: explain the effect of --minibar / -_ / 'set minibar'
docs: explain the purpose of --markmatch / -^ / 'set markmatch'
docs: insert links to the mailing-list archives into the README
docs: mention in NEWS that some workarounds were removed
docs: mention the new 'set promptcolor' option
docs: remove all mentions of Slang
feedback: differentiate between remarks, mistakes, and information
feedback: wipe the status bar by default after 20 keystrokes
files: when truncating a file name, give an indication of this
general: remove support for Slang
gnulib: update to its current upstream state
input: intercept ^Z also when --minibar is active
input: interpret a keystroke as Meta only when an earlier escape was solo
memory: avoid leaking the speller or linter command string, when invoked
minibar: add an [x/y] "counter" when multiple files are open
minibar: add a percentage that shows how far the cursor is into the file
minibar: allow the number-of-lines to overrule also the state flags
minibar: allow the number-of-lines to overrule location + character code
minibar: drop the side spaces before suppressing the state flags
minibar: represent bytes as 0xNN and valid Unicode code points as U+NNNN
minibar: show the info bar again some 0.8 seconds after a message
minibar: show the line count in the bar (at startup and when saving)
minibar: show Unicode codes when in a UTF-8 locale
minibar: suppress some elements when there is no room to show them
minibar: when the next character has zero width, show its code too
minibar: when the overnext character has zero width too, show its code
mouse: do not offset the shortcuts by 'margin' when using --linenumbers
oops: use the correct condition for checking the last line will change
options: accept 'set promptcolor' for setting the color of the prompt bar
options: add --markmatch and -^ for activating the select-match behavior
options: add --minibar and -_ for activating basic state-information bar
prompt: restore a workaround for a cursor misplacement bug in ncurses
prompt: suppress the ">" character always when exactly at the right edge
rcfile: rename 'nowrap' toggle to 'breaklonglines', to match the option
search: set the mark at the end of a found match so it gets highlighted
search: suppress the cursor when highlighting a match
speller: do an internal spell check when --speller is an empty string
speller: strip leading whitespace from command, to avoid a sneaky crash
syntax: go: add author and license line
syntax: nanorc: colorize 'bookstyle' as a valid option
syntax: nanorc: colorize 'set promptcolor' as valid
syntax: sh: recognize shebangs with any shell after 'env', not just 'sh'
tweaks: adjust the indentation after the previous change
tweaks: avoid compilation warnings on 32-bit machine plus newer compiler
tweaks: avoid computing the cursor column twice, and the "page" too
tweaks: avoid hitting negative values when using size_t
tweaks: change an intermediate variable to a better one
tweaks: clean up after the previous change
tweaks: condense the description of how to report a bug
tweaks: correct a translator hint
tweaks: correct two comments after the previous changes
tweaks: do not change the pointer, but move the content of the string
tweaks: drop a small optimization for invalid UTF-8 starter bytes
tweaks: elide a variable, by using a reallocation instead
tweaks: fold some conditions into bitwise masks, for efficiency
tweaks: fold two similar and three identical cases together
tweaks: move 'set indicator' to its alphabetical place in the manual
tweaks: move the displaying of the state letters into a separate function
tweaks: push back the deprecation of the 'set nowrap' option
tweaks: put the new options in a consistent order in the code
tweaks: reduce the scope of a static variable
tweaks: remove some #ifdefs that were there only for Slang
tweaks: rename a variable, to be similar to its sister
tweaks: reshuffle a condition, to probably avoid an unneeded calculation
tweaks: reshuffle an option, to have two related ones grouped together
tweaks: reshuffle some lines, to group things better
tweaks: reshuffle some lines, to have most #includes near the beginning
tweaks: reshuffle some more lines, to have most #defines together
tweaks: reshuffle two lines, and rename a variable to a plain word
tweaks: reword the description of an option
tweaks: simplify a bit of logic
tweaks: use a boolean instead of an enumeration of two values
undo: remove the added magic line when a replacement caused one
weeding: remove some obsolete information from the README
OIX (1):
mouse: update title bar (the M flag) when the click is on the cursor
Changes between v5.3 and v5.4:
------------------------------
Benno Schulenberg (31):
bindings: accept b for scrolling back up in help viewer and file browser
build: exclude a workaround for VTE/Konsole when using a recent ncurses
build: include a workaround for VTE only when using an older libvte
bump version numbers and add a news item for the 5.4 release
copyright: update to the current year for significantly changed files
docs: adjust for the changed name of the header-file package on Debian
docs: use standard-compliant HTML entities for the four arrows
feedback: abort when user tries to open multiple files in tiny version
gnulib: update to its current upstream state
help: allow the penultimate item extra space when the number is uneven
help: show all valid help items also in the Write-Out menu
linting: avoid putting the cursor beyond the end of the line
moving: skip combining characters and other zero-width characters
options: do not spew out the help text when an option is not recognized
prompt: skip over combining characters also when editing a search string
rcfile: stop accepting 'set view' in a nanorc file, and undocument it
statusbar: properly pluralize the line+word+character count report
tweaks: avoid copying an option's argument when there is no need
tweaks: normalize the formatting after the previous two changes
tweaks: rename two variables and improve two comments
tweaks: rename two variables, one for contrast, another for visibility
tweaks: reshuffle a fragment of code, for clarity
tweaks: reshuffle a line, elide two braces, and adjust the indentation
tweaks: reshuffle three lines and elide braces after the previous change
tweaks: slightly shorten a loop, to place the actual action outside of it
tweaks: use the standard symbols for the three standard file descriptors
utils: die when trying to allocate zero bytes
weeding: remove another unneeded workaround for VTE
weeding: remove a workaround for early versions of ncurses-6.0
weeding: remove a workaround for versions of ncurses before 5.9
weeding: remove a workaround for VTE that is not needed
Changes between v5.2 and v5.3:
------------------------------

View File

@@ -2,6 +2,10 @@ Improvements in GNU nano
========================
Since 5.0:
- A search highlights the found text, in black on yellow by default.
- Option --minibar reduces the interface to a bottom bar with basic info.
- The cursor skips over combining characters, <Del> deletes them together
with the character they combine with, but <Bsp> deletes them separately.
- For using libmagic the option --magic or -! or 'set magic' is required.
- With --stateflags the state of some things is shown in the title bar.
- M-Bsp deletes a word leftward.

60
NEWS
View File

@@ -1,3 +1,62 @@
2021.06.15 - GNU nano 5.8 "Why is it necessary to be special?"
• After a search, the spotlighting is dropped after 1.5 seconds (0.8
seconds with --quick) to avoid the idea that the text is selected.
• A + and a space before a filename on the command line will put the
cursor at the end of the corresponding buffer.
• Linter messages no longer include filename and line/column numbers.
• Color name "grey" or "gray" can be used instead of "lightblack".
• The color of the minibar can be chosen with 'set minicolor'.
2021.04.29 - GNU nano 5.7 "Toți ceilalți arau câmpurile"
• The output of --constantshow (without --minibar) is more stable.
• When opening multiple buffers and there is an error message, this
message is shown again upon first switch to the relevant buffer.
• The position and size of the indicator now follow actual lines,
instead of visual lines when in softwrap mode, meaning that the
size of the indicator can change when scrolling in softwrap mode.
2021.03.03 - GNU nano 5.6.1 "Geelgors"
• Search matches are properly colorized in softwrap mode too.
• Option 'highlightcolor' has been renamed to 'spotlightcolor'.
2021.02.24 - GNU nano 5.6 "Wielewaal"
• A search match gets highlighted (in black on yellow by default),
in addition to placing the cursor at the start of the match.
The color combination can be changed with 'set highlightcolor'.
By default the cursor is hidden until the next keystroke, but
it can be forced on with --showcursor / 'set showcursor'.
• Option --markmatch / 'set markmatch' has been removed.
• Cursor position and character code are displayed in the minibar
only when option --constantshow / 'set constantshow' is used,
and their display can be toggled with M-C.
• The state flags are displayed in the minibar only when option
--stateflags / 'set stateflags' is used.
2021.01.14 - GNU nano 5.5 "Rebecca"
• Option 'set minibar' makes nano suppress the title bar and instead
show a bar with basic editing information at the bottom: file name
(plus an asterisk when the buffer is modified), the cursor position
(line,column), the character under the cursor (U+xxxx), the flags
that --stateflags normally shows, plus the percentage of the buffer
that is above the cursor.
• With 'set promptcolor' the color combination of the prompt bar can
be changed, to allow contrasting it with the mini bar (which always
has the same color as the title bar).
• Option 'set markmatch' highlights the result of a successful search
by putting the mark at the end of the match, making the match more
visible. It also suppresses the cursor until the next keystroke.
(If you dislike the hiding of the cursor, use 'set showcursor'.)
• The bindable toggle 'nowrap' has been renamed to 'breaklonglines',
to match the corresponding option, like for all other toggles.
• Support for Slang has been removed.
2020.12.02 - GNU nano 5.4 "Terre des hommes"
• Moving the cursor now skips over combining characters (and other
zero-width characters). Deleting a character deletes also any
succeeding zero-width characters, but backspacing deletes just
one character at a time.
• Workarounds for older ncurses and older libvtes were removed.
2020.10.07 - GNU nano 5.3 "Revolution!"
• Option 'set stateflags' makes nano show the state of auto-indenting,
the mark, hard-wrapping, macro recording, and soft-wrapping in the
@@ -136,6 +195,7 @@
2019.06.18 - GNU nano 4.3 "Musa Kart"
• The ability to read from and write to a FIFO has been regained.
• Opening a file no longer triggers an inotify CLOSE_WRITE event.
• Startup time is reduced by fully parsing a syntax only when needed.
• Asking for help (^G) when using --operatingdir does not crash.
• The reading of a huge or slow file can be stopped with ^C.

32
README
View File

@@ -25,7 +25,7 @@ Overview
How to compile and install nano
Download the latest nano source tarball, then:
Download the latest nano source tarball, and then:
tar -xvf nano-x.y.tar.gz
cd nano-x.y
@@ -33,12 +33,13 @@ How to compile and install nano
make
make install
It's that simple. Use --prefix with configure to override the
default installation directory of /usr/local.
You will need the header files of ncurses installed for ./configure
to succeed -- get them from libncurses-dev (Debian) or ncurses-devel
(Fedora) or a similarly named package. Use --prefix with ./configure
to override the default installation directory of /usr/local.
If you haven't configured with the --disable-nanorc option, after
installation you may want to copy the doc/sample.nanorc file to
your home directory, rename it to ".nanorc", and then edit it
After installation you may want to copy the doc/sample.nanorc file
to your home directory, rename it to ".nanorc", and then edit it
according to your taste.
Web Page
@@ -51,26 +52,25 @@ Mailing Lists
+ info-nano@gnu.org is a very low traffic list used to announce
new nano versions or other important info about the project.
+ help-nano@gnu.org is for those seeking to get help without
wanting to hear about the technical details of its development.
+ nano-devel@gnu.org is the list used by the people that make nano
and a general development discussion list, with moderate traffic.
To subscribe, send email to <name>-request@gnu.org with a subject
of "subscribe", where <name> is the list you want to subscribe to.
The archives of the development and help mailing lists are here:
https://lists.gnu.org/archive/html/nano-devel/
https://lists.gnu.org/archive/html/help-nano/
Bug Reports
To report a bug, please file a description of the problem on nano's
bug tracker (https://savannah.gnu.org/bugs/?group=nano -- hover on
"Bugs", then click "Submit new"). The issue may have already been
reported, so please look first.
Current Status
Since version 2.5.0, GNU nano has abandoned the distinction between
a stable and a development branch: it is now on a "rolling" release
-- fixing bugs and adding new features go hand in hand.
If you find a bug, please file a detailed description of the problem
on nano's bug tracker: https://savannah.gnu.org/bugs/?group=nano.
Copyright Years

View File

@@ -22,11 +22,11 @@ packages:
- pkg-config (version >= 0.22)
- texinfo (version >= 4.0)
If you want UTF-8 support, you will also need libncursesw5-dev installed
(version >= 5.7), or libslang2-dev (version >= 2.0) if you use --with-slang.
You will also need to have the header files for ncurses installed,
from libncurses-dev on Debian, ncurses-devel on Fedora, or similar.
These should all be available in your distro's package manager or software
center, or otherwise on any GNU mirror.
These should all be available in your distro's package manager or
software center, or otherwise on any GNU mirror.
Download the source

2
THANKS
View File

@@ -18,6 +18,8 @@ Mihai Cristescu <mihai.cristescu@archlinux.info> Romanian
Yavor Doganov <yavor@doganov.org> Bulgarian
Karl Eichwalder <keichwa@gmx.net> German
A. Murat EREN <meren@comu.edu.tr> Turkish
Sveinn í Felli <sv1@fellsnet.is> Icelandic
Marek Felšöci <marek@felsoci.sk> Slovak
Doruk Fisek <dfisek@fisek.com.tr> Turkish
Rafael Fontenelle <rffontenelle@gmail.com> Brazilian Portuguese
Pavel Fric <pavelfric@seznam.cz> Czech

View File

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

View File

@@ -1,6 +1,6 @@
# Configuration for GNU nano - a small and user-friendly text editor
#
# Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.
# Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc.
# Copyright (C) 2014, 2017 Mike Frysinger
#
# GNU nano is free software: you can redistribute it and/or modify
@@ -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], [5.3], [nano-devel@gnu.org], [nano])
AC_INIT([GNU nano], [5.8], [nano-devel@gnu.org], [nano])
AC_CONFIG_SRCDIR([src/nano.c])
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([1.14])
@@ -59,7 +59,7 @@ AC_DEFINE_DIR([PKGDATADIR], [pkgdatadir], [Where data are placed to.])
dnl Whether this is a git repository.
AC_MSG_CHECKING([whether building from git])
if test -f roll-a-release.sh ; then
if test -f "$srcdir/roll-a-release.sh" ; then
AC_MSG_RESULT([yes])
from_git=yes
else
@@ -90,13 +90,6 @@ AC_CHECK_HEADERS(libintl.h limits.h pwd.h termios.h sys/param.h)
dnl Checks for options.
if test "x$with_slang" = xyes; then
if test "x$enable_tiny" != xyes; then
AC_MSG_ERROR([
*** --with-slang is supported only together with --enable-tiny])
fi
fi
AC_ARG_ENABLE(browser,
AS_HELP_STRING([--disable-browser], [Disable the built-in file browser]))
if test "x$enable_tiny" = xyes; then
@@ -354,198 +347,10 @@ AS_HELP_STRING([--enable-altrcname], [Specify an alternate rcfile name (default:
AC_DEFINE_UNQUOTED(RCFILE_NAME, "$enableval", [Specify an alternate rcfile name (default: .nanorc).]) rcfilename=$enableval
fi])
AC_MSG_CHECKING([whether to use slang])
CURSES_LIB_NAME=""
AC_ARG_WITH(slang,
AS_HELP_STRING([--with-slang[=DIR]], [Use the slang library instead of curses]),
[ case "$with_slang" in
no)
AC_MSG_RESULT(no)
;;
*)
AC_MSG_RESULT(yes)
if test x$with_slang != xyes; then
# Add additional search path.
LDFLAGS="-L$with_slang/lib $LDFLAGS"
CPPFLAGS="-I$with_slang/include $CPPFLAGS"
fi
if test "x$enable_utf8" != xno; then
AC_CHECK_HEADER(slcurses.h,
AC_MSG_CHECKING([for SLutf8_enable in -lslang])
_libs=$LIBS
LIBS="$LIBS -lslang"
AC_TRY_RUN([
#include <slcurses.h>
int main(void)
{
SLutf8_enable(1);
return 0;
}],
[AC_MSG_RESULT(yes)
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
CURSES_LIB_WIDE=yes
if test x$with_slang != xyes; then
CURSES_LIB="-L${with_slang}/lib -lslang"
else
CURSES_LIB="-lslang"
fi
CURSES_LIB_NAME=slang],
[AC_MSG_RESULT(no)
# We might need the term library.
for termlib in ncurses curses termcap terminfo termlib; do
AC_CHECK_LIB([${termlib}], tputs, [tcap="-l$termlib"])
test -n "$tcap" && break
done
AC_MSG_CHECKING([for SLutf8_enable in -lslang $tcap])
LIBS="$LIBS $tcap"
AC_TRY_RUN([
#include <slcurses.h>
int main(void)
{
SLutf8_enable(1);
return 0;
}],
[AC_MSG_RESULT(yes)
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
CURSES_LIB_WIDE=yes
if test x$with_slang != xyes; then
CURSES_LIB="-L${with_slang}/lib -lslang $tcap"
else
CURSES_LIB="-lslang $tcap"
fi
CURSES_LIB_NAME=slang],
[AC_MSG_RESULT(no)
# We might need the math library.
AC_MSG_CHECKING([for SLutf8_enable in -lslang $tcap -lm])
LIBS="$LIBS -lm"
AC_TRY_RUN([
#include <slcurses.h>
int main(void)
{
SLutf8_enable(1);
return 0;
}],
[AC_MSG_RESULT(yes)
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
CURSES_LIB_WIDE=yes
if test x$with_slang != xyes; then
CURSES_LIB="-L${with_slang}/lib -lslang $tcap -lm"
else
CURSES_LIB="-lslang $tcap -lm"
fi
CURSES_LIB_NAME=slang],
[AC_MSG_RESULT(no)],
AC_MSG_WARN([*** Can not use slang when cross-compiling]))],
AC_MSG_WARN([*** Can not use slang when cross-compiling]))],
AC_MSG_WARN([*** Can not use slang when cross-compiling])),
AC_MSG_ERROR([
*** The header file slcurses.h was not found. This header file
*** is required if you wish to use Slang support. Please either
*** install a version of Slang that includes the slcurses.h file
*** or do not call the configure script with --with-slang.]))
fi
if eval "test x$CURSES_LIB_NAME = x"; then
# Reset libs if the above slang tests failed.
if test "x$enable_utf8" != xno; then
LIBS=$_libs
fi
AC_CHECK_HEADER(slcurses.h,
AC_MSG_CHECKING([for SLtt_initialize in -lslang])
_libs=$LIBS
LIBS="$LIBS -lslang"
AC_TRY_RUN([
#include <slcurses.h>
int main(void)
{
SLtt_initialize(NULL);
return 0;
}],
[AC_MSG_RESULT(yes)
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
if test x$with_slang != xyes; then
CURSES_LIB="-L${with_slang}/lib -lslang"
else
CURSES_LIB="-lslang"
fi
CURSES_LIB_NAME=slang],
[AC_MSG_RESULT(no)
# We might need the term library.
for termlib in ncurses curses termcap terminfo termlib; do
AC_CHECK_LIB([${termlib}], tputs, [tcap="-l$termlib"])
test -n "$tcap" && break
done
AC_MSG_CHECKING([for SLtt_initialize in -lslang $tcap])
LIBS="$LIBS $tcap"
AC_TRY_RUN([
#include <slcurses.h>
int main(void)
{
SLtt_initialize(NULL);
return 0;
}],
[AC_MSG_RESULT(yes)
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
if test x$with_slang != xyes; then
CURSES_LIB="-L${with_slang}/lib -lslang $tcap"
else
CURSES_LIB="-lslang $tcap"
fi
CURSES_LIB_NAME=slang],
[AC_MSG_RESULT(no)
# We might need the math library.
AC_MSG_CHECKING([for SLtt_initialize in -lslang $tcap -lm])
LIBS="$LIBS -lm"
AC_TRY_RUN([
#include <slcurses.h>
int main(void)
{
SLtt_initialize(NULL);
return 0;
}],
[AC_MSG_RESULT(yes)
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
if test x$with_slang != xyes; then
CURSES_LIB="-L${with_slang}/lib -lslang $tcap -lm"
else
CURSES_LIB="-lslang $tcap -lm"
fi
CURSES_LIB_NAME=slang],
[AC_MSG_RESULT(no)],
AC_MSG_WARN([*** Can not use slang when cross-compiling]))],
AC_MSG_WARN([*** Can not use slang when cross-compiling]))],
AC_MSG_WARN([*** Can not use slang when cross-compiling])),
AC_MSG_ERROR([
*** The header file slcurses.h was not found. This header file
*** is required if you wish to use Slang support. Please either
*** install a version of Slang that includes the slcurses.h file
*** or do not call the configure script with --with-slang.]))
fi
if test "${_libs+set}" = "set"; then
LIBS=$_libs
fi
if test x$with_slang != xyes; then
LDFLAGS=${_ldflags}
fi
;;
esac], [AC_MSG_RESULT(no)])
dnl Checks for functions.
if test "x$enable_utf8" != xno; then
AC_CHECK_FUNCS(iswalnum iswpunct mblen mbstowcs mbtowc wctomb)
AC_CHECK_FUNCS(iswalpha iswalnum iswpunct mbstowcs wctomb)
fi
dnl Checks for available flags.
@@ -608,7 +413,7 @@ fi
if eval "test x$CURSES_LIB_NAME = x"; then
AC_MSG_ERROR([
*** No curses lib was found. Please install the curses header files
*** from libncursesw5-dev (Debian), ncurses-devel (Fedora), or similar.
*** from libncurses-dev (Debian), ncurses-devel (Fedora), or similar.
*** (Or install ncurses from https://ftp.gnu.org/gnu/ncurses/.)])
else
AC_MSG_RESULT([ The curses library to be used is: $CURSES_LIB_NAME])
@@ -630,11 +435,10 @@ AC_SUBST(CURSES_LIB)
if test "x$enable_utf8" != xno && \
test x$CURSES_LIB_WIDE = xyes && \
test x$ac_cv_func_iswalpha = xyes && \
test x$ac_cv_func_iswalnum = xyes && \
test x$ac_cv_func_iswpunct = xyes && \
test x$ac_cv_func_mblen = xyes && \
test x$ac_cv_func_mbstowcs = xyes && \
test x$ac_cv_func_mbtowc = xyes && \
test x$ac_cv_func_wctomb = xyes; then
AC_DEFINE(ENABLE_UTF8, 1, [Define this if your system has sufficient UTF-8 support.])
else

View File

@@ -79,14 +79,14 @@
<table><tbody>
<tr><td>Ctrl+B &nbsp;&nbsp;</td><td>One character backward</td></tr>
<tr><td>Ctrl+F</td><td>One character forward</td></tr>
<tr><td>Ctrl+<b>&leftarrow;</b></td><td>One word backward</td></tr>
<tr><td>Ctrl+<b>&rightarrow;</b></td><td>One word forward</td></tr>
<tr><td>Ctrl+<b>&larr;</b></td><td>One word backward</td></tr>
<tr><td>Ctrl+<b>&rarr;</b></td><td>One word forward</td></tr>
<tr><td>Ctrl+A</td><td>To start of line</td></tr>
<tr><td>Ctrl+E</td><td>To end of line</td></tr>
<tr><td>Ctrl+P</td><td>One line up</td></tr>
<tr><td>Ctrl+N</td><td>One line down</td></tr>
<tr><td>Ctrl+<b>&uparrow;</b></td><td>To previous block</td></tr>
<tr><td>Ctrl+<b>&downarrow;</b></td><td>To next block</td></tr>
<tr><td>Ctrl+<b>&uarr;</b></td><td>To previous block</td></tr>
<tr><td>Ctrl+<b>&darr;</b></td><td>To next block</td></tr>
<tr><td>Ctrl+Y</td><td>One page up</td></tr>
<tr><td>Ctrl+V</td><td>One page down</td></tr>
<tr><td>Alt+\</td><td>To top of buffer</td></tr>
@@ -98,8 +98,8 @@
<table><tbody>
<tr><td>Alt+G &nbsp;&nbsp;&nbsp;</td><td>Go to specified line</td></tr>
<tr><td>Alt+]</td><td>Go to complementary bracket</td></tr>
<tr><td>Alt+<b>&uparrow;</b></td><td>Scroll viewport up</td></tr>
<tr><td>Alt+<b>&downarrow;</b></td><td>Scroll viewport down</td></tr>
<tr><td>Alt+<b>&uarr;</b></td><td>Scroll viewport up</td></tr>
<tr><td>Alt+<b>&darr;</b></td><td>Scroll viewport down</td></tr>
<tr><td>Alt+&lt;</td><td>Switch to preceding buffer</td></tr>
<tr><td>Alt+&gt;</td><td>Switch to succeeding buffer</td></tr>
</tbody></table>
@@ -108,7 +108,7 @@
<b>Information</b>
<table><tbody>
<tr><td>Ctrl+C &nbsp;&nbsp;</td><td>Report cursor position</td></tr>
<tr><td>Alt+D</td><td>Report word/line/char count</td></tr>
<tr><td>Alt+D</td><td>Report line/word/character count</td></tr>
<tr><td>Ctrl+G</td><td>Display help text</td></tr>
</tbody></table>
<br>

View File

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

View File

@@ -1,4 +1,4 @@
.\" Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.
.\" Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc.
.\"
.\" This document is dual-licensed. You may distribute and/or modify it
.\" under the terms of either of the following licenses:
@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>.
.\"
.TH NANO 1 "version 5.3" "October 2020"
.TH NANO 1 "version 5.8" "June 2021"
.SH NAME
nano \- Nano's ANOther editor, inspired by Pico
@@ -190,9 +190,9 @@ Set the size (width) of a tab to \fInumber\fP columns. The value of
\fInumber\fR must be greater than 0. The default value is \fB8\fR.
.TP
.BR \-U ", " \-\-quickblank
Do quick status-bar blanking: status-bar messages will disappear after 1
keystroke instead of 25. Note that option \fB\-c\fR (\fB\-\-constantshow\fR)
overrides this.
Make status-bar messages disappear after 1 keystroke instead of after 20.
Note that options \fB\-c\fR (\fB\-\-constantshow\fR)
and \fB\-_\fR (\fB\-\-minibar\fR) override this.
.TP
.BR \-V ", " \-\-version
Show the current version number and exit.
@@ -337,6 +337,23 @@ and \fBS\fR when soft-wrapping.
When the buffer is modified, a star (\fB*\fR) is shown after the
filename in the center of the title bar.
.TP
.BR \-_ ", " \-\-minibar
Suppress the title bar and instead show information about
the current buffer at the bottom of the screen, in the space
for the status bar. In this "minibar" the file name is shown
on the left, followed by an asterisk if the buffer has been modified.
On the right are displayed the current line and column number, the
code of the character under the cursor (in Unicode format: U+xxxx),
the same flags as are shown by \fB\-\-stateflags\fR, and a percentage
that expresses how far the cursor is into the file (linewise).
When a file is loaded or saved, and also when switching between buffers,
the number of lines in the buffer is displayed after the file name.
This number is cleared upon the next keystroke, or replaced with an
[i/n] counter when multiple buffers are open.
The line plus column numbers and the character code are displayed only when
\fB\-\-constantshow\fR is used, and can be toggled on and off with \fBM-C\fR.
The state flags are displayed only when \fB\-\-stateflags\fR is used.
.TP
.BR \-! ", " \-\-magic
When neither the file's name nor its first line give a clue,
try using libmagic to determine the applicable syntax.

View File

@@ -7,9 +7,9 @@
@documentencoding UTF-8
@smallbook
@set EDITION 0.5
@set VERSION 5.3
@set UPDATED October 2020
@set EDITION 0.6
@set VERSION 5.8
@set UPDATED June 2021
@dircategory Editors
@direntry
@@ -23,7 +23,7 @@
@titlepage
@title GNU @command{nano}
@subtitle a small and friendly text editor
@subtitle version 5.3
@subtitle version 5.8
@author Chris Allegretta
@page
@@ -33,7 +33,7 @@ This manual documents the GNU @command{nano} editor.
This manual is part of the GNU @command{nano} distribution.@*
@sp 4
Copyright @copyright{} 1999-2009, 2014-2020 Free Software Foundation, Inc.
Copyright @copyright{} 1999-2009, 2014-2021 Free Software Foundation, Inc.
@sp 1
This document is dual-licensed. You may distribute and/or modify it
@@ -53,8 +53,10 @@ under the terms of either of the following licenses:
along with this program. If not, see @url{https://www.gnu.org/licenses/}.
@sp 1
You may contact the author by
You may contact the original author by
e-mail: @email{chrisa@@asty.org}@*
For suggesting improvements: @email{nano-devel@@gnu.org}@*
@end titlepage
@ifnottex
@@ -63,7 +65,7 @@ e-mail: @email{chrisa@@asty.org}@*
@node Top
@top
This manual documents the GNU @command{nano} editor, version 5.3.
This manual documents the GNU @command{nano} editor, version 5.8.
@menu
* Introduction::
@@ -103,9 +105,9 @@ If you want the old, Pico behavior back, you can use the
following options: @option{--breaklonglines},
@option{--jumpyscrolling}, and @option{--emptyline}
(or @option{-bje}).
@sp 1
Please report bugs via @url{https://savannah.gnu.org/bugs/?group=nano}.
@sp 1
For background information see @url{https://nano-editor.org/}.
@node Invoking
@@ -281,9 +283,9 @@ Set the displayed tab length to @var{number} columns. The value of
@item -U
@itemx --quickblank
Do quick status-bar blanking: status-bar messages will disappear after 1
keystroke instead of 25. Note that option @option{-c}
(@option{--constantshow}) overrides this.
Make status-bar messages disappear after 1 keystroke instead of after 20.
Note that options @option{-c} (@option{--constantshow})
and @option{-_} (@option{--minibar}) override this.
@item -V
@itemx --version
@@ -477,6 +479,24 @@ and @code{S} when soft-wrapping.
When the buffer is modified, a star (@code{*}) is shown after the
filename in the center of the title bar.
@item -_
@itemx --minibar
Suppress the title bar and instead show information about
the current buffer at the bottom of the screen, in the space
for the status bar. In this "minibar" the file name is shown
on the left, followed by an asterisk if the buffer has been modified.
On the right are displayed the current line and column number, the
code of the character under the cursor (in Unicode format: U+xxxx),
the same flags as are shown by @code{--stateflags}, and a percentage
that expresses how far the cursor is into the file (linewise).
When a file is loaded or saved, and also when switching between buffers,
the number of lines in the buffer is displayed after the file name.
This number is cleared upon the next keystroke, or replaced with an
[i/n] counter when multiple buffers are open.
The line plus column numbers and the character code are displayed only when
@code{--constantshow} is used, and can be toggled on and off with @key{M-C}.
The state flags are displayed only when @code{--stateflags} is used.
@item -!
@itemx --magic
When neither the file's name nor its first line give a clue,
@@ -858,6 +878,8 @@ Valid names for the foreground and background colors are:
@code{white}, and @code{black}.
Each of these eight names may be prefixed with the word
@code{light} to get a brighter version of that color.
The word @code{grey} or @code{gray} may be used as
a synonym for @code{lightblack}.
On terminal emulators that can do at least 256 colors,
other valid (but unprefixable) color names are:
@@ -878,6 +900,11 @@ text. (The color of the stripe can be changed with @code{set stripecolor}.)
Save the last hundred search strings and replacement strings and
executed commands, so they can be easily reused in later sessions.
@item set indicator
Display a "scrollbar" on the righthand side of the edit window.
It shows the position of the viewport in the buffer
and how much of the buffer is covered by the viewport.
@item set jumpyscrolling
Scroll the buffer contents per half-screen instead of per line.
@@ -906,9 +933,27 @@ searches. This may not include blank characters. The opening set must
come before the closing set, and the two sets must be in the same order.
The default value is "@t{(<[@{)>]@}}".
@item set morespace
Deprecated option since it has become the default setting.
When needed, use @code{unset emptyline} instead.
@item set minibar
Suppress the title bar and instead show information about
the current buffer at the bottom of the screen, in the space
for the status bar. In this "minibar" the file name is shown
on the left, followed by an asterisk if the buffer has been modified.
On the right are displayed the current line and column number, the
code of the character under the cursor (in Unicode format: U+xxxx),
the same flags as are shown by @code{set stateflags}, and a percentage
that expresses how far the cursor is into the file (linewise).
When a file is loaded or saved, and also when switching between buffers,
the number of lines in the buffer is displayed after the file name.
This number is cleared upon the next keystroke, or replaced with an
[i/n] counter when multiple buffers are open.
The line plus column numbers and the character code are displayed only when
@code{set constantshow} is used, and can be toggled on and off with @key{M-C}.
The state flags are displayed only when @code{set stateflags} is used.
@item set minicolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
Use this color combination for the minibar.
(When this option is not specified, the colors of the title bar are used.)
@xref{@code{set functioncolor}} for valid color names.
@item set mouse
Enable mouse support, so that mouse clicks can be used to place the
@@ -927,9 +972,6 @@ Don't display the help lists at the bottom of the screen.
Don't automatically add a newline when a text does not end with one.
(This can cause you to save non-POSIX text files.)
@item set nopauses
Obsolete option. Ignored.
@item set nowrap
Deprecated option since it has become the default setting.
When needed, use @code{unset breaklonglines} instead.
@@ -951,10 +993,10 @@ The cursor position is remembered for the 200 most-recently edited files.
@item set preserve
Preserve the XON and XOFF keys (@kbd{^Q} and @kbd{^S}).
@item set indicator
Display a "scrollbar" on the righthand side of the edit window.
It shows the position of the viewport in the buffer
and how much of the buffer is covered by the viewport.
@item set promptcolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
Use this color combination for the prompt bar.
(When this option is not specified, the colors of the title bar are used.)
@xref{@code{set functioncolor}} for valid color names.
@item set punct "@var{characters}"
Set the characters treated as closing punctuation when justifying
@@ -964,8 +1006,8 @@ specified closing punctuation, optionally followed by closing brackets
The default value is "@t{!.?}".
@item set quickblank
Do quick status-bar blanking: status-bar messages will disappear after 1
keystroke instead of 25. Note that @option{constantshow} overrides this.
Make status-bar messages disappear after 1 keystroke instead of after 20.
Note that options @option{constantshow} and @option{minibar} override this.
@item set quotestr "@var{regex}"
Set the regular expression for matching the quoting part of a line.
@@ -1015,10 +1057,6 @@ jump to that beginning (either forwards or backwards). If the cursor is
already at that position, it will jump to the true beginning of the
line.
@item set smooth
Deprecated option since it has become the default setting.
When needed, use @code{unset jumpyscrolling} instead.
@item set softwrap
Display lines that exceed the screen's width over multiple screen lines.
(You can make this soft-wrapping occur at whitespace instead of rudely at
@@ -1028,6 +1066,11 @@ the screen's edge, by using also @code{set atblanks}.)
Use the given program to do spell checking and correcting.
@xref{@option{--speller}} for details.
@item set spotlightcolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
Use this color combination for highlighting a search match.
The default value is @t{black,lightyellow}.
@xref{@code{set functioncolor}} for valid color names.
@item set stateflags
Use the top-right corner of the screen for showing some state flags:
@code{I} when auto-indenting, @code{M} when the mark is on, @code{L} when
@@ -1067,11 +1110,6 @@ Save a file by default in Unix format. This overrides nano's
default behavior of saving a file in the format that it had.
(This option has no effect when you also use @code{set noconvert}.)
@item set view
Disallow file modification: read-only mode.
This mode allows the user to open also other files for viewing,
unless @option{--restricted} is given on the command line.
@anchor{Whitespace}
@item set whitespace "@var{characters}"
Set the two characters used to indicate the presence of tabs and
@@ -1636,8 +1674,9 @@ is the beginning of a paragraph.
Toggles whether cutting text will cut the whole line or just from the current cursor
position to the end of the line.
@item nowrap
@item breaklonglines
Toggles whether long lines will be hard-wrapped to the next line.
(The old name of this function, 'nowrap', is deprecated.)
@item tabstospaces
Toggles whether typed tabs will be converted to spaces.
@@ -1920,8 +1959,8 @@ Exclude Native Language support. This will disable the use of any
available GNU @command{nano} translations.
@item --enable-utf8
Include support for reading and writing Unicode files. This will require
either a wide version of curses, or a UTF-8-enabled version of Slang.
Include support for reading and writing Unicode files.
This requires a wide version of the curses library.
@item --disable-utf8
Exclude support for reading and writing Unicode files. Normally the
@@ -1932,10 +1971,6 @@ You can use this or the previous option to override that detection.
Use the file with the given @var{name} (in the user's home directory)
as nano's settings file, instead of the default @code{.nanorc}.
@item --with-slang
Compile @command{nano} against Slang instead of against ncurses or other
curses libraries.
@end table
@html

View File

@@ -1,4 +1,4 @@
.\" Copyright (C) 2003-2011, 2013-2020 Free Software Foundation, Inc.
.\" Copyright (C) 2003-2011, 2013-2021 Free Software Foundation, Inc.
.\"
.\" This document is dual-licensed. You may distribute and/or modify it
.\" under the terms of either of the following licenses:
@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>.
.\"
.TH NANORC 5 "version 5.3" "October 2020"
.TH NANORC 5 "version 5.8 "June 2021"
.SH NAME
nanorc \- GNU nano's configuration file
@@ -138,7 +138,7 @@ point to vary along with the width of the screen if the screen is resized.
The default value is \fB\-8\fR.
.TP
.B set functioncolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Specify the color combination to use for the function descriptions
Use this color combination for the concise function descriptions
in the two help lines at the bottom of the screen.
See \fBset titlecolor\fR for more details.
.TP
@@ -159,7 +159,7 @@ and how much of the buffer is covered by the viewport.
Scroll the buffer contents per half-screen instead of per line.
.TP
.B set keycolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Specify the color combination to use for the shortcut key combos
Use this color combination for the shortcut key combos
in the two help lines at the bottom of the screen.
See \fBset titlecolor\fR for more details.
.TP
@@ -182,9 +182,27 @@ searches. This may not include blank characters. The opening set must
come before the closing set, and the two sets must be in the same order.
The default value is "\fB(<[{)>]}\fP".
.TP
.B set morespace
Deprecated option since it has become the default setting.
When needed, use \fBunset emptyline\fR instead.
.B set minibar
Suppress the title bar and instead show information about
the current buffer at the bottom of the screen, in the space
for the status bar. In this "minibar" the file name is shown
on the left, followed by an asterisk if the buffer has been modified.
On the right are displayed the current line and column number, the
code of the character under the cursor (in Unicode format: U+xxxx),
the same flags as are shown by \fBset stateflags\fR, and a percentage
that expresses how far the cursor is into the file (linewise).
When a file is loaded or saved, and also when switching between buffers,
the number of lines in the buffer is displayed after the file name.
This number is cleared upon the next keystroke, or replaced with an
[i/n] counter when multiple buffers are open.
The line plus column numbers and the character code are displayed only when
\fBset constantshow\fR is used, and can be toggled on and off with \fBM-C\fR.
The state flags are displayed only when \fBset stateflags\fR is used.
.TP
.B set minicolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Use this color combination for the minibar.
(When this option is not specified, the colors of the title bar are used.)
See \fBset titlecolor\fR for more details.
.TP
.B set mouse
Enable mouse support, if available for your system. When enabled, mouse
@@ -206,15 +224,12 @@ Don't display the two help lines at the bottom of the screen.
Don't automatically add a newline when a text does not end with one.
(This can cause you to save non-POSIX text files.)
.TP
.B set nopauses
Obsolete option. Ignored.
.TP
.B set nowrap
Deprecated option since it has become the default setting.
When needed, use \fBunset breaklonglines\fR instead.
.TP
.B set numbercolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Specify the color combination to use for line numbers.
Use this color combination for line numbers.
See \fBset titlecolor\fR for more details.
.TP
.B set operatingdir "\fIdirectory\fP"
@@ -230,6 +245,11 @@ The cursor position is remembered for the 200 most-recently edited files.
.B set preserve
Preserve the XON and XOFF keys (\fB^Q\fR and \fB^S\fR).
.TP
.B set promptcolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Use this color combination for the prompt bar.
(When this option is not specified, the colors of the title bar are used.)
See \fBset titlecolor\fR for more details.
.TP
.BI "set punct """ characters """
Set the characters treated as closing punctuation when justifying
paragraphs. This may not include blank characters. Only the
@@ -237,8 +257,8 @@ specfified closing punctuation, optionally followed by closing brackets
(see \fBbrackets\fP), can end sentences. The default value is "\fB!.?\fP".
.TP
.B set quickblank
Do quick status-bar blanking: status-bar messages will disappear after 1
keystroke instead of 25. The option \fBconstantshow\fR overrides this.
Make status-bar messages disappear after 1 keystroke instead of after 20.
Note that options \fBconstantshow\fR and \fBminibar\fR override this.
.TP
.BI "set quotestr """ regex """
Set the regular expression for matching the quoting part of a line.
@@ -267,13 +287,13 @@ Save a changed buffer automatically on exit (\fB^X\fR); don't prompt.
(The old form of this option, \fBset tempfile\fR, is deprecated.)
.TP
.B set scrollercolor \fIfgcolor\fB,\fIbgcolor\fR
Specify the color combination to use for the indicator alias "scrollbar".
Use this color combination for the indicator alias "scrollbar".
(On terminal emulators that link to a libvte older than version 0.55,
using a background color here does not work correctly.)
See \fBset titlecolor\fR for more details.
.TP
.B set selectedcolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Specify the color combination to use for selected text.
Use this color combination for selected text.
See \fBset titlecolor\fR for more details.
.TP
.B set showcursor
@@ -287,10 +307,6 @@ jump to that beginning (either forwards or backwards). If the cursor is
already at that position, it will jump to the true beginning of the
line.
.TP
.B set smooth
Deprecated option since it has become the default setting.
When needed, use \fBunset jumpyscrolling\fR instead.
.TP
.B set softwrap
Display lines that exceed the screen's width over multiple screen lines.
(You can make this soft-wrapping occur at whitespace instead of rudely at
@@ -300,6 +316,11 @@ the screen's edge, by using also \fBset atblanks\fR.)
Use the given \fIprogram\fR to do spell checking and correcting, instead of
using the built-in corrector that calls \fBhunspell\fR(1) or \fBspell\fR(1).
.TP
.B set spotlightcolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Use this color combination for highlighting a search match.
The default value is \fBblack,lightyellow\fR.
See \fBset titlecolor\fR for valid color names.
.TP
.B set stateflags
Use the top-right corner of the screen for showing some state flags:
\fBI\fR when auto-indenting, \fBM\fR when the mark is on, \fBL\fR when
@@ -309,11 +330,11 @@ When the buffer is modified, a star (\fB*\fR) is shown after the
filename in the center of the title bar.
.TP
.B set statuscolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Specify the color combination to use for the status bar.
Use this color combination for the status bar.
See \fBset titlecolor\fR for more details.
.TP
.B set stripecolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Specify the color combination to use for the vertical guiding stripe.
Use this color combination for the vertical guiding stripe.
See \fBset titlecolor\fR for more details.
.TP
.B set suspendable
@@ -327,12 +348,14 @@ greater than 0. The default value is \fB8\fR.
Convert typed tabs to spaces.
.TP
.B set titlecolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Specify the color combination to use for the title bar.
Use this color combination for the title bar.
Valid names for the foreground and background colors are:
.BR red ", " green ", " blue ", " magenta ", " yellow ", " cyan ", "
.BR white ", and " black .
Each of these eight names may be prefixed with the word \fBlight\fR
to get a brighter version of that color.
The word \fBgrey\fR or \fBgray\fR may be used
as a synonym for \fBlightblack\fR.
On terminal emulators that can do at least 256 colors,
other valid (but unprefixable) color names are:
.BR pink ", " purple ", " mauve ", " lagoon ", " mint ", "
@@ -352,11 +375,6 @@ Save a file by default in Unix format. This overrides nano's
default behavior of saving a file in the format that it had.
(This option has no effect when you also use \fBset noconvert\fR.)
.TP
.B set view
Disallow file modification: read-only mode.
This mode allows the user to open also other files for viewing,
unless \fB\-\-restricted\fR is given on the command line.
.TP
.BI "set whitespace """ characters """
Set the two characters used to indicate the presence of tabs and
spaces. They must be single-column characters. The default pair
@@ -898,8 +916,9 @@ is the beginning of a paragraph.
Toggles whether cutting text will cut the whole line or just from the current cursor
position to the end of the line.
.TP
.B nowrap
.B breaklonglines
Toggles whether long lines will be hard-wrapped to the next line.
(The old name of this function, 'nowrap', is deprecated.)
.TP
.B tabstospaces
Toggles whether typed tabs will be converted to spaces.

View File

@@ -1,4 +1,4 @@
.\" Copyright (C) 2002-2007, 2014-2020 Free Software Foundation, Inc.
.\" Copyright (C) 2002-2007, 2014-2021 Free Software Foundation, Inc.
.\"
.\" This document is dual-licensed. You may distribute and/or modify it
.\" under the terms of either of the following licenses:
@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>.
.\"
.TH RNANO 1 "version 5.3" "October 2020"
.TH RNANO 1 "version 5.8" "June 2021"
.SH NAME
rnano \- a restricted nano

View File

@@ -44,8 +44,7 @@
## Do case-sensitive searches by default.
# set casesensitive
## Constantly display the cursor position in the status bar. Note that
## this overrides "quickblank".
## Constantly display the cursor position in the status bar or minibar.
# set constantshow
## Use cut-from-cursor-to-end-of-line by default.
@@ -84,6 +83,9 @@
## come before the latter set, and both must be in the same order.
# set matchbrackets "(<[{)>]}"
## Suppress title bar and show file name and editor state at the bottom.
# set minibar
## Enable mouse support, if available for your system. When enabled,
## mouse clicks can be used to place the cursor, set the mark (with a
## double click), and execute shortcuts. The mouse will work in the X
@@ -121,8 +123,7 @@
## sentences.
# set punct "!.?"
## Do quick status-bar blanking. Status-bar messages will disappear after
## 1 keystroke instead of 26. Note that "constantshow" overrides this.
## Make status-bar messages disappear after 1 keystroke instead of after 20.
# set quickblank
## The regular expression that matches quoting characters in email
@@ -179,9 +180,6 @@
## Snip whitespace at the end of lines when justifying or hard-wrapping.
# set trimblanks
## Disallow file modification. Why would you want this in an rcfile? ;)
# set view
## The two single-column characters used to display the first characters
## of tabs and spaces. 187 in ISO 8859-1 (0000BB in Unicode) and 183 in
## ISO-8859-1 (0000B7 in Unicode) seem to be good values for these.
@@ -203,11 +201,14 @@
## of a single character, and without affecting the cutbuffer).
# set zap
## Paint the interface elements of nano. These are examples;
## by default there are no colors, except for errorcolor.
## Paint the interface elements of nano. These are examples; there are
## no colors by default, except for errorcolor and spotlightcolor.
# set titlecolor bold,lightwhite,blue
# set promptcolor lightwhite,lightblack
# set statuscolor bold,lightwhite,green
# set errorcolor bold,lightwhite,red
# set spotlightcolor black,lime
# set selectedcolor lightwhite,magenta
# set stripecolor ,yellow
# set scrollercolor cyan
@@ -217,8 +218,10 @@
## In root's .nanorc you might want to use:
# set titlecolor bold,lightwhite,magenta
# set promptcolor black,yellow
# set statuscolor bold,lightwhite,magenta
# set errorcolor bold,lightwhite,red
# set spotlightcolor black,orange
# set selectedcolor lightwhite,cyan
# set stripecolor ,yellow
# set scrollercolor magenta
@@ -262,6 +265,12 @@
## <Ctrl+Backspace> delete the word to the left of the cursor with:
# bind ^H chopwordleft main
## For quickly uppercasing or lowercasing the word under the cursor.
## (These effectively do a Ctrl+Right followed by a Shift+Ctrl+Left,
## and then pipe the selected text through a sed command.)
#bind Sh-M-U "Oc|sed 's/.*/\U&/'
" main
#bind Sh-M-L "Oc|sed 's/.*/\L&/'
" main
## If you would like nano to have keybindings that are more "usual",
@@ -276,11 +285,11 @@
#bind ^F whereis all
#bind ^G findnext all
#bind ^B wherewas all
#bind M-X flipnewbuffer all
#bind ^X cut all
#bind ^D findprevious all
#bind ^R replace main
#bind ^X cut main
#bind ^C copy main
#bind ^V paste all
#bind ^P location main
#bind ^E execute main
#bind ^A mark main
@@ -290,9 +299,10 @@
#unbind ^Y all
#unbind M-J main
#unbind M-T main
#bind ^Y speller main
#bind ^T gotoline main
#bind ^T gotodir browser
#bind ^T cutrestoffile execute
#bind ^L linter execute
#bind ^U undo main
#bind ^E redo main
#bind M-U undo main
#bind M-R redo main
#bind ^Z undo main

View File

@@ -1,2 +1,2 @@
# List of available languages.
bg ca cs da de eo es eu fi fr ga gl hr hu id it ja ko ms nb nl nn pl pt pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
bg ca cs da de eo es eu fi fr ga gl hr hu id is it ja ko ms nb nl nn pl pt pt_BR ro ru sk sl sr sv tr uk vi zh_CN zh_TW

1172
po/bg.po

File diff suppressed because it is too large Load Diff

1210
po/ca.po

File diff suppressed because it is too large Load Diff

1180
po/cs.po

File diff suppressed because it is too large Load Diff

1176
po/da.po

File diff suppressed because it is too large Load Diff

1185
po/de.po

File diff suppressed because it is too large Load Diff

1187
po/eo.po

File diff suppressed because it is too large Load Diff

1184
po/es.po

File diff suppressed because it is too large Load Diff

1172
po/eu.po

File diff suppressed because it is too large Load Diff

1176
po/fi.po

File diff suppressed because it is too large Load Diff

1193
po/fr.po

File diff suppressed because it is too large Load Diff

1188
po/ga.po

File diff suppressed because it is too large Load Diff

1859
po/gl.po

File diff suppressed because it is too large Load Diff

1451
po/hr.po

File diff suppressed because it is too large Load Diff

1176
po/hu.po

File diff suppressed because it is too large Load Diff

1168
po/id.po

File diff suppressed because it is too large Load Diff

2948
po/is.po Normal file

File diff suppressed because it is too large Load Diff

1176
po/it.po

File diff suppressed because it is too large Load Diff

1182
po/ja.po

File diff suppressed because it is too large Load Diff

1190
po/ko.po

File diff suppressed because it is too large Load Diff

1244
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1185
po/nb.po

File diff suppressed because it is too large Load Diff

1187
po/nl.po

File diff suppressed because it is too large Load Diff

1172
po/nn.po

File diff suppressed because it is too large Load Diff

1435
po/pl.po

File diff suppressed because it is too large Load Diff

1221
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1458
po/ro.po

File diff suppressed because it is too large Load Diff

2194
po/ru.po

File diff suppressed because it is too large Load Diff

3059
po/sk.po Normal file

File diff suppressed because it is too large Load Diff

1180
po/sl.po

File diff suppressed because it is too large Load Diff

1367
po/sr.po

File diff suppressed because it is too large Load Diff

1335
po/sv.po

File diff suppressed because it is too large Load Diff

1185
po/tr.po

File diff suppressed because it is too large Load Diff

1190
po/uk.po

File diff suppressed because it is too large Load Diff

1172
po/vi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#!/bin/bash
VERSION="5.3"
VERSION="5.8"
./configure -C --enable-tiny && make && ./configure -C &&
@@ -12,7 +12,7 @@ po/update_linguas.sh &&
make distcheck && make dist-xz &&
git add po/*.po po/nano.pot &&
git add po/*.po po/nano.pot po/LINGUAS &&
git commit -m "$(git log -1 --grep 'po: up' | grep o: | sed 's/^ //')" &&
gpg -a -b nano-$VERSION.tar.gz &&

View File

@@ -6,7 +6,7 @@ CLEANFILES = revision.h
if BUILDING_FROM_GIT
SOMETHING = "REVISION \"`git describe --tags 2>/dev/null`\""
else
SOMETHING = "NOTHING \"from tarball\""
SOMETHING = "PLAINBUILD \"from tarball\""
endif
nano.o: revision.h

View File

@@ -1,8 +1,8 @@
/**************************************************************************
* browser.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 2015-2016 Benno Schulenberg *
* Copyright (C) 2001-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2015-2016, 2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -30,7 +30,7 @@
static char **filelist = NULL;
/* The list of files to display in the file browser. */
static size_t filelist_len = 0;
static size_t list_length = 0;
/* The number of files in the list. */
static size_t width = 0;
/* The number of files that we can display per screen row. */
@@ -40,14 +40,14 @@ static size_t selected = 0;
/* The currently selected filename in the list; zero-based. */
/* Set filelist to the list of files contained in the directory path,
* set filelist_len to the number of files in that list, set longest to
* set list_length to the number of files in that list, set longest to
* the width in columns of the longest filename in that list (between 15
* and COLS), and set width to the number of files that we can display
* per screen row. And sort the list too. */
void read_the_list(const char *path, DIR *dir)
{
size_t path_len = strlen(path), index = 0;
const struct dirent *nextdir;
size_t i = 0, path_len = strlen(path);
longest = 0;
@@ -58,7 +58,7 @@ void read_the_list(const char *path, DIR *dir)
if (name_len > longest)
longest = name_len;
i++;
index++;
}
/* Put 10 characters' worth of blank space between columns of filenames
@@ -74,32 +74,31 @@ void read_the_list(const char *path, DIR *dir)
rewinddir(dir);
free_chararray(filelist, filelist_len);
free_chararray(filelist, list_length);
filelist_len = i;
list_length = index;
index = 0;
filelist = nmalloc(filelist_len * sizeof(char *));
filelist = nmalloc(list_length * sizeof(char *));
i = 0;
while ((nextdir = readdir(dir)) != NULL && i < filelist_len) {
while ((nextdir = readdir(dir)) != NULL && index < list_length) {
/* Don't show the "." entry. */
if (strcmp(nextdir->d_name, ".") == 0)
continue;
filelist[i] = nmalloc(path_len + strlen(nextdir->d_name) + 1);
sprintf(filelist[i], "%s%s", path, nextdir->d_name);
filelist[index] = nmalloc(path_len + strlen(nextdir->d_name) + 1);
sprintf(filelist[index], "%s%s", path, nextdir->d_name);
i++;
index++;
}
/* Maybe the number of files in the directory changed between the
* first time we scanned and the second. i is the actual length of
* filelist, so record it. */
filelist_len = i;
/* Maybe the number of files in the directory decreased between the
* first time we scanned and the second time. index is the actual
* length of the file list, so record it. */
list_length = index;
/* Sort the list of names. */
qsort(filelist, filelist_len, sizeof(char *), diralphasort);
qsort(filelist, list_length, sizeof(char *), diralphasort);
/* Calculate how many files fit on a line -- feigning room for two
* spaces beyond the right edge, and adding two spaces of padding
@@ -113,7 +112,7 @@ void browser_select_dirname(const char *needle)
{
size_t looking_at = 0;
for (; looking_at < filelist_len; looking_at++) {
for (; looking_at < list_length; looking_at++) {
if (strcmp(filelist[looking_at], needle) == 0) {
selected = looking_at;
break;
@@ -122,12 +121,12 @@ void browser_select_dirname(const char *needle)
/* If the sought name isn't found, move the highlight so that the
* changed selection will be noticed. */
if (looking_at == filelist_len) {
if (looking_at == list_length) {
--selected;
/* Make sure we stay within the available range. */
if (selected >= filelist_len)
selected = filelist_len - 1;
if (selected >= list_length)
selected = list_length - 1;
}
}
@@ -145,7 +144,7 @@ void browser_refresh(void)
blank_edit();
for (size_t index = selected - selected % (editwinrows * width);
index < filelist_len && row < editwinrows; index++) {
index < list_length && row < editwinrows; index++) {
const char *thename = tail(filelist[index]);
/* The filename we display, minus the path. */
size_t namelen = breadth(thename);
@@ -283,13 +282,13 @@ void findfile(const char *needle, bool forwards)
* we've come back to the point where we started. */
while (TRUE) {
if (forwards) {
if (looking_at++ == filelist_len - 1) {
if (looking_at++ == list_length - 1) {
looking_at = 0;
statusbar(_("Search Wrapped"));
}
} else {
if (looking_at-- == 0) {
looking_at = filelist_len - 1;
looking_at = list_length - 1;
statusbar(_("Search Wrapped"));
}
}
@@ -488,8 +487,8 @@ char *browse(char *path)
selected--;
/* If we're beyond the list, select the last filename. */
if (selected > filelist_len - 1)
selected = filelist_len - 1;
if (selected > list_length - 1)
selected = list_length - 1;
/* If we selected the same filename as last time, fake a
* press of the Enter key so that the file is read in. */
@@ -539,19 +538,19 @@ char *browse(char *path)
if (selected > 0)
selected--;
} else if (func == do_right) {
if (selected < filelist_len - 1)
if (selected < list_length - 1)
selected++;
} else if (func == to_prev_word) {
selected -= (selected % width);
} else if (func == to_next_word) {
selected += width - 1 - (selected % width);
if (selected >= filelist_len)
selected = filelist_len - 1;
if (selected >= list_length)
selected = list_length - 1;
} else if (func == do_up) {
if (selected >= width)
selected -= width;
} else if (func == do_down) {
if (selected + width <= filelist_len - 1)
if (selected + width <= list_length - 1)
selected += width;
} else if (func == to_prev_block) {
selected = ((selected / (editwinrows * width)) *
@@ -560,9 +559,9 @@ char *browse(char *path)
selected = ((selected / (editwinrows * width)) *
editwinrows * width) + selected % width +
editwinrows * width - width;
if (selected >= filelist_len)
selected = (filelist_len / width) * width + selected % width;
if (selected >= filelist_len)
if (selected >= list_length)
selected = (list_length / width) * width + selected % width;
if (selected >= list_length)
selected -= width;
} else if (func == do_page_up) {
if (selected < width)
@@ -572,17 +571,17 @@ char *browse(char *path)
else
selected -= editwinrows * width;
} else if (func == do_page_down) {
if (selected + width >= filelist_len - 1)
selected = filelist_len - 1;
else if (selected + editwinrows * width >= filelist_len)
selected = (selected + editwinrows * width - filelist_len) %
width + filelist_len - width;
if (selected + width >= list_length - 1)
selected = list_length - 1;
else if (selected + editwinrows * width >= list_length)
selected = (selected + editwinrows * width - list_length) %
width + list_length - width;
else
selected += editwinrows * width;
} else if (func == to_first_file) {
selected = 0;
} else if (func == to_last_file) {
selected = filelist_len - 1;
selected = list_length - 1;
} else if (func == goto_dir) {
/* Ask for the directory to go to. */
if (do_prompt(MGOTODIR, "", NULL,
@@ -616,7 +615,7 @@ char *browse(char *path)
/* In case the specified directory cannot be entered, select it
* (if it is in the current list) so it will be highlighted. */
for (size_t j = 0; j < filelist_len; j++)
for (size_t j = 0; j < list_length; j++)
if (strcmp(filelist[j], path) == 0)
selected = j;
@@ -690,9 +689,9 @@ char *browse(char *path)
free(path);
free_chararray(filelist, filelist_len);
free_chararray(filelist, list_length);
filelist = NULL;
filelist_len = 0;
list_length = 0;
return chosen;
}

View File

@@ -1,8 +1,8 @@
/**************************************************************************
* chars.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 2016-2019 Benno Schulenberg *
* Copyright (C) 2001-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2016-2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -51,7 +51,7 @@ bool is_alpha_char(const char *c)
#ifdef ENABLE_UTF8
wchar_t wc;
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
if (mbtowide(&wc, c) < 0)
return FALSE;
return iswalpha(wc);
@@ -67,7 +67,7 @@ bool is_alnum_char(const char *c)
#ifdef ENABLE_UTF8
wchar_t wc;
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
if (mbtowide(&wc, c) < 0)
return FALSE;
return iswalnum(wc);
@@ -85,7 +85,7 @@ bool is_blank_char(const char *c)
if ((signed char)*c >= 0)
return (*c == ' ' || *c == '\t');
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
if (mbtowide(&wc, c) < 0)
return FALSE;
return iswblank(wc);
@@ -112,7 +112,7 @@ bool is_punct_char(const char *c)
#ifdef ENABLE_UTF8
wchar_t wc;
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
if (mbtowide(&wc, c) < 0)
return FALSE;
return iswpunct(wc);
@@ -176,56 +176,123 @@ char control_mbrep(const char *c, bool isdata)
}
#ifdef ENABLE_UTF8
/* Return the width in columns of the given (multibyte) character. */
int mbwidth(const char *c)
/* Convert the given multibyte sequence c to wide character wc, and return
* the number of bytes in the sequence, or -1 for an invalid sequence. */
int mbtowide(wchar_t *wc, const char *c)
{
/* Ask for the width only when the character isn't plain ASCII. */
if ((signed char)*c <= 0) {
wchar_t wc;
int width;
if ((signed char)*c < 0 && use_utf8) {
unsigned char v1 = (unsigned char)c[0];
unsigned char v2 = (unsigned char)c[1] ^ 0x80;
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
return 1;
if (v2 > 0x3F || v1 < 0xC2)
return -1;
width = wcwidth(wc);
if (v1 < 0xE0) {
*wc = (((unsigned int)(v1 & 0x1F) << 6) | (unsigned int)v2);
return 2;
}
if (width < 0)
return 1;
unsigned char v3 = (unsigned char)c[2] ^ 0x80;
return width;
} else
return 1;
}
if (v3 > 0x3F)
return -1;
/* Convert the given Unicode value to a multibyte character, if possible.
* If the conversion succeeds, return the (dynamically allocated) multibyte
* character and its length. Otherwise, return a length of zero. */
char *make_mbchar(long code, int *length)
{
char *mb_char = nmalloc(MAXCHARLEN);
if (v1 < 0xF0) {
if ((v1 > 0xE0 || v2 >= 0x20) && (v1 != 0xED || v2 < 0x20)) {
*wc = (((unsigned int)(v1 & 0x0F) << 12) |
((unsigned int)v2 << 6) | (unsigned int)v3);
return 3;
} else
return -1;
}
*length = wctomb(mb_char, (wchar_t)code);
unsigned char v4 = (unsigned char)c[3] ^ 0x80;
/* Reject invalid Unicode characters. */
if (*length < 0 || !is_valid_unicode((wchar_t)code)) {
IGNORE_CALL_RESULT(wctomb(NULL, 0));
*length = 0;
if (v4 > 0x3F || v1 > 0xF4)
return -1;
if ((v1 > 0xF0 || v2 >= 0x10) && (v1 != 0xF4 || v2 < 0x10)) {
*wc = (((unsigned int)(v1 & 0x07) << 18) | ((unsigned int)v2 << 12) |
((unsigned int)v3 << 6) | (unsigned int)v4);
return 4;
} else
return -1;
}
return mb_char;
*wc = (unsigned int)*c;
return 1;
}
/* Return TRUE when the given character occupies two cells. */
bool is_doublewidth(const char *ch)
{
wchar_t wc;
/* Only from U+1100 can code points have double width. */
if ((unsigned char)*ch < 0xE1 || !use_utf8)
return FALSE;
if (mbtowide(&wc, ch) < 0)
return FALSE;
return (wcwidth(wc) == 2);
}
/* Return TRUE when the given character occupies zero cells. */
bool is_zerowidth(const char *ch)
{
wchar_t wc;
/* Only from U+0300 can code points have zero width. */
if ((unsigned char)*ch < 0xCC || !use_utf8)
return FALSE;
if (mbtowide(&wc, ch) < 0)
return FALSE;
#if defined(__OpenBSD__)
/* Work around an OpenBSD bug -- see https://sv.gnu.org/bugs/?60393. */
if (wc >= 0xF0000)
return FALSE;
#endif
return (wcwidth(wc) == 0);
}
#endif /* ENABLE_UTF8 */
/* Return the length (in bytes) of the character located at *pointer. */
/* Return the number of bytes in the character that starts at *pointer. */
int char_length(const char *pointer)
{
#ifdef ENABLE_UTF8
/* If possibly a multibyte character, get its length; otherwise, it's 1. */
if ((signed char)*pointer < 0) {
int length = mblen(pointer, MAXCHARLEN);
if ((unsigned char)*pointer > 0xC1 && use_utf8) {
unsigned char c1 = (unsigned char)pointer[0];
unsigned char c2 = (unsigned char)pointer[1];
return (length < 0 ? 1 : length);
} else
if ((c2 ^ 0x80) > 0x3F)
return 1;
if (c1 < 0xE0)
return 2;
if (((unsigned char)pointer[2] ^ 0x80) > 0x3F)
return 1;
if (c1 < 0xF0) {
if ((c1 > 0xE0 || c2 >= 0xA0) && (c1 != 0xED || c2 < 0xA0))
return 3;
else
return 1;
}
if (((unsigned char)pointer[3] ^ 0x80) > 0x3F)
return 1;
if (c1 > 0xF4)
return 1;
if ((c1 > 0xF0 || c2 >= 0x90) && (c1 != 0xF4 || c2 < 0x90))
return 4;
}
#endif
return 1;
}
@@ -236,15 +303,7 @@ size_t mbstrlen(const char *pointer)
size_t count = 0;
while (*pointer != '\0') {
#ifdef ENABLE_UTF8
if ((signed char)*pointer < 0) {
int length = mblen(pointer, MAXCHARLEN);
pointer += (length < 0 ? 1 : length);
} else
#endif
pointer++;
pointer += char_length(pointer);
count++;
}
@@ -255,19 +314,7 @@ size_t mbstrlen(const char *pointer)
* given string, and return a copy of this character in *thechar. */
int collect_char(const char *string, char *thechar)
{
int charlen;
#ifdef ENABLE_UTF8
/* If this is a UTF-8 starter byte, get the number of bytes of the character. */
if ((signed char)*string < 0) {
charlen = mblen(string, MAXCHARLEN);
/* When the multibyte sequence is invalid, only take the first byte. */
if (charlen <= 0)
charlen = 1;
} else
#endif
charlen = 1;
int charlen = char_length(string);
for (int i = 0; i < charlen; i++)
thechar[i] = string[i];
@@ -280,20 +327,29 @@ int collect_char(const char *string, char *thechar)
int advance_over(const char *string, size_t *column)
{
#ifdef ENABLE_UTF8
if ((signed char)*string < 0) {
int charlen = mblen(string, MAXCHARLEN);
if (charlen > 0) {
if (is_cntrl_char(string))
*column += 2;
else
*column += mbwidth(string);
if ((signed char)*string < 0 && use_utf8) {
/* A UTF-8 upper control code has two bytes and takes two columns. */
if (((unsigned char)string[0] == 0xC2 && (signed char)string[1] < -96)) {
*column += 2;
return 2;
} else {
charlen = 1;
*column += 1;
}
wchar_t wc;
int charlen = mbtowide(&wc, string);
return charlen;
if (charlen < 0) {
*column += 1;
return 1;
}
int width = wcwidth(wc);
#if defined(__OpenBSD__)
*column += (width < 0 || wc >= 0xF0000) ? 1 : width;
#else
*column += (width < 0) ? 1 : width;
#endif
return charlen;
}
}
#endif
@@ -302,12 +358,8 @@ int advance_over(const char *string, size_t *column)
*column += tabsize - *column % tabsize;
else
*column += 2;
} else if (*string == 0x7F)
} else if (0x7E < (unsigned char)*string && (unsigned char)*string < 0xA0)
*column += 2;
#ifndef ENABLE_UTF8
else if (0x7F < (unsigned char)*string && (unsigned char)*string < 0xA0)
*column += 2;
#endif
else
*column += 1;
@@ -390,8 +442,8 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n)
continue;
}
bool bad1 = (mbtowc(&wc1, s1, MAXCHARLEN) < 0);
bool bad2 = (mbtowc(&wc2, s2, MAXCHARLEN) < 0);
bool bad1 = (mbtowide(&wc1, s1) < 0);
bool bad2 = (mbtowide(&wc2, s2) < 0);
if (bad1 || bad2) {
if (*s1 != *s2)
@@ -446,7 +498,7 @@ char *revstrstr(const char *haystack, const char *needle,
size_t tail_len = strlen(pointer);
if (tail_len < needle_len)
pointer += tail_len - needle_len;
pointer -= (needle_len - tail_len);
while (pointer >= haystack) {
if (strncmp(pointer, needle, needle_len) == 0)
@@ -466,7 +518,7 @@ char *revstrcasestr(const char *haystack, const char *needle,
size_t tail_len = strlen(pointer);
if (tail_len < needle_len)
pointer += tail_len - needle_len;
pointer -= (needle_len - tail_len);
while (pointer >= haystack) {
if (strncasecmp(pointer, needle, needle_len) == 0)
@@ -488,7 +540,7 @@ char *mbrevstrcasestr(const char *haystack, const char *needle,
size_t tail_len = mbstrlen(pointer);
if (tail_len < needle_len)
pointer += tail_len - needle_len;
pointer -= (needle_len - tail_len);
if (pointer < haystack)
return NULL;
@@ -516,13 +568,13 @@ char *mbstrchr(const char *string, const char *chr)
bool bad_s = FALSE, bad_c = FALSE;
wchar_t ws, wc;
if (mbtowc(&wc, chr, MAXCHARLEN) < 0) {
if (mbtowide(&wc, chr) < 0) {
wc = (unsigned char)*chr;
bad_c = TRUE;
}
while (*string != '\0') {
int symlen = mbtowc(&ws, string, MAXCHARLEN);
int symlen = mbtowide(&ws, string);
if (symlen < 0) {
ws = (unsigned char)*string;
@@ -584,20 +636,13 @@ char *mbrevstrpbrk(const char *head, const char *accept, const char *pointer)
#endif /* !NANO_TINY */
#if defined(ENABLE_NANORC) && (!defined(NANO_TINY) || defined(ENABLE_JUSTIFY))
/* Return TRUE if the given string contains at least one blank character,
* and FALSE otherwise. */
/* Return TRUE if the given string contains at least one blank character. */
bool has_blank_char(const char *string)
{
char symbol[MAXCHARLEN];
while (*string != '\0' && !is_blank_char(string))
string += char_length(string);
while (*string != '\0') {
string += collect_char(string, symbol);
if (is_blank_char(symbol))
return TRUE;
}
return FALSE;
return *string;
}
#endif /* ENABLE_NANORC && (!NANO_TINY || ENABLE_JUSTIFY) */
@@ -609,14 +654,3 @@ bool white_string(const char *string)
return !*string;
}
#ifdef ENABLE_UTF8
/* Return TRUE if wc is valid Unicode, and FALSE otherwise. */
bool is_valid_unicode(wchar_t wc)
{
return ((0 <= wc && wc <= 0xD7FF) ||
(0xE000 <= wc && wc <= 0xFDCF) ||
(0xFDF0 <= wc && wc <= 0xFFFD) ||
(0xFFFF < wc && wc <= 0x10FFFF && (wc & 0xFFFF) <= 0xFFFD));
}
#endif

View File

@@ -1,8 +1,8 @@
/**************************************************************************
* color.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 2014-2017 Benno Schulenberg *
* Copyright (C) 2001-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2014-2017, 2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -29,15 +29,6 @@
#endif
#include <string.h>
/* For early versions of ncurses-6.0, use an additional A_PROTECT attribute
* for all colors, in order to work around an ncurses miscoloring bug. */
#if defined(NCURSES_VERSION_MAJOR) && (NCURSES_VERSION_MAJOR == 6) && \
(NCURSES_VERSION_MINOR == 0) && (NCURSES_VERSION_PATCH < 20151017)
#define A_BANDAID A_PROTECT
#else
#define A_BANDAID A_NORMAL
#endif
static bool defaults_allowed = FALSE;
/* Whether ncurses accepts -1 to mean "default color". */
@@ -61,17 +52,20 @@ void set_interface_colorpairs(void)
combo->bg = COLOR_BLACK;
}
init_pair(index + 1, combo->fg, combo->bg);
interface_color_pair[index] = COLOR_PAIR(index + 1) | A_BANDAID |
combo->attributes;
interface_color_pair[index] = COLOR_PAIR(index + 1) | combo->attributes;
} else {
if (index == FUNCTION_TAG || index == SCROLL_BAR)
interface_color_pair[index] = A_NORMAL;
else if (index == GUIDE_STRIPE)
interface_color_pair[index] = A_REVERSE;
else if (index == SPOTLIGHTED) {
init_pair(index + 1, COLOR_BLACK, COLOR_YELLOW + (COLORS > 15 ? 8 : 0));
interface_color_pair[index] = COLOR_PAIR(index + 1);
} else if (index == MINI_INFOBAR || index == PROMPT_BAR)
interface_color_pair[index] = interface_color_pair[TITLE_BAR];
else if (index == ERROR_MESSAGE) {
init_pair(index + 1, COLOR_WHITE, COLOR_RED);
interface_color_pair[index] = COLOR_PAIR(index + 1) |
A_BOLD | A_BANDAID;
interface_color_pair[index] = COLOR_PAIR(index + 1) | A_BOLD;
} else
interface_color_pair[index] = hilite_attribute;
}
@@ -102,7 +96,7 @@ void set_syntax_colorpairs(syntaxtype *sntx)
ink->pairnum = (older != ink) ? older->pairnum : ++number;
ink->attributes |= COLOR_PAIR(ink->pairnum) | A_BANDAID;
ink->attributes |= COLOR_PAIR(ink->pairnum);
}
}
@@ -125,19 +119,9 @@ void prepare_palette(void)
* the list starting at head. Return TRUE upon success. */
bool found_in_list(regexlisttype *head, const char *shibboleth)
{
regexlisttype *item;
regex_t rgx;
for (item = head; item != NULL; item = item->next) {
regcomp(&rgx, item->full_regex, NANO_REG_EXTENDED);
if (regexec(&rgx, shibboleth, 0, NULL, 0) == 0) {
regfree(&rgx);
for (regexlisttype *item = head; item != NULL; item = item->next)
if (regexec(item->one_rgx, shibboleth, 0, NULL, 0) == 0)
return TRUE;
}
regfree(&rgx);
}
return FALSE;
}
@@ -240,15 +224,6 @@ void find_and_prime_applicable_syntax(void)
openfile->syntax = sntx;
}
/* Allocate and initialize (for the given line) the cache for multiline info. */
void set_up_multicache(linestruct *line)
{
line->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
for (short index = 0; index < openfile->syntax->nmultis; index++)
line->multidata[index] = -1;
}
/* Determine whether the matches of multiline regexes are still the same,
* and if not, schedule a screen refresh, so things will be repainted. */
void check_the_multis(linestruct *line)
@@ -262,8 +237,10 @@ void check_the_multis(linestruct *line)
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0)
return;
if (line->multidata == NULL)
set_up_multicache(line);
if (line->multidata == NULL) {
refresh_needed = TRUE;
return;
}
for (ink = openfile->syntax->color; ink != NULL; ink = ink->next) {
/* If it's not a multiline regex, skip. */
@@ -275,19 +252,22 @@ void check_the_multis(linestruct *line)
anend = (regexec(ink->end, afterstart, 1, &endmatch, 0) == 0);
/* Check whether the multidata still matches the current situation. */
if (line->multidata[ink->id] == CNONE ||
line->multidata[ink->id] == CWHOLELINE) {
if (line->multidata[ink->id] == NOTHING) {
if (!astart)
continue;
} else if (line->multidata[ink->id] & (WHOLELINE|WOULDBE)) {
if (!astart && !anend)
continue;
} else if (line->multidata[ink->id] == CSTARTENDHERE) {
if (astart && anend && startmatch.rm_so < endmatch.rm_so)
} else if (line->multidata[ink->id] == JUSTONTHIS) {
if (astart && anend && regexec(ink->start, line->data + endmatch.rm_eo,
1, &startmatch, 0) != 0)
continue;
} else if (line->multidata[ink->id] == CBEGINBEFORE) {
if (!astart && anend)
continue;
} else if (line->multidata[ink->id] == CENDAFTER) {
} else if (line->multidata[ink->id] == STARTSHERE) {
if (astart && !anend)
continue;
} else if (line->multidata[ink->id] == ENDSHERE) {
if (!astart && anend)
continue;
}
/* There is a mismatch, so something changed: repaint. */
@@ -304,13 +284,19 @@ void precalc_multicolorinfo(void)
regmatch_t startmatch, endmatch;
linestruct *line, *tailline;
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0 ||
openfile->filetop->multidata || ISSET(NO_SYNTAX))
if (!openfile->syntax || openfile->syntax->nmultis == 0 || ISSET(NO_SYNTAX))
return;
//#define TIMEPRECALC 123
#ifdef TIMEPRECALC
#include <time.h>
clock_t start = clock();
#endif
/* For each line, allocate cache space for the multiline-regex info. */
for (line = openfile->filetop; line != NULL; line = line->next)
set_up_multicache(line);
if (!line->multidata)
line->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
for (ink = openfile->syntax->color; ink != NULL; ink = ink->next) {
/* If this is not a multi-line regex, skip it. */
@@ -321,66 +307,68 @@ void precalc_multicolorinfo(void)
int index = 0;
/* Assume nothing applies until proven otherwise below. */
line->multidata[ink->id] = CNONE;
line->multidata[ink->id] = NOTHING;
/* For an unpaired start match, mark all remaining lines. */
if (line->prev && line->prev->multidata[ink->id] == CWOULDBE) {
line->multidata[ink->id] = CWOULDBE;
continue;
}
/* When the line contains a start match, look for an end, and if
* found, mark all the lines that are affected. */
while (regexec(ink->start, line->data + index, 1,
&startmatch, (index == 0) ? 0 : REG_NOTBOL) == 0) {
/* When the line contains a start match, look for an end,
* and if found, mark all the lines that are affected. */
while (regexec(ink->start, line->data + index, 1, &startmatch,
(index == 0) ? 0 : REG_NOTBOL) == 0) {
/* Begin looking for an end match after the start match. */
index += startmatch.rm_eo;
/* If there is an end match on this line, mark the line, but
* continue looking for other starts after it. */
if (regexec(ink->end, line->data + index, 1,
&endmatch, (index == 0) ? 0 : REG_NOTBOL) == 0) {
line->multidata[ink->id] = CSTARTENDHERE;
/* If there is an end match on this same line, mark the line,
* but continue looking for other starts after it. */
if (regexec(ink->end, line->data + index, 1, &endmatch,
(index == 0) ? 0 : REG_NOTBOL) == 0) {
line->multidata[ink->id] = JUSTONTHIS;
index += endmatch.rm_eo;
/* If both start and end are mere anchors, step ahead. */
if (startmatch.rm_so == startmatch.rm_eo &&
endmatch.rm_so == endmatch.rm_eo) {
/* When at end-of-line, we're done. */
/* If the total match has zero length, force an advance. */
if (startmatch.rm_eo - startmatch.rm_so + endmatch.rm_eo == 0) {
/* When at end-of-line, there is no other start. */
if (line->data[index] == '\0')
break;
index = step_right(line->data, index);
}
continue;
}
/* Look for an end match on later lines. */
tailline = line->next;
while (tailline != NULL) {
if (regexec(ink->end, tailline->data, 1, &endmatch, 0) == 0)
break;
while (tailline && regexec(ink->end, tailline->data,
1, &endmatch, 0) != 0)
tailline = tailline->next;
}
/* When there is no end match, mark relevant lines as such. */
if (tailline == NULL) {
line->multidata[ink->id] = CWOULDBE;
for (; line->next != NULL; line = line->next)
line->multidata[ink->id] = WOULDBE;
line->multidata[ink->id] = WOULDBE;
break;
}
/* We found it, we found it, la la la la la. Mark all
* the lines in between and the end properly. */
line->multidata[ink->id] = CENDAFTER;
/* We found it, we found it, la lala lala. Mark the lines. */
line->multidata[ink->id] = STARTSHERE;
// Note that this also advances the line in the main loop.
for (line = line->next; line != tailline; line = line->next)
line->multidata[ink->id] = CWHOLELINE;
line->multidata[ink->id] = WHOLELINE;
tailline->multidata[ink->id] = CBEGINBEFORE;
tailline->multidata[ink->id] = ENDSHERE;
/* Begin looking for a new start after the end match. */
/* Look for a possible new start after the end match. */
index = endmatch.rm_eo;
}
}
}
#ifdef TIMEPRECALC
statusline(INFO, "Precalculation: %.1f ms", 1000 * (double)(clock() - start) / CLOCKS_PER_SEC);
napms(1200);
#endif
}
#endif /* ENABLE_COLOR */

View File

@@ -1,9 +1,9 @@
/**************************************************************************
* cut.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2014 Mark Majeres *
* Copyright (C) 2016, 2018, 2019 Benno Schulenberg *
* Copyright (C) 2016, 2018-2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -34,7 +34,7 @@ void do_deletion(undo_type action)
int charlen = char_length(openfile->current->data + openfile->current_x);
size_t line_len = strlen(openfile->current->data + openfile->current_x);
#ifndef NANO_TINY
size_t old_amount = openfile->current->extrarows;
size_t old_amount = ISSET(SOFTWRAP) ? extra_chunks_in(openfile->current) : 0;
/* If the type of action changed or the cursor moved to a different
* line, create a new undo item, otherwise update the existing item. */
@@ -49,13 +49,9 @@ void do_deletion(undo_type action)
&openfile->current->data[openfile->current_x + charlen],
line_len - charlen + 1);
#ifndef NANO_TINY
/* When softwrapping, recompute the number of chunks in the line,
* and schedule a refresh if the number changed. */
if (ISSET(SOFTWRAP)) {
openfile->current->extrarows = extra_chunks_in(openfile->current);
if (openfile->current->extrarows != old_amount)
refresh_needed = TRUE;
}
/* When softwrapping, a changed number of chunks requires a refresh. */
if (ISSET(SOFTWRAP) && extra_chunks_in(openfile->current) != old_amount)
refresh_needed = TRUE;
/* Adjust the mark if it is after the cursor on the current line. */
if (openfile->mark == openfile->current &&
@@ -94,10 +90,6 @@ void do_deletion(undo_type action)
unlink_node(joining);
#ifndef NANO_TINY
if (ISSET(SOFTWRAP))
openfile->current->extrarows = extra_chunks_in(openfile->current);
#endif
/* Two lines were joined, so do a renumbering and refresh the screen. */
renumber_from(openfile->current);
refresh_needed = TRUE;
@@ -121,7 +113,14 @@ void do_delete(void)
zap_text();
else
#endif
{
do_deletion(DEL);
#ifdef ENABLE_UTF8
while (openfile->current->data[openfile->current_x] != '\0' &&
is_zerowidth(openfile->current->data + openfile->current_x))
do_deletion(DEL);
#endif
}
}
/* Backspace over one character. That is, move the cursor left one
@@ -133,7 +132,10 @@ void do_backspace(void)
zap_text();
else
#endif
if (openfile->current_x > 0 || openfile->current != openfile->filetop) {
if (openfile->current_x > 0) {
openfile->current_x = step_left(openfile->current->data, openfile->current_x);
do_deletion(BACK);
} else if (openfile->current != openfile->filetop) {
do_left();
do_deletion(BACK);
}
@@ -326,9 +328,6 @@ void extract_segment(linestruct *top, size_t top_x, linestruct *bot, size_t bot_
#ifndef NANO_TINY
openfile->current->has_anchor = was_anchored;
if (ISSET(SOFTWRAP))
openfile->current->extrarows = extra_chunks_in(openfile->current);
if (post_marked || same_line)
openfile->mark = openfile->current;
if (post_marked)
@@ -381,10 +380,6 @@ void ingraft_buffer(linestruct *topline)
}
if (topline != botline) {
#ifndef NANO_TINY
/* First compute the softwrapped chunks for each line in the graft. */
compute_the_extra_rows_per_line_from(topline);
#endif
/* When inserting at end-of-buffer, update the relevant pointer. */
if (line->next == NULL)
openfile->filebot = botline;
@@ -417,11 +412,6 @@ void ingraft_buffer(linestruct *topline)
openfile->mark_x += length - xpos;
} else if (mark_follows)
openfile->mark_x += extralen;
if (ISSET(SOFTWRAP)) {
line->extrarows = extra_chunks_in(line);
openfile->current->extrarows = extra_chunks_in(openfile->current);
}
#endif
delete_node(topline);
@@ -702,7 +692,7 @@ void paste_text(void)
/* The leftedge where we started the paste. */
if (cutbuffer == NULL) {
statusbar(_("Cutbuffer is empty"));
statusline(AHEM, _("Cutbuffer is empty"));
return;
}
@@ -724,6 +714,10 @@ void paste_text(void)
/* If we pasted less than a screenful, don't center the cursor. */
if (less_than_a_screenful(was_lineno, was_leftedge))
focusing = FALSE;
#ifdef ENABLE_COLOR
else
precalc_multicolorinfo();
#endif
/* Set the desired x position to where the pasted text ends. */
openfile->placewewant = xplustabs();

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* definitions.h -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2014-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@@ -41,10 +41,55 @@
#include <limits.h>
#endif
/* Set a default value for PATH_MAX if there isn't one. */
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <dirent.h>
#include <regex.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/stat.h>
/* Prefer wide ncurses over normal ncurses over curses. */
#if defined(HAVE_NCURSESW_NCURSES_H)
#include <ncursesw/ncurses.h>
#elif defined(HAVE_NCURSES_H)
#include <ncurses.h>
#else
#include <curses.h>
#endif
/* Native language support. */
#ifdef ENABLE_NLS
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#endif
#define _(string) gettext(string)
#define P_(singular, plural, number) ngettext(singular, plural, number)
#else
#define _(string) (string)
#define P_(singular, plural, number) (number == 1 ? singular : plural)
#endif
/* For marking a string on which gettext() will be called later. */
#define gettext_noop(string) (string)
#define N_(string) gettext_noop(string)
/* If we aren't using an ncurses with mouse support, then
* exclude the mouse routines, as they are useless then. */
#ifndef NCURSES_MOUSE_VERSION
#undef ENABLE_MOUSE
#endif
#if defined(ENABLE_WRAPPING) || defined(ENABLE_JUSTIFY)
#define ENABLED_WRAPORJUSTIFY 1
#endif
/* Suppress warnings for __attribute__((warn_unused_result)). */
#define IGNORE_CALL_RESULT(call) do { if (call) {} } while(0)
@@ -56,70 +101,6 @@
#define ISSET(flag) ((FLAGS(flag) & FLAGMASK(flag)) != 0)
#define TOGGLE(flag) FLAGS(flag) ^= FLAGMASK(flag)
/* In UTF-8 a character is at most six bytes long. */
#ifdef ENABLE_UTF8
#define MAXCHARLEN 6
#else
#define MAXCHARLEN 1
#endif
/* Set a default value for PATH_MAX if there isn't one. */
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#ifdef USE_SLANG
/* Slang support. */
#include <slcurses.h>
/* Slang curses emulation brain damage, part 3: Slang doesn't define the
* curses equivalents of the Insert or Delete keys. */
#define KEY_DC SL_KEY_DELETE
#define KEY_IC SL_KEY_IC
/* Ncurses support. */
#elif defined(HAVE_NCURSESW_NCURSES_H)
#include <ncursesw/ncurses.h>
#elif defined(HAVE_NCURSES_H)
#include <ncurses.h>
#else
/* Curses support. */
#include <curses.h>
#endif /* CURSES_H */
#if defined(NCURSES_VERSION_MAJOR) && (NCURSES_VERSION_MAJOR < 6)
#define USING_OLD_NCURSES yes
#endif
#ifdef ENABLE_NLS
/* Native language support. */
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#endif
#define _(string) gettext(string)
#define P_(singular, plural, number) ngettext(singular, plural, number)
#else
#define _(string) (string)
#define P_(singular, plural, number) (number == 1 ? singular : plural)
#endif
#define gettext_noop(string) (string)
#define N_(string) gettext_noop(string)
/* Mark a string that will be sent to gettext() later. */
#include <dirent.h>
#include <regex.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/stat.h>
/* If we aren't using an ncurses with mouse support, exclude any
* mouse routines, as they are useless then. */
#ifndef NCURSES_MOUSE_VERSION
#undef ENABLE_MOUSE
#endif
#if defined(ENABLE_WRAPPING) || defined(ENABLE_JUSTIFY)
#define ENABLED_WRAPORJUSTIFY 1
#endif
#define BACKWARD FALSE
#define FORWARD TRUE
@@ -130,30 +111,152 @@
#define REPLACING 1
#define INREGION 2
#ifdef ENABLE_UTF8
/* In UTF-8 a valid character is at most four bytes long. */
#define MAXCHARLEN 4
#else
#define MAXCHARLEN 1
#endif
/* The default width of a tab in spaces. */
#define WIDTH_OF_TAB 8
/* The default number of columns from end of line where wrapping occurs. */
#define COLUMNS_FROM_EOL 8
/* The default comment character when a syntax does not specify any. */
#define GENERAL_COMMENT_CHARACTER "#"
/* The maximum number of search/replace history strings saved. */
#define MAX_SEARCH_HISTORY 100
/* The largest size_t number that doesn't have the high bit set. */
#define HIGHEST_POSITIVE ((~(size_t)0) >> 1)
#ifdef ENABLE_COLOR
#define THE_DEFAULT -1
#define BAD_COLOR -2
/* Flags for indicating how a multiline regex pair apply to a line. */
#define NOTHING (1<<1)
/* The start/end regexes don't cover this line at all. */
#define STARTSHERE (1<<2)
/* The start regex matches on this line, the end regex on a later one. */
#define WHOLELINE (1<<3)
/* The start regex matches on an earlier line, the end regex on a later one. */
#define ENDSHERE (1<<4)
/* The start regex matches on an earlier line, the end regex on this one. */
#define JUSTONTHIS (1<<5)
/* Both the start and end regexes match within this line. */
#define WOULDBE (1<<6)
/* An unpaired start match is on or before this line. */
#endif
#define STANDARD_INPUT 0
/* Basic control codes. */
#define ESC_CODE 0x1B
#define DEL_CODE 0x7F
/* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
#define CONTROL_LEFT 0x401
#define CONTROL_RIGHT 0x402
#define CONTROL_UP 0x403
#define CONTROL_DOWN 0x404
#define CONTROL_HOME 0x405
#define CONTROL_END 0x406
#define CONTROL_DELETE 0x40D
#define SHIFT_CONTROL_LEFT 0x411
#define SHIFT_CONTROL_RIGHT 0x412
#define SHIFT_CONTROL_UP 0x413
#define SHIFT_CONTROL_DOWN 0x414
#define SHIFT_CONTROL_HOME 0x415
#define SHIFT_CONTROL_END 0x416
#define CONTROL_SHIFT_DELETE 0x41D
#define ALT_LEFT 0x421
#define ALT_RIGHT 0x422
#define ALT_UP 0x423
#define ALT_DOWN 0x424
#define ALT_PAGEUP 0x427
#define ALT_PAGEDOWN 0x428
#define ALT_INSERT 0x42C
#define ALT_DELETE 0x42D
#define SHIFT_ALT_LEFT 0x431
#define SHIFT_ALT_RIGHT 0x432
#define SHIFT_ALT_UP 0x433
#define SHIFT_ALT_DOWN 0x434
//#define SHIFT_LEFT 0x451
//#define SHIFT_RIGHT 0x452
#define SHIFT_UP 0x453
#define SHIFT_DOWN 0x454
#define SHIFT_HOME 0x455
#define SHIFT_END 0x456
#define SHIFT_PAGEUP 0x457
#define SHIFT_PAGEDOWN 0x458
#define SHIFT_DELETE 0x45D
#define SHIFT_TAB 0x45F
/* A special keycode for when <Tab> is pressed while the mark is on. */
#define INDENT_KEY 0x4F1
/* A special keycode to signal the beginning and end of a bracketed paste. */
#define BRACKETED_PASTE_MARKER 0x4FB
/* A special keycode for when a key produces an unknown escape sequence. */
#define FOREIGN_SEQUENCE 0x4FC
/* A special keycode for plugging into the input stream after a suspension. */
#define KEY_FLUSH KEY_F0
#ifndef NANO_TINY
/* A special keycode for when we get a SIGWINCH (a window resize). */
#define KEY_WINCH -2
/* Some extra flags for the undo function. */
#define WAS_BACKSPACE_AT_EOF (1<<1)
#define WAS_WHOLE_LINE (1<<2)
#define INCLUDED_LAST_LINE (1<<3)
#define MARK_WAS_SET (1<<4)
#define CURSOR_WAS_AT_HEAD (1<<5)
#endif /* !NANO_TINY */
/* Identifiers for the different menus. */
#define MMAIN (1<<0)
#define MWHEREIS (1<<1)
#define MREPLACE (1<<2)
#define MREPLACEWITH (1<<3)
#define MGOTOLINE (1<<4)
#define MWRITEFILE (1<<5)
#define MINSERTFILE (1<<6)
#define MEXECUTE (1<<7)
#define MHELP (1<<8)
#define MSPELL (1<<9)
#define MBROWSER (1<<10)
#define MWHEREISFILE (1<<11)
#define MGOTODIR (1<<12)
#define MYESNO (1<<13)
#define MLINTER (1<<14)
#define MFINDINHELP (1<<15)
/* This is an abbreviation for all menus except Help and Browser and YesNo. */
#define MMOST (MMAIN|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE|MWRITEFILE|MINSERTFILE|\
MEXECUTE|MWHEREISFILE|MGOTODIR|MFINDINHELP|MSPELL|MLINTER)
#ifndef NANO_TINY
#define MSOME MMOST|MBROWSER
#else
#define MSOME MMAIN|MBROWSER
#endif
/* Enumeration types. */
typedef enum {
NIX_FILE, DOS_FILE, MAC_FILE
UNSPECIFIED, NIX_FILE, DOS_FILE, MAC_FILE
} format_type;
typedef enum {
VACUUM, HUSH, NOTICE, MILD, ALERT
VACUUM, HUSH, REMARK, INFO, NOTICE, AHEM, MILD, ALERT
} message_type;
typedef enum {
OVERWRITE, APPEND, PREPEND
} kind_of_writing_type;
typedef enum {
SOFTMARK, HARDMARK
} mark_type;
typedef enum {
CENTERING, FLOWING, STATIONARY
} update_type;
@@ -172,6 +275,76 @@ typedef enum {
COUPLE_BEGIN, COUPLE_END, OTHER
} undo_type;
/* The elements of the interface that can be colored differently. */
enum {
TITLE_BAR = 0,
LINE_NUMBER,
GUIDE_STRIPE,
SCROLL_BAR,
SELECTED_TEXT,
SPOTLIGHTED,
MINI_INFOBAR,
PROMPT_BAR,
STATUS_BAR,
ERROR_MESSAGE,
KEY_COMBO,
FUNCTION_TAG,
NUMBER_OF_ELEMENTS
};
/* Enumeration used in the flags array. See the definition of FLAGMASK. */
enum {
DONTUSE = 0,
CASE_SENSITIVE,
CONSTANT_SHOW,
NO_HELP,
SUSPENDABLE,
NO_WRAP,
AUTOINDENT,
VIEW_MODE,
USE_MOUSE,
USE_REGEXP,
SAVE_ON_EXIT,
CUT_FROM_CURSOR,
BACKWARDS_SEARCH,
MULTIBUFFER,
REBIND_DELETE,
RAW_SEQUENCES,
NO_CONVERT,
MAKE_BACKUP,
INSECURE_BACKUP,
NO_SYNTAX,
PRESERVE,
HISTORYLOG,
RESTRICTED,
SMART_HOME,
WHITESPACE_DISPLAY,
TABS_TO_SPACES,
QUICK_BLANK,
WORD_BOUNDS,
NO_NEWLINES,
BOLD_TEXT,
SOFTWRAP,
POSITIONLOG,
LOCKING,
NOREAD_MODE,
MAKE_IT_UNIX,
TRIM_BLANKS,
SHOW_CURSOR,
LINE_NUMBERS,
AT_BLANKS,
AFTER_ENDS,
LET_THEM_ZAP,
BREAK_LONG_LINES,
JUMPY_SCROLLING,
EMPTY_LINE,
INDICATOR,
BOOKSTYLE,
STATEFLAGS,
USE_MAGIC,
MINIBAR
};
/* Structure types. */
#ifdef ENABLE_COLOR
typedef struct colortype {
@@ -194,8 +367,8 @@ typedef struct colortype {
} colortype;
typedef struct regexlisttype {
char *full_regex;
/* A regex string to match things that imply a certain syntax. */
regex_t *one_rgx;
/* A regex to match things that imply a certain syntax. */
struct regexlisttype *next;
/* The next regex. */
} regexlisttype;
@@ -218,7 +391,7 @@ typedef struct syntaxtype {
/* File where the syntax is defined, or NULL if not an included file. */
size_t lineno;
/* The line number where the 'syntax' command was found. */
struct augmentstruct *augmentations;
augmentstruct *augmentations;
/* List of extendsyntax commands to apply when loaded. */
regexlisttype *extensions;
/* The list of extensions that this syntax applies to. */
@@ -258,20 +431,6 @@ typedef struct lintstruct {
struct lintstruct *prev;
/* Previous error. */
} lintstruct;
/* Flags that indicate how a multiline regex applies to a line. */
#define CNONE (1<<1)
/* Yay, regex doesn't apply to this line at all! */
#define CBEGINBEFORE (1<<2)
/* Regex starts on an earlier line, ends on this one. */
#define CENDAFTER (1<<3)
/* Regex starts on this line and ends on a later one. */
#define CWHOLELINE (1<<4)
/* Whole line engulfed by the regex, start < me, end > me. */
#define CSTARTENDHERE (1<<5)
/* Regex starts and ends within this line. */
#define CWOULDBE (1<<6)
/* An unpaired start match on or before this line. */
#endif /* ENABLE_COLOR */
/* More structure types. */
@@ -280,10 +439,6 @@ typedef struct linestruct {
/* The text of this line. */
ssize_t lineno;
/* The number of this line. */
#ifndef NANO_TINY
ssize_t extrarows;
/* The extra rows that this line occupies when softwrapping. */
#endif
struct linestruct *next;
/* Next node. */
struct linestruct *prev;
@@ -384,8 +539,8 @@ typedef struct openfilestruct {
/* The line in the file where the mark is set; NULL if not set. */
size_t mark_x;
/* The mark's x position in the above line. */
mark_type kind_of_mark;
/* Whether it is a soft (with Shift) or a hard mark. */
bool softmark;
/* Whether a marked region was made by holding Shift. */
format_type fmt;
/* The file's format -- Unix or DOS or Mac. */
char *lock_filename;
@@ -406,6 +561,8 @@ typedef struct openfilestruct {
/* The syntax that applies to this file, if any. */
#endif
#ifdef ENABLE_MULTIBUFFER
char *errormessage;
/* The ALERT message (if any) that occurred when opening the file. */
struct openfilestruct *next;
/* The next open file, if any. */
struct openfilestruct *prev;
@@ -472,185 +629,3 @@ typedef struct completion_word {
struct completion_word *next;
} completion_word;
#endif
/* The elements of the interface that can be colored differently. */
enum
{
TITLE_BAR = 0,
LINE_NUMBER,
GUIDE_STRIPE,
SCROLL_BAR,
SELECTED_TEXT,
STATUS_BAR,
ERROR_MESSAGE,
KEY_COMBO,
FUNCTION_TAG,
NUMBER_OF_ELEMENTS
};
/* Enumeration used in the flags array. See the definition of FLAGMASK. */
enum
{
DONTUSE,
CASE_SENSITIVE,
CONSTANT_SHOW,
NO_HELP,
SUSPENDABLE,
NO_WRAP,
AUTOINDENT,
VIEW_MODE,
USE_MOUSE,
USE_REGEXP,
SAVE_ON_EXIT,
CUT_FROM_CURSOR,
BACKWARDS_SEARCH,
MULTIBUFFER,
SMOOTH_SCROLL,
REBIND_DELETE,
RAW_SEQUENCES,
NO_CONVERT,
MAKE_BACKUP,
INSECURE_BACKUP,
NO_SYNTAX,
PRESERVE,
HISTORYLOG,
RESTRICTED,
SMART_HOME,
WHITESPACE_DISPLAY,
MORE_SPACE,
TABS_TO_SPACES,
QUICK_BLANK,
WORD_BOUNDS,
NO_NEWLINES,
BOLD_TEXT,
SOFTWRAP,
POSITIONLOG,
LOCKING,
NOREAD_MODE,
MAKE_IT_UNIX,
TRIM_BLANKS,
SHOW_CURSOR,
LINE_NUMBERS,
NO_PAUSES,
AT_BLANKS,
AFTER_ENDS,
LET_THEM_ZAP,
BREAK_LONG_LINES,
JUMPY_SCROLLING,
EMPTY_LINE,
INDICATOR,
BOOKSTYLE,
STATEFLAGS,
USE_MAGIC
};
/* Flags for the menus in which a given function should be present. */
#define MMAIN (1<<0)
#define MWHEREIS (1<<1)
#define MREPLACE (1<<2)
#define MREPLACEWITH (1<<3)
#define MGOTOLINE (1<<4)
#define MWRITEFILE (1<<5)
#define MINSERTFILE (1<<6)
#define MEXECUTE (1<<7)
#define MHELP (1<<8)
#define MSPELL (1<<9)
#define MBROWSER (1<<10)
#define MWHEREISFILE (1<<11)
#define MGOTODIR (1<<12)
#define MYESNO (1<<13)
#define MLINTER (1<<14)
#define MFINDINHELP (1<<15)
/* This is an abbreviation for all menus except Help and Browser and YesNo. */
#define MMOST (MMAIN|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE|MWRITEFILE|MINSERTFILE|\
MEXECUTE|MWHEREISFILE|MGOTODIR|MFINDINHELP|MSPELL|MLINTER)
#ifndef NANO_TINY
#define MSOME MMOST|MBROWSER
#else
#define MSOME MMAIN|MBROWSER
#endif
/* Basic control codes. */
#define ESC_CODE 0x1B
#define DEL_CODE 0x7F
/* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
#define CONTROL_LEFT 0x401
#define CONTROL_RIGHT 0x402
#define CONTROL_UP 0x403
#define CONTROL_DOWN 0x404
#define CONTROL_HOME 0x405
#define CONTROL_END 0x406
#define CONTROL_DELETE 0x40D
#define SHIFT_CONTROL_LEFT 0x411
#define SHIFT_CONTROL_RIGHT 0x412
#define SHIFT_CONTROL_UP 0x413
#define SHIFT_CONTROL_DOWN 0x414
#define SHIFT_CONTROL_HOME 0x415
#define SHIFT_CONTROL_END 0x416
#define CONTROL_SHIFT_DELETE 0x41D
#define ALT_LEFT 0x421
#define ALT_RIGHT 0x422
#define ALT_UP 0x423
#define ALT_DOWN 0x424
#define ALT_PAGEUP 0x427
#define ALT_PAGEDOWN 0x428
#define ALT_INSERT 0x42C
#define ALT_DELETE 0x42D
#define SHIFT_ALT_LEFT 0x431
#define SHIFT_ALT_RIGHT 0x432
#define SHIFT_ALT_UP 0x433
#define SHIFT_ALT_DOWN 0x434
//#define SHIFT_LEFT 0x451
//#define SHIFT_RIGHT 0x452
#define SHIFT_UP 0x453
#define SHIFT_DOWN 0x454
#define SHIFT_HOME 0x455
#define SHIFT_END 0x456
#define SHIFT_PAGEUP 0x457
#define SHIFT_PAGEDOWN 0x458
#define SHIFT_DELETE 0x45D
#define SHIFT_TAB 0x45F
/* A special keycode for when <Tab> is pressed while the mark is on. */
#define INDENT_KEY 0x4F1
/* A special keycode to signal the beginning and end of a bracketed paste. */
#define BRACKETED_PASTE_MARKER 0x4FB
/* A special keycode for when a key produces an unknown escape sequence. */
#define FOREIGN_SEQUENCE 0x4FC
#ifdef USE_SLANG
#define KEY_FLUSH 0xFF /* Clipped error code. */
#else
#define KEY_FLUSH KEY_F0 /* Nonexistent function key. */
#endif
#ifndef NANO_TINY
/* An imaginary key for when we get a SIGWINCH (window resize). */
#define KEY_WINCH -2
/* Some extra flags for the undo function. */
#define WAS_BACKSPACE_AT_EOF (1<<1)
#define WAS_WHOLE_LINE (1<<2)
#define INCLUDED_LAST_LINE (1<<3)
#define MARK_WAS_SET (1<<4)
#define CURSOR_WAS_AT_HEAD (1<<5)
#endif /* !NANO_TINY */
/* The default number of columns from end of line where wrapping occurs. */
#define COLUMNS_FROM_EOL 8
/* The default width of a tab in spaces. */
#define WIDTH_OF_TAB 8
/* The default comment character when a syntax does not specify any. */
#define GENERAL_COMMENT_CHARACTER "#"
/* The maximum number of search/replace history strings saved, not
* counting the blank lines at their ends. */
#define MAX_SEARCH_HISTORY 100
/* The largest size_t number that doesn't have the high bit set. */
#define HIGHEST_POSITIVE ((~(size_t)0) >> 1)

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* files.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2015-2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@@ -81,8 +81,9 @@ void make_new_buffer(void)
#endif
#ifndef NANO_TINY
openfile->mark = NULL;
openfile->softmark = FALSE;
openfile->fmt = NIX_FILE;
openfile->fmt = UNSPECIFIED;
openfile->undotop = NULL;
openfile->current_undo = NULL;
@@ -92,11 +93,34 @@ void make_new_buffer(void)
openfile->statinfo = NULL;
openfile->lock_filename = NULL;
#endif
#ifdef ENABLE_MULTIBUFFER
openfile->errormessage = NULL;
#endif
#ifdef ENABLE_COLOR
openfile->syntax = NULL;
#endif
}
/* Return the given file name in a way that fits within the given space. */
char *crop_to_fit(const char *name, int room)
{
char *clipped;
if (breadth(name) <= room)
return display_string(name, 0, room, FALSE, FALSE);
if (room < 4)
return copy_of("_");
clipped = display_string(name, breadth(name) - room + 3, room, FALSE, FALSE);
clipped = nrealloc(clipped, strlen(clipped) + 4);
memmove(clipped + 3, clipped, strlen(clipped) + 1);
clipped[0] = '.'; clipped[1] = '.'; clipped[2] = '.';
return clipped;
}
#ifndef NANO_TINY
/* Delete the lockfile. Return TRUE on success, and FALSE otherwise. */
bool delete_lockfile(const char *lockfilename)
@@ -179,7 +203,8 @@ bool write_lockfile(const char *lockfilename, const char *filename, bool modifie
* some byte-order-checking numbers (bytes 1008-1022). */
lockdata[0] = 0x62;
lockdata[1] = 0x30;
snprintf(&lockdata[2], 10, "nano %s", VERSION);
/* It's fine to overwrite byte 12 with the \0 as it is 0x00 anyway. */
snprintf(&lockdata[2], 11, "nano %s", VERSION);
lockdata[24] = mypid % 256;
lockdata[25] = (mypid / 256) % 256;
lockdata[26] = (mypid / (256 * 256)) % 256;
@@ -225,7 +250,7 @@ char *do_lockfile(const char *filename, bool ask_the_user)
else if (stat(lockfilename, &fileinfo) != -1) {
char *lockbuf, *question, *pidstring, *postedname, *promptstr;
static char lockprog[11], lockuser[17];
int lockfd, lockpid, room, choice;
int lockfd, lockpid, choice;
ssize_t readamt;
if ((lockfd = open(lockfilename, O_RDONLY)) < 0) {
@@ -266,19 +291,8 @@ char *do_lockfile(const char *filename, bool ask_the_user)
/* 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); open anyway?");
room = COLS - breadth(question) + 7 - breadth(lockuser) -
breadth(lockprog) - breadth(pidstring);
if (room < 4)
postedname = copy_of("_");
else if (room < breadth(filename)) {
char *fragment = display_string(filename,
breadth(filename) - room + 3, room, FALSE, FALSE);
postedname = nmalloc(strlen(fragment) + 4);
strcpy(postedname, "...");
strcat(postedname, fragment);
free(fragment);
} else
postedname = display_string(filename, 0, room, FALSE, FALSE);
postedname = crop_to_fit(filename, COLS - breadth(question) - breadth(lockuser) -
breadth(lockprog) - breadth(pidstring) + 7);
/* Allow extra space for username (14), program name (8), PID (8),
* and terminating \0 (1), minus the %s (2) for the file name. */
@@ -360,9 +374,6 @@ bool open_buffer(const char *filename, bool new_one)
{
char *realname;
/* The filename after tilde expansion. */
#ifndef NANO_TINY
char *thelocksname = NULL;
#endif
struct stat fileinfo;
int descriptor = 0;
/* Code 0 means new file, -1 means failure, and else it's the fd. */
@@ -407,23 +418,28 @@ bool open_buffer(const char *filename, bool new_one)
/* When loading into a new buffer, first check the file's path is valid,
* and then (if requested and possible) create a lock file for it. */
if (new_one && has_valid_path(realname)) {
#ifndef NANO_TINY
if (ISSET(LOCKING) && !ISSET(VIEW_MODE) && filename[0] != '\0') {
thelocksname = do_lockfile(realname, TRUE);
/* When not overriding an existing lock, don't open a buffer. */
if (thelocksname == SKIPTHISFILE) {
free(realname);
return FALSE;
}
}
#endif
}
if (new_one)
if (new_one) {
make_new_buffer();
if (has_valid_path(realname)) {
#ifndef NANO_TINY
if (ISSET(LOCKING) && !ISSET(VIEW_MODE) && filename[0] != '\0') {
char *thelocksname = do_lockfile(realname, TRUE);
/* When not overriding an existing lock, discard the buffer. */
if (thelocksname == SKIPTHISFILE) {
#ifdef ENABLE_MULTIBUFFER
close_buffer();
#endif
free(realname);
return FALSE;
} else
openfile->lock_filename = thelocksname;
}
#endif /* NANO_TINY */
}
}
/* If we have a filename and are not in NOREAD mode, open the file. */
if (filename[0] != '\0' && !ISSET(NOREAD_MODE))
descriptor = open_file(realname, new_one, &f);
@@ -442,13 +458,9 @@ bool open_buffer(const char *filename, bool new_one)
#endif
}
/* When we've loaded a file into a new buffer, set the filename
* and put the cursor at the start of the buffer. */
/* For a new buffer, store filename and put cursor at start of buffer. */
if (descriptor >= 0 && new_one) {
openfile->filename = mallocstrcpy(openfile->filename, realname);
#ifndef NANO_TINY
openfile->lock_filename = thelocksname;
#endif
openfile->current = openfile->filetop;
openfile->current_x = 0;
openfile->placewewant = 0;
@@ -459,6 +471,7 @@ bool open_buffer(const char *filename, bool new_one)
if (new_one)
find_and_prime_applicable_syntax();
#endif
free(realname);
return TRUE;
}
@@ -488,7 +501,8 @@ void prepare_for_display(void)
#ifdef ENABLE_COLOR
/* Precalculate the data for any multiline coloring regexes. */
precalc_multicolorinfo();
if (!openfile->filetop->multidata)
precalc_multicolorinfo();
have_palette = FALSE;
#endif
refresh_needed = TRUE;
@@ -500,8 +514,14 @@ void mention_name_and_linecount(void)
{
size_t count = openfile->filebot->lineno -
(openfile->filebot->data[0] == '\0' ? 1 : 0);
#ifndef NANO_TINY
if (openfile->fmt != NIX_FILE)
if (ISSET(MINIBAR)) {
report_size = TRUE;
return;
}
if (openfile->fmt > NIX_FILE)
/* TRANSLATORS: First %s is file name, second %s is file format. */
statusline(HUSH, P_("%s -- %zu line (%s)", "%s -- %zu lines (%s)", count),
openfile->filename[0] == '\0' ?
@@ -519,15 +539,13 @@ void redecorate_after_switch(void)
{
/* If only one file buffer is open, there is nothing to update. */
if (openfile == openfile->next) {
statusbar(_("No more open file buffers"));
statusline(AHEM, _("No more open file buffers"));
return;
}
#ifndef NANO_TINY
/* While in a different buffer, the effective width of the screen may
* have changed, so make sure that the softwrapped chunks per line and
* the starting column for the first row get corresponding values. */
compute_the_extra_rows_per_line_from(openfile->filetop);
/* While in a different buffer, the width of the screen may have changed,
* so make sure that the starting column for the first row is fitting. */
ensure_firstcolumn_is_aligned();
#endif
@@ -540,6 +558,11 @@ void redecorate_after_switch(void)
/* Prevent a possible Shift selection from getting cancelled. */
shift_held = TRUE;
if (openfile->errormessage) {
statusline(ALERT, openfile->errormessage);
free(openfile->errormessage);
openfile->errormessage = NULL;
} else
/* Indicate on the status bar where we switched to. */
mention_name_and_linecount();
}
@@ -577,12 +600,16 @@ void close_buffer(void)
/* Free the undo stack. */
discard_until(NULL);
#endif
free(orphan->errormessage);
openfile = orphan->prev;
if (openfile == orphan)
openfile = NULL;
free(orphan);
/* When just one buffer remains open, show "Exit" in the help lines. */
if (openfile == openfile->next)
if (openfile && openfile == openfile->next)
exitfunc->desc = exit_tag;
}
#endif /* ENABLE_MULTIBUFFER */
@@ -628,11 +655,9 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
bool writable = TRUE;
/* Whether the file is writable (in case we care). */
#ifndef NANO_TINY
int format = 0;
/* 0 = Unix, 1 = DOS, 2 = Mac. */
#endif
format_type format = NIX_FILE;
/* The type of line ending the file uses: Unix, DOS, or Mac. */
#ifndef NANO_TINY
if (undoable)
add_undo(INSERT, NULL);
@@ -661,20 +686,20 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
if (control_C_was_pressed)
break;
/* When the byte before the current one is a CR and we're doing
* format conversion, then strip this CR when it's before a LF
* OR when the file is in Mac format. Also, when still on the
* first line, set the format to either DOS (1) or Mac (2). */
/* When the byte before the current one is a CR and automatic format
* conversion has not been switched off, then strip this CR when it's
* before a LF OR when the file is in Mac format. Also, when this is
* the first line break, make a note of the format. */
if (input == '\n') {
#ifndef NANO_TINY
if (len > 0 && buf[len - 1] == '\r' && !ISSET(NO_CONVERT)) {
if (num_lines == 0)
format = 1;
format = DOS_FILE;
len--;
}
} else if ((num_lines == 0 || format == 2) &&
} else if ((num_lines == 0 || format == MAC_FILE) &&
len > 0 && buf[len - 1] == '\r' && !ISSET(NO_CONVERT)) {
format = 2;
format = MAC_FILE;
len--;
#endif
} else {
@@ -722,7 +747,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
/* When reading from stdin, restore the terminal and reenter curses mode. */
if (isendwin()) {
if (!isatty(STANDARD_INPUT))
if (!isatty(STDIN_FILENO))
reconnect_and_store_state();
terminal_init();
doupdate();
@@ -741,7 +766,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
if (fd > 0 && !undoable && !ISSET(VIEW_MODE))
writable = (access(filename, W_OK) == 0);
/* If the file ended with newline, or it was entirely empty, make the
/* If the file ended with a newline, or it was entirely empty, make the
* last line blank. Otherwise, put the last read data in. */
if (len == 0)
bottomline->data = copy_of("");
@@ -753,7 +778,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
* strip this CR and indicate that an extra blank line is needed. */
if (buf[len - 1] == '\r' && !ISSET(NO_CONVERT)) {
if (num_lines == 0)
format = 2;
format = MAC_FILE;
buf[--len] = '\0';
mac_line_needs_newline = TRUE;
}
@@ -782,18 +807,15 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
if (!writable)
statusline(ALERT, _("File '%s' is unwritable"), filename);
#ifndef NANO_TINY
else if (format == 2) {
else if (format == MAC_FILE)
/* TRANSLATORS: Keep the next three messages at most 78 characters. */
openfile->fmt = MAC_FILE;
statusline(HUSH, P_("Read %zu line (Converted from Mac format)",
"Read %zu lines (Converted from Mac format)",
num_lines), num_lines);
} else if (format == 1) {
openfile->fmt = DOS_FILE;
else if (format == DOS_FILE)
statusline(HUSH, P_("Read %zu line (Converted from DOS format)",
"Read %zu lines (Converted from DOS format)",
num_lines), num_lines);
}
#endif
else
statusline(HUSH, P_("Read %zu line", "Read %zu lines",
@@ -802,6 +824,10 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
/* If we inserted less than a screenful, don't center the cursor. */
if (undoable && less_than_a_screenful(was_lineno, was_leftedge))
focusing = FALSE;
#ifdef ENABLE_COLOR
else if (undoable)
precalc_multicolorinfo();
#endif
#ifndef NANO_TINY
if (undoable)
@@ -809,6 +835,8 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
if (ISSET(MAKE_IT_UNIX))
openfile->fmt = NIX_FILE;
else if (openfile->fmt == UNSPECIFIED)
openfile->fmt = format;
#endif
}
@@ -831,7 +859,7 @@ int open_file(const char *filename, bool new_one, FILE **f)
free(full_filename);
if (new_one) {
statusbar(_("New File"));
statusline(REMARK, _("New File"));
return 0;
} else {
statusline(ALERT, _("File \"%s\" not found"), filename);
@@ -966,13 +994,16 @@ bool execute_command(const char *command)
close(from_fd[0]);
/* Connect the write end of the output pipe to the process' output streams. */
dup2(from_fd[1], fileno(stdout));
dup2(from_fd[1], fileno(stderr));
if (dup2(from_fd[1], STDOUT_FILENO) < 0)
exit(3);
if (dup2(from_fd[1], STDERR_FILENO) < 0)
exit(4);
/* If the parent sends text, connect the read end of the
* feeding pipe to the child's input stream. */
if (should_pipe) {
dup2(to_fd[0], fileno(stdin));
if (dup2(to_fd[0], STDIN_FILENO) < 0)
exit(5);
close(to_fd[1]);
}
@@ -980,7 +1011,7 @@ bool execute_command(const char *command)
execl(theshell, tail(theshell), "-c", should_pipe ? &command[1] : command, NULL);
/* If the exec call returns, there was an error. */
exit(1);
exit(6);
}
/* Parent: close the unused write end of the pipe. */
@@ -1085,9 +1116,6 @@ void do_insertfile(bool execute)
#ifdef ENABLE_MULTIBUFFER
bool was_multibuffer = ISSET(MULTIBUFFER);
#endif
#ifndef NANO_TINY
format_type was_fmt = openfile->fmt;
#endif
/* Display newlines in filenames as ^J. */
as_an_at = FALSE;
@@ -1255,12 +1283,9 @@ void do_insertfile(bool execute)
{
/* If the file actually changed, mark it as modified. */
if (openfile->current->lineno != was_current_lineno ||
openfile->current_x != was_current_x)
openfile->current_x != was_current_x)
set_modified();
#ifndef NANO_TINY
/* Ensure that the buffer retains the format that it had. */
openfile->fmt = was_fmt;
#endif
refresh_needed = TRUE;
}
@@ -1978,8 +2003,13 @@ bool write_file(const char *name, FILE *thefile, bool tmp,
titlebar(NULL);
}
#ifndef NANO_TINY
if (ISSET(MINIBAR) && LINES > 1 && fullbuffer && !tmp)
report_size = TRUE;
else
#endif
if (!tmp)
statusline(HUSH, P_("Wrote %zu line", "Wrote %zu lines",
statusline(REMARK, P_("Wrote %zu line", "Wrote %zu lines",
lineswritten), lineswritten);
retval = TRUE;
@@ -2043,12 +2073,11 @@ bool write_marked_file(const char *name, FILE *stream, bool tmp,
* the buffer is to be discarded. */
int do_writeout(bool exiting, bool withprompt)
{
bool result = FALSE;
kind_of_writing_type method = OVERWRITE;
char *given;
/* The filename we offer, or what the user typed so far. */
bool maychange = (openfile->filename[0] == '\0');
/* Whether it's okay to save the file under a different name. */
kind_of_writing_type method = OVERWRITE;
#ifdef ENABLE_EXTRA
static bool did_credits = FALSE;
#endif
@@ -2105,7 +2134,8 @@ int do_writeout(bool exiting, bool withprompt)
if (response < 0) {
statusbar(_("Cancelled"));
break;
free(given);
return 0;
}
func = func_from_key(&response);
@@ -2147,9 +2177,8 @@ int do_writeout(bool exiting, bool withprompt)
continue;
}
#endif
if (func == do_help) {
if (func == do_help)
continue;
}
#ifdef ENABLE_EXTRA
/* If the user pressed Ctrl-X in the edit window, and answered "Y" at
@@ -2162,8 +2191,10 @@ int do_writeout(bool exiting, bool withprompt)
did_credits = TRUE;
} else
/* TRANSLATORS: Concisely say the screen is too small. */
statusbar(_("Too tiny"));
break;
statusline(AHEM, _("Too tiny"));
free(given);
return 0;
}
#endif
@@ -2176,6 +2207,7 @@ int do_writeout(bool exiting, bool withprompt)
full_filename = get_full_path(openfile->filename);
name_exists = (stat((full_answer == NULL) ?
answer : full_answer, &st) != -1);
if (openfile->filename[0] == '\0')
do_warning = name_exists;
else
@@ -2211,10 +2243,8 @@ int do_writeout(bool exiting, bool withprompt)
if (name_exists) {
char *question = _("File \"%s\" exists; OVERWRITE? ");
char *name = display_string(answer, 0,
COLS - breadth(question) + 1, FALSE, FALSE);
char *message = nmalloc(strlen(question) +
strlen(name) + 1);
char *name = crop_to_fit(answer, COLS - breadth(question) + 1);
char *message = nmalloc(strlen(question) + strlen(name) + 1);
sprintf(message, question, name);
@@ -2262,23 +2292,19 @@ int do_writeout(bool exiting, bool withprompt)
#endif
}
/* Here's where we allow the selected text to be written to
* a separate file. If we're using restricted mode, this
* function is disabled, since it allows reading from or
* writing to files not specified on the command line. */
#ifndef NANO_TINY
if (openfile->mark && !exiting && withprompt && !ISSET(RESTRICTED))
result = write_marked_file(answer, NULL, FALSE, method);
else
#endif
result = write_file(answer, NULL, FALSE, method, TRUE);
free(given);
break;
}
free(given);
return result ? 1 : 0;
/* When the mark is on (and we've prompted for a name and we're
* not exiting and we're not in restricted mode), then write out
* the marked region; otherwise, write out the whole buffer. */
#ifndef NANO_TINY
if (openfile->mark && withprompt && !exiting && !ISSET(RESTRICTED))
return write_marked_file(answer, NULL, FALSE, method);
else
#endif
return write_file(answer, NULL, FALSE, method, TRUE);
}
/* Write the current buffer to disk, or discard it. */

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* global.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2014-2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@@ -49,7 +49,8 @@ bool we_are_running = FALSE;
/* Becomes TRUE as soon as all options and files have been read. */
bool more_than_one = FALSE;
/* Whether more than one buffer is or has been open. */
bool report_size = TRUE;
/* Whether to show the number of lines when the minibar is used. */
bool ran_a_tool = FALSE;
/* Whether a tool has been run at the Execute-Command prompt. */
@@ -79,6 +80,8 @@ linestruct *pletion_line = NULL;
bool also_the_last = FALSE;
/* Whether indenting/commenting should include the last line of
* the marked region. */
bool hide_cursor = FALSE;
/* Whether to suppress the cursor when highlighting a search match. */
char *answer = NULL;
/* The answer string used by the status-bar prompt. */
@@ -381,7 +384,7 @@ int keycode_from_string(const char *keystring)
{
if (keystring[0] == '^') {
if (keystring[2] == '\0') {
if (keystring[1] == '/')
if (keystring[1] == '/' || keystring[1] == '-')
return 31;
if (keystring[1] <= '_')
return keystring[1] - 64;
@@ -477,7 +480,8 @@ size_t shown_entries_for(int menu)
}
/* When --saveonexit is not used, widen the grid of the WriteOut menu. */
if (menu == MWRITEFILE && first_sc_for(menu, discard_buffer) == NULL)
if (menu == MWRITEFILE && item == NULL &&
first_sc_for(menu, discard_buffer) == NULL)
count--;
return count;
@@ -529,6 +533,7 @@ functionptrtype interpret(int *keycode)
return do_findnext;
switch (tolower(*keycode)) {
case 'b':
case '-':
return do_page_up;
case ' ':
@@ -771,7 +776,7 @@ void shortcut_init(void)
CAN_OPEN_OTHER_BUFFER);
#ifdef ENABLE_JUSTIFY
else
add_to_funcs(do_justify_void, MMAIN,
add_to_funcs(do_justify, MMAIN,
N_("Justify"), WITHORSANS(justify_gist), BLANKAFTER, NOVIEW);
#endif
@@ -810,7 +815,7 @@ void shortcut_init(void)
N_("Execute"), WITHORSANS(execute_gist), TOGETHER, NOVIEW);
#endif
#ifdef ENABLE_JUSTIFY
add_to_funcs(do_justify_void, MMAIN,
add_to_funcs(do_justify, MMAIN,
N_("Justify"), WITHORSANS(justify_gist), BLANKAFTER, NOVIEW);
#endif
}
@@ -836,7 +841,7 @@ void shortcut_init(void)
add_to_funcs(do_mark, MMAIN,
N_("Set Mark"), WITHORSANS(mark_gist), TOGETHER, VIEW);
add_to_funcs(copy_text, MMAIN,
N_("Copy"), WITHORSANS(copy_gist), BLANKAFTER, NOVIEW);
N_("Copy"), WITHORSANS(copy_gist), BLANKAFTER, VIEW);
#endif
add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
@@ -944,7 +949,7 @@ void shortcut_init(void)
N_("Next Block"), WITHORSANS(nextblock_gist), TOGETHER, VIEW);
#ifdef ENABLE_JUSTIFY
add_to_funcs(to_para_begin, MMAIN|MGOTOLINE,
/* TRANSLATORS: Try to keep these two strings at most 15 characters. */
/* TRANSLATORS: Try to keep these two strings at most 16 characters. */
N_("Begin of Paragr."), WITHORSANS(parabegin_gist), TOGETHER, VIEW);
add_to_funcs(to_para_end, MMAIN|MGOTOLINE,
N_("End of Paragraph"), WITHORSANS(paraend_gist), BLANKAFTER, VIEW);
@@ -1187,6 +1192,12 @@ void shortcut_init(void)
N_("Next Linter message"), WITHORSANS(nextlint_gist), TOGETHER, VIEW);
#endif
#ifdef __linux__
#define SLASH_OR_DASH (on_a_vt) ? "^-" : "^/"
#else
#define SLASH_OR_DASH "^/"
#endif
/* Link key combos to functions in certain menus. */
add_to_sclist(MMOST|MBROWSER, "^M", '\r', do_enter, 0);
add_to_sclist(MMOST|MBROWSER, "Enter", KEY_ENTER, do_enter, 0);
@@ -1215,7 +1226,7 @@ void shortcut_init(void)
add_to_sclist(MMAIN, "^T", 0, do_execute, 0);
#endif
#ifdef ENABLE_JUSTIFY
add_to_sclist(MMAIN, "^J", '\n', do_justify_void, 0);
add_to_sclist(MMAIN, "^J", '\n', do_justify, 0);
#endif
#ifdef ENABLE_SPELLER
add_to_sclist(MEXECUTE, "^S", 0, do_spell, 0);
@@ -1228,8 +1239,9 @@ void shortcut_init(void)
add_to_sclist(MEXECUTE, "^O", 0, do_formatter, 0);
#endif
add_to_sclist(MMAIN, "^C", 0, report_cursor_position, 0);
add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN, SLASH_OR_DASH, 0, do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN, "M-G", 0, do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "^Y", 0, do_page_up, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "PgUp", KEY_PPAGE, do_page_up, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "^V", 0, do_page_down, 0);
@@ -1281,14 +1293,14 @@ void shortcut_init(void)
add_to_sclist(MMOST|MBROWSER, "^F", 0, do_right, 0);
#ifdef ENABLE_UTF8
if (using_utf8()) {
add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x97\x80", KEY_LEFT, do_left, 0);
add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x96\xb6", KEY_RIGHT, do_right, 0);
add_to_sclist(MSOME, "^\xE2\x97\x80", CONTROL_LEFT, to_prev_word, 0);
add_to_sclist(MSOME, "^\xE2\x96\xb6", CONTROL_RIGHT, to_next_word, 0);
add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x97\x82", KEY_LEFT, do_left, 0);
add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x96\xb8", KEY_RIGHT, do_right, 0);
add_to_sclist(MSOME, "^\xE2\x97\x82", CONTROL_LEFT, to_prev_word, 0);
add_to_sclist(MSOME, "^\xE2\x96\xb8", CONTROL_RIGHT, to_next_word, 0);
#if !defined(NANO_TINY) && defined(ENABLE_MULTIBUFFER)
if (!on_a_vt) {
add_to_sclist(MMAIN, "M-\xE2\x97\x80", ALT_LEFT, switch_to_prev_buffer, 0);
add_to_sclist(MMAIN, "M-\xE2\x96\xb6", ALT_RIGHT, switch_to_next_buffer, 0);
add_to_sclist(MMAIN, "M-\xE2\x97\x82", ALT_LEFT, switch_to_prev_buffer, 0);
add_to_sclist(MMAIN, "M-\xE2\x96\xb8", ALT_RIGHT, switch_to_next_buffer, 0);
}
#endif
} else
@@ -1315,10 +1327,10 @@ void shortcut_init(void)
add_to_sclist(MMAIN|MBROWSER|MHELP, "^N", 0, do_down, 0);
#ifdef ENABLE_UTF8
if (using_utf8()) {
add_to_sclist(MMAIN|MBROWSER|MHELP, "\xE2\x96\xb2", KEY_UP, do_up, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "\xE2\x96\xbc", KEY_DOWN, do_down, 0);
add_to_sclist(MMAIN|MBROWSER|MLINTER, "^\xE2\x96\xb2", CONTROL_UP, to_prev_block, 0);
add_to_sclist(MMAIN|MBROWSER|MLINTER, "^\xE2\x96\xbc", CONTROL_DOWN, to_next_block, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "\xE2\x96\xb4", KEY_UP, do_up, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "\xE2\x96\xbe", KEY_DOWN, do_down, 0);
add_to_sclist(MMAIN|MBROWSER|MLINTER, "^\xE2\x96\xb4", CONTROL_UP, to_prev_block, 0);
add_to_sclist(MMAIN|MBROWSER|MLINTER, "^\xE2\x96\xbe", CONTROL_DOWN, to_next_block, 0);
} else
#endif
{
@@ -1338,8 +1350,8 @@ void shortcut_init(void)
#ifndef NANO_TINY
#ifdef ENABLE_UTF8
if (using_utf8()) {
add_to_sclist(MMAIN|MHELP, "M-\xE2\x96\xb2", ALT_UP, do_scroll_up, 0);
add_to_sclist(MMAIN|MHELP, "M-\xE2\x96\xbc", ALT_DOWN, do_scroll_down, 0);
add_to_sclist(MMAIN|MHELP, "M-\xE2\x96\xb4", ALT_UP, do_scroll_up, 0);
add_to_sclist(MMAIN|MHELP, "M-\xE2\x96\xbe", ALT_DOWN, do_scroll_down, 0);
} else
#endif
{
@@ -1423,8 +1435,8 @@ void shortcut_init(void)
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "^N", 0, get_history_newer_void, 0);
#ifdef ENABLE_UTF8
if (using_utf8()) {
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "\xE2\x96\xb2", KEY_UP, get_history_older_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "\xE2\x96\xbc", KEY_DOWN, get_history_newer_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "\xE2\x96\xb4", KEY_UP, get_history_older_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "\xE2\x96\xbe", KEY_DOWN, get_history_newer_void, 0);
} else
#endif
{
@@ -1450,8 +1462,9 @@ void shortcut_init(void)
add_to_sclist(MBROWSER, "End", KEY_END, to_last_file, 0);
add_to_sclist(MBROWSER, "^Home", CONTROL_HOME, to_first_file, 0);
add_to_sclist(MBROWSER, "^End", CONTROL_END, to_last_file, 0);
add_to_sclist(MBROWSER, "^_", 0, goto_dir, 0);
add_to_sclist(MBROWSER, SLASH_OR_DASH, 0, goto_dir, 0);
add_to_sclist(MBROWSER, "M-G", 0, goto_dir, 0);
add_to_sclist(MBROWSER, "^_", 0, goto_dir, 0);
#endif
if (ISSET(SAVE_ON_EXIT) && !ISSET(PRESERVE))
add_to_sclist(MWRITEFILE, "^Q", 0, discard_buffer, 0);
@@ -1501,7 +1514,7 @@ void shortcut_init(void)
add_to_sclist(MMAIN|MBROWSER|MHELP, "F2", KEY_F(2), do_exit, 0);
add_to_sclist(MMAIN, "F3", KEY_F(3), do_writeout_void, 0);
#ifdef ENABLE_JUSTIFY
add_to_sclist(MMAIN, "F4", KEY_F(4), do_justify_void, 0);
add_to_sclist(MMAIN, "F4", KEY_F(4), do_justify, 0);
#endif
add_to_sclist(MMAIN, "F5", KEY_F(5), do_insertfile_void, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "F6", KEY_F(6), do_search_forward, 0);

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* help.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2000-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 2000-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2017 Rishabh Dave *
* Copyright (C) 2014-2019 Benno Schulenberg *
* *
@@ -50,7 +50,7 @@ void help_init(void)
char *ptr;
/* First, set up the initial help text for the current function. */
if (currmenu == MWHEREIS || currmenu == MREPLACE || currmenu == MREPLACEWITH) {
if (currmenu & (MWHEREIS|MREPLACE|MREPLACEWITH)) {
htx[0] = N_("Search Command Help Text\n\n "
"Enter the words or characters you would like to "
"search for, and then press Enter. If there is a "
@@ -457,9 +457,13 @@ void show_help(void)
/* Show the cursor when we searched and found something. */
kbinput = get_kbinput(edit, didfind == 1 || ISSET(SHOW_CURSOR));
didfind = 0;
#ifndef NANO_TINY
spotlighted = FALSE;
hide_cursor = FALSE;
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) {
beep();
continue;
@@ -548,7 +552,7 @@ void show_help(void)
}
#ifdef ENABLE_BROWSER
if (oldmenu == MBROWSER || oldmenu == MWHEREISFILE || oldmenu == MGOTODIR)
if (oldmenu & (MBROWSER|MWHEREISFILE|MGOTODIR))
browser_refresh();
else
#endif
@@ -566,7 +570,7 @@ void do_help(void)
#ifdef ENABLE_HELP
show_help();
#else
if (currmenu == MMAIN || currmenu == MBROWSER)
if (currmenu & (MMAIN|MBROWSER))
statusbar(_("^W = Ctrl+W M-W = Alt+W"));
else
beep();

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* history.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2003-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 2003-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2016, 2017, 2019 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* move.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2014-2018 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@@ -291,6 +291,10 @@ void do_prev_word(bool allow_punct)
/* If at the head of a line now, this surely is a word start. */
if (openfile->current_x == 0)
break;
#ifdef ENABLE_UTF8
} else if (is_zerowidth(openfile->current->data + openfile->current_x)) {
; /* skip */
#endif
} else if (seen_a_word) {
/* This is space now: we've overshot the start of the word. */
step_forward = TRUE;
@@ -339,11 +343,20 @@ bool do_next_word(bool after_ends, bool allow_punct)
if (is_word_char(openfile->current->data + openfile->current_x,
allow_punct))
seen_word = TRUE;
#ifdef ENABLE_UTF8
else if (is_zerowidth(openfile->current->data + openfile->current_x))
; /* skip */
#endif
else if (seen_word)
break;
} else
#endif
{
#ifdef ENABLE_UTF8
if (is_zerowidth(openfile->current->data + openfile->current_x))
; /* skip */
else
#endif
/* If this is not a word character, then it's a separator; else
* if we've already seen a separator, then it's a word start. */
if (!is_word_char(openfile->current->data + openfile->current_x,
@@ -581,10 +594,16 @@ void do_left(void)
{
linestruct *was_current = openfile->current;
if (openfile->current_x > 0)
if (openfile->current_x > 0) {
openfile->current_x = step_left(openfile->current->data,
openfile->current_x);
else if (openfile->current != openfile->filetop) {
#ifdef ENABLE_UTF8
while (openfile->current_x > 0 &&
is_zerowidth(openfile->current->data + openfile->current_x))
openfile->current_x = step_left(openfile->current->data,
openfile->current_x);
#endif
} else if (openfile->current != openfile->filetop) {
openfile->current = openfile->current->prev;
openfile->current_x = strlen(openfile->current->data);
}
@@ -597,10 +616,16 @@ void do_right(void)
{
linestruct *was_current = openfile->current;
if (openfile->current->data[openfile->current_x] != '\0')
if (openfile->current->data[openfile->current_x] != '\0') {
openfile->current_x = step_right(openfile->current->data,
openfile->current_x);
else if (openfile->current != openfile->filebot) {
#ifdef ENABLE_UTF8
while (openfile->current->data[openfile->current_x] != '\0' &&
is_zerowidth(openfile->current->data + openfile->current_x))
openfile->current_x = step_right(openfile->current->data,
openfile->current_x);
#endif
} else if (openfile->current != openfile->filebot) {
openfile->current = openfile->current->next;
openfile->current_x = 0;
}

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* nano.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2014-2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@@ -62,10 +62,6 @@ static struct termios original_state;
static struct sigaction oldaction, newaction;
/* Containers for the original and the temporary handler for SIGINT. */
#ifdef USE_SLANG
static bool selfinduced = FALSE;
/* Whether a suspension was caused from inside nano or from outside. */
#endif
/* Create a new linestruct node. Note that we do not set prevnode->next. */
linestruct *make_new_node(linestruct *prevnode)
@@ -80,7 +76,6 @@ linestruct *make_new_node(linestruct *prevnode)
#endif
newnode->lineno = (prevnode) ? prevnode->lineno + 1 : 1;
#ifndef NANO_TINY
newnode->extrarows = -2; /* Bad value, to make it easier to find bugs. */
newnode->has_anchor = FALSE;
#endif
@@ -104,6 +99,9 @@ void splice_node(linestruct *afterthis, linestruct *newnode)
/* Free the data structures in the given node. */
void delete_node(linestruct *line)
{
/* If the first line on the screen gets deleted, step one back. */
if (line == openfile->edittop)
openfile->edittop = line->prev;
#ifdef ENABLE_WRAPPING
/* If the spill-over line for hard-wrapping is deleted... */
if (line == openfile->spillage_line)
@@ -156,7 +154,6 @@ linestruct *copy_node(const linestruct *src)
#endif
dst->lineno = src->lineno;
#ifndef NANO_TINY
dst->extrarows = src->extrarows;
dst->has_anchor = FALSE;
#endif
@@ -201,14 +198,14 @@ void renumber_from(linestruct *line)
/* Display a warning about a key disabled in view mode. */
void print_view_warning(void)
{
statusbar(_("Key is invalid in view mode"));
statusline(AHEM, _("Key is invalid in view mode"));
}
/* When in restricted mode, show a warning and return TRUE. */
bool in_restricted_mode(void)
{
if (ISSET(RESTRICTED)) {
statusbar(_("This function is disabled in restricted mode"));
statusline(AHEM, _("This function is disabled in restricted mode"));
beep();
return TRUE;
} else
@@ -225,7 +222,7 @@ void restore_terminal(void)
printf("\x1B[?2004l");
fflush(stdout);
#endif
tcsetattr(0, TCSANOW, &original_state);
tcsetattr(STDIN_FILENO, TCSANOW, &original_state);
}
/* Exit normally: restore terminal state and report any startup errors. */
@@ -399,22 +396,28 @@ void window_init(void)
delwin(bottomwin);
}
topwin = NULL;
/* If the terminal is very flat, don't set up a title bar. */
if (LINES < 3) {
topwin = NULL;
editwinrows = 1;
/* Set up two subwindows. If the terminal is just one line,
* edit window and status-bar window will cover each other. */
edit = newwin(1, COLS, 0, 0);
bottomwin = newwin(1, COLS, LINES - 1, 0);
} else {
int toprows = (!ISSET(EMPTY_LINE) ? 1 : (LINES < 6) ? 1 : 2);
int bottomrows = (ISSET(NO_HELP) ? 1 : (LINES < 5) ? 1 : 3);
int toprows = ((ISSET(EMPTY_LINE) && LINES > 5) ? 2 : 1);
int bottomrows = ((ISSET(NO_HELP) || LINES < 5) ? 1 : 3);
#ifndef NANO_TINY
if (ISSET(MINIBAR))
toprows = 0;
#endif
editwinrows = LINES - toprows - bottomrows;
/* Set up the normal three subwindows. */
topwin = newwin(toprows, COLS, 0, 0);
if (toprows > 0)
topwin = newwin(toprows, COLS, 0, 0);
edit = newwin(editwinrows, COLS, toprows, 0);
bottomwin = newwin(bottomrows, COLS, toprows + editwinrows, 0);
}
@@ -422,13 +425,11 @@ void window_init(void)
/* In case the terminal shrunk, make sure the status line is clear. */
wipe_statusbar();
#ifndef USE_SLANG
/* When not disabled, turn escape-sequence translation on. */
if (!ISSET(RAW_SEQUENCES)) {
keypad(edit, TRUE);
keypad(bottomwin, TRUE);
}
#endif
#ifdef ENABLED_WRAPORJUSTIFY
/* Set up the wrapping point, accounting for screen width when negative. */
@@ -526,10 +527,8 @@ void usage(void)
print_opt(_("-J <number>"), _("--guidestripe=<number>"),
N_("Show a guiding bar at this column"));
#endif
#ifndef USE_SLANG
print_opt("-K", "--rawsequences",
N_("Fix numeric keypad key confusion problem"));
#endif
#ifndef NANO_TINY
print_opt("-L", "--nonewlines",
N_("Don't add an automatic newline"));
@@ -643,6 +642,7 @@ void usage(void)
print_opt("-z", "--suspendable", N_("Enable suspension"));
#ifndef NANO_TINY
print_opt("-%", "--stateflags", N_("Show some states on the title bar"));
print_opt("-_", "--minibar", N_("Show a feedback bar at the bottom"));
#endif
#ifdef HAVE_LIBMAGIC
print_opt("-!", "--magic", N_("Also try magic to determine syntax"));
@@ -659,8 +659,8 @@ void version(void)
printf(_(" GNU nano, version %s\n"), VERSION);
#endif
#ifndef NANO_TINY
printf(" (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.\n");
printf(_(" (C) 2014-%s the contributors to nano\n"), "2020");
printf(" (C) 1999-2011, 2013-2021 Free Software Foundation, Inc.\n");
printf(_(" (C) 2014-%s the contributors to nano\n"), "2021");
#endif
printf(_(" Compiled options:"));
@@ -775,9 +775,6 @@ void version(void)
printf(" --enable-utf8");
#else
printf(" --disable-utf8");
#endif
#ifdef USE_SLANG
printf(" --with-slang");
#endif
printf("\n");
}
@@ -813,15 +810,14 @@ void reconnect_and_store_state(void)
{
int thetty = open("/dev/tty", O_RDONLY);
if (thetty < 1)
if (thetty < 0 || dup2(thetty, STDIN_FILENO) < 0)
die(_("Could not reconnect stdin to keyboard\n"));
dup2(thetty, STANDARD_INPUT);
close(thetty);
/* If input was not cut short, store the current state of the terminal. */
if (!control_C_was_pressed)
tcgetattr(0, &original_state);
tcgetattr(STDIN_FILENO, &original_state);
}
/* Read whatever comes from standard input into a new buffer. */
@@ -832,7 +828,7 @@ bool scoop_stdin(void)
restore_terminal();
/* When input comes from a terminal, show a helpful message. */
if (isatty(STANDARD_INPUT))
if (isatty(STDIN_FILENO))
fprintf(stderr, _("Reading data from keyboard; "
"type ^D or ^D^D to finish.\n"));
@@ -957,18 +953,11 @@ void do_suspend(int signal)
/* Put nano to sleep (if suspension is enabled). */
void do_suspend_void(void)
{
if (ISSET(SUSPENDABLE)) {
#ifdef USE_SLANG
selfinduced = TRUE;
do_suspend(0);
selfinduced = FALSE;
#else
do_suspend(0);
#endif
} else {
statusbar(_("Suspension is not enabled"));
if (!ISSET(SUSPENDABLE)) {
statusline(AHEM, _("Suspension is not enabled"));
beep();
}
} else
do_suspend(0);
ran_a_tool = TRUE;
}
@@ -988,13 +977,9 @@ void do_continue(int signal)
/* Put the terminal in the desired state again. */
terminal_init();
#endif
#ifdef USE_SLANG
if (!selfinduced)
full_refresh();
#else
/* Insert a fake keystroke, to neutralize a key-eating issue. */
ungetch(KEY_FLUSH);
#endif
}
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER) || defined(ENABLE_COLOR)
@@ -1022,14 +1007,6 @@ void handle_sigwinch(int signal)
the_window_resized = TRUE;
}
/* Compute and store how many extra rows each line needs when softwrapping. */
void compute_the_extra_rows_per_line_from(linestruct *fromline)
{
if (ISSET(SOFTWRAP))
for (linestruct *line = fromline; line != NULL; line = line->next)
line->extrarows = extra_chunks_in(line);
}
/* Reinitialize and redraw the screen completely. */
void regenerate_screen(void)
{
@@ -1072,7 +1049,6 @@ void regenerate_screen(void)
/* If we have an open buffer, redraw the contents of the subwindows. */
if (openfile) {
compute_the_extra_rows_per_line_from(openfile->filetop);
ensure_firstcolumn_is_aligned();
draw_all_subwindows();
}
@@ -1081,8 +1057,6 @@ void regenerate_screen(void)
/* Handle the global toggle specified in flag. */
void do_toggle(int flag)
{
bool enabled;
if (flag == SUSPENDABLE && in_restricted_mode())
return;
@@ -1100,9 +1074,7 @@ void do_toggle(int flag)
break;
#endif
case SOFTWRAP:
if (ISSET(SOFTWRAP))
compute_the_extra_rows_per_line_from(openfile->filetop);
else
if (!ISSET(SOFTWRAP))
openfile->firstcolumn = 0;
refresh_needed = TRUE;
break;
@@ -1118,17 +1090,27 @@ void do_toggle(int flag)
#endif
}
if (ISSET(STATEFLAGS) && (flag == AUTOINDENT ||
flag == BREAK_LONG_LINES || flag == SOFTWRAP))
titlebar(NULL);
if (!ISSET(MINIBAR) && ISSET(STATEFLAGS))
if (flag == AUTOINDENT || flag == BREAK_LONG_LINES || flag == SOFTWRAP)
titlebar(NULL);
enabled = ISSET(flag);
if (ISSET(MINIBAR) && (flag == NO_HELP || flag == LINE_NUMBERS ))
return;
if (flag == NO_HELP || flag == NO_SYNTAX)
enabled = !enabled;
if (flag == CONSTANT_SHOW)
wipe_statusbar();
else if (!ISSET(MINIBAR) || !ISSET(STATEFLAGS) || flag == SMART_HOME ||
flag == NO_SYNTAX || flag == WHITESPACE_DISPLAY ||
flag == CUT_FROM_CURSOR || flag == TABS_TO_SPACES ||
flag == USE_MOUSE || flag == SUSPENDABLE) {
bool enabled = ISSET(flag);
statusline(HUSH, "%s %s", _(flagtostr(flag)),
enabled ? _("enabled") : _("disabled"));
if (flag == NO_HELP || flag == NO_SYNTAX)
enabled = !enabled;
statusline(REMARK, "%s %s", _(flagtostr(flag)),
enabled ? _("enabled") : _("disabled"));
}
}
#endif /* !NANO_TINY */
@@ -1203,36 +1185,15 @@ void enable_flow_control(void)
* control characters. */
void terminal_init(void)
{
#ifdef USE_SLANG
/* Slang curses emulation brain damage, part 2: Slang doesn't
* implement raw(), nonl(), or noecho() properly, so there's no way
* to properly reinitialize the terminal using them. We have to
* disable the special control keys and interpretation of the flow
* control characters using termios, save the terminal state after
* the first call, and restore it on subsequent calls. */
static struct termios desired_state;
static bool have_new_state = FALSE;
raw();
nonl();
noecho();
if (!have_new_state) {
#endif
raw();
nonl();
noecho();
disable_extended_io();
#ifdef USE_SLANG
tcgetattr(0, &desired_state);
have_new_state = TRUE;
} else
tcsetattr(0, TCSANOW, &desired_state);
disable_extended_io();
SLang_init_tty(-1, 0, 0);
#endif
if (ISSET(PRESERVE))
enable_flow_control();
#ifdef USE_SLANG
else
disable_flow_control();
#endif
disable_kb_interrupt();
#ifndef NANO_TINY
@@ -1269,14 +1230,15 @@ void confirm_margin(void)
needed_margin = 0;
if (needed_margin != margin) {
bool keep_focus = (margin > 0) && focusing;
margin = needed_margin;
editwincols = COLS - margin - thebar;
#ifndef NANO_TINY
/* Recompute the softwrapped chunks for each line in the buffer,
* and ensure a proper starting column for the first screen row. */
compute_the_extra_rows_per_line_from(openfile->filetop);
/* Ensure a proper starting column for the first screen row. */
ensure_firstcolumn_is_aligned();
focusing = keep_focus;
#endif
/* The margin has changed -- schedule a full refresh. */
refresh_needed = TRUE;
@@ -1290,28 +1252,28 @@ void unbound_key(int code)
if (code == FOREIGN_SEQUENCE)
/* TRANSLATORS: This refers to a sequence of escape codes
* (from the keyboard) that nano does not recognize. */
statusline(ALERT, _("Unknown sequence"));
statusline(AHEM, _("Unknown sequence"));
else if (code > 0x7F)
statusline(ALERT, _("Unbound key"));
statusline(AHEM, _("Unbound key"));
else if (meta_key) {
#ifndef NANO_TINY
if (code < 0x20)
statusline(ALERT, _("Unbindable key: M-^%c"), code + 0x40);
statusline(AHEM, _("Unbindable key: M-^%c"), code + 0x40);
else
#endif
#ifdef ENABLE_NANORC
if (shifted_metas && 'A' <= code && code <= 'Z')
statusline(ALERT, _("Unbound key: Sh-M-%c"), code);
statusline(AHEM, _("Unbound key: Sh-M-%c"), code);
else
#endif
statusline(ALERT, _("Unbound key: M-%c"), toupper(code));
statusline(AHEM, _("Unbound key: M-%c"), toupper(code));
} else if (code == ESC_CODE)
statusline(ALERT, _("Unbindable key: ^["));
statusline(AHEM, _("Unbindable key: ^["));
else if (code < 0x20)
statusline(ALERT, _("Unbound key: ^%c"), code + 0x40);
statusline(AHEM, _("Unbound key: ^%c"), code + 0x40);
#if defined(ENABLE_BROWSER) || defined (ENABLE_HELP)
else
statusline(ALERT, _("Unbound key: %c"), code);
statusline(AHEM, _("Unbound key: %c"), code);
#endif
set_blankdelay_to_one();
}
@@ -1355,9 +1317,11 @@ int do_mouse(void)
#ifndef NANO_TINY
/* Clicking where the cursor is toggles the mark, as does clicking
* beyond the line length with the cursor at the end of the line. */
if (sameline && openfile->current_x == current_x_save)
if (sameline && openfile->current_x == current_x_save) {
do_mark();
else
if (ISSET(STATEFLAGS))
titlebar(NULL);
} else
#endif
/* The cursor moved; clean the cutbuffer on the next cut. */
keep_cutbuffer = FALSE;
@@ -1438,12 +1402,13 @@ void inject(char *burst, size_t count)
linestruct *thisline = openfile->current;
size_t datalen = strlen(thisline->data);
#ifndef NANO_TINY
size_t old_amount = openfile->current->extrarows;
size_t original_row = 0;
size_t old_amount = 0;
if (ISSET(SOFTWRAP)) {
if (openfile->current_y == editwinrows - 1)
original_row = chunk_for(xplustabs(), thisline);
old_amount = extra_chunks_in(thisline);
}
#endif
@@ -1507,14 +1472,11 @@ void inject(char *burst, size_t count)
/* When softwrapping and the number of chunks in the current line changed,
* or we were on the last row of the edit window and moved to a new chunk,
* we need a full refresh. */
if (ISSET(SOFTWRAP)) {
openfile->current->extrarows = extra_chunks_in(openfile->current);
if (openfile->current->extrarows != old_amount ||
if (ISSET(SOFTWRAP) && (extra_chunks_in(openfile->current) != old_amount ||
(openfile->current_y == editwinrows - 1 &&
chunk_for(xplustabs(), openfile->current) > original_row)) {
refresh_needed = TRUE;
focusing = FALSE;
}
chunk_for(xplustabs(), openfile->current) > original_row))) {
refresh_needed = TRUE;
focusing = FALSE;
}
#endif
@@ -1546,6 +1508,9 @@ void process_a_keystroke(void)
/* Read in a keystroke, and show the cursor while waiting. */
input = get_kbinput(edit, VISIBLE);
lastmessage = VACUUM;
hide_cursor = FALSE;
#ifndef NANO_TINY
if (input == KEY_WINCH)
return;
@@ -1572,7 +1537,7 @@ void process_a_keystroke(void)
print_view_warning();
else {
#ifndef NANO_TINY
if (openfile->mark && openfile->kind_of_mark == SOFTMARK) {
if (openfile->mark && openfile->softmark) {
openfile->mark = NULL;
refresh_needed = TRUE;
}
@@ -1646,7 +1611,7 @@ void process_a_keystroke(void)
if (shift_held && !openfile->mark) {
openfile->mark = openfile->current;
openfile->mark_x = openfile->current_x;
openfile->kind_of_mark = SOFTMARK;
openfile->softmark = TRUE;
}
#endif
@@ -1658,7 +1623,7 @@ void process_a_keystroke(void)
* discard a soft mark. And when the marked region covers a
* different set of lines, reset the "last line too" flag. */
if (openfile->mark) {
if (!shift_held && openfile->kind_of_mark == SOFTMARK &&
if (!shift_held && openfile->softmark &&
(openfile->current != was_current ||
openfile->current_x != was_x ||
wanted_to_move(shortcut->func))) {
@@ -1712,9 +1677,7 @@ int main(int argc, char **argv)
#ifdef ENABLE_NANORC
{"ignorercfiles", 0, NULL, 'I'},
#endif
#ifndef USE_SLANG
{"rawsequences", 0, NULL, 'K'},
#endif
#ifdef ENABLED_WRAPORJUSTIFY
{"trimblanks", 0, NULL, 'M'},
#endif
@@ -1790,6 +1753,7 @@ int main(int argc, char **argv)
{"unix", 0, NULL, 'u'},
{"afterends", 0, NULL, 'y'},
{"stateflags", 0, NULL, '%'},
{"minibar", 0, NULL, '_'},
#endif
#ifdef HAVE_LIBMAGIC
{"magic", 0, NULL, '!'},
@@ -1801,27 +1765,22 @@ int main(int argc, char **argv)
struct vt_stat dummy;
/* Check whether we're running on a Linux console. */
on_a_vt = (ioctl(1, VT_GETSTATE, &dummy) == 0);
on_a_vt = (ioctl(STDOUT_FILENO, VT_GETSTATE, &dummy) == 0);
#endif
/* Back up the terminal settings so that they can be restored. */
tcgetattr(0, &original_state);
tcgetattr(STDIN_FILENO, &original_state);
/* Get the state of standard input and ensure it uses blocking mode. */
stdin_flags = fcntl(0, F_GETFL, 0);
stdin_flags = fcntl(STDIN_FILENO, F_GETFL, 0);
if (stdin_flags != -1)
fcntl(0, F_SETFL, stdin_flags & ~O_NONBLOCK);
fcntl(STDIN_FILENO, F_SETFL, stdin_flags & ~O_NONBLOCK);
#ifdef ENABLE_UTF8
/* If setting the locale is successful and it uses UTF-8, we need
* to use the multibyte functions for text processing. */
if (setlocale(LC_ALL, "") != NULL &&
strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
#ifdef USE_SLANG
SLutf8_enable(1);
#endif
/* If setting the locale is successful and it uses UTF-8, we will
* need to use the multibyte functions for text processing. */
if (setlocale(LC_ALL, "") && strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
utf8_init();
}
#else
setlocale(LC_ALL, "");
#endif
@@ -1831,25 +1790,15 @@ int main(int argc, char **argv)
textdomain(PACKAGE);
#endif
#if defined(ENABLE_UTF8) && !defined(NANO_TINY)
if (MB_CUR_MAX > MAXCHARLEN)
fprintf(stderr, "Unexpected large character size: %i bytes"
" -- please report a bug\n", (int)MB_CUR_MAX);
#endif
/* Set sensible defaults, different from what Pico does. */
/* Set a sensible default, different from what Pico does. */
SET(NO_WRAP);
SET(SMOOTH_SCROLL);
/* Give a small visual hint that nano has changed. */
SET(MORE_SPACE);
/* If the executable's name starts with 'r', activate restricted mode. */
if (*(tail(argv[0])) == 'r')
SET(RESTRICTED);
while ((optchr = getopt_long(argc, argv, "ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Z"
"abcdef:ghijklmno:pqr:s:tuvwxyz$?%!", long_options, NULL)) != -1) {
"abcdef:ghijklmno:pqr:s:tuvwxyz$%_!", long_options, NULL)) != -1) {
switch (optchr) {
#ifndef NANO_TINY
case 'A':
@@ -1899,11 +1848,9 @@ int main(int argc, char **argv)
}
break;
#endif
#ifndef USE_SLANG
case 'K':
SET(RAW_SEQUENCES);
break;
#endif
#ifndef NANO_TINY
case 'L':
SET(NO_NEWLINES);
@@ -2002,7 +1949,6 @@ int main(int argc, char **argv)
break;
#endif
case 'h':
case '?':
usage();
exit(0);
#ifndef NANO_TINY
@@ -2092,6 +2038,9 @@ int main(int argc, char **argv)
case '%':
SET(STATEFLAGS);
break;
case '_':
SET(MINIBAR);
break;
#endif
#ifdef HAVE_LIBMAGIC
case '!':
@@ -2197,15 +2146,14 @@ int main(int argc, char **argv)
free(alt_speller);
alt_speller = alt_speller_cmdline;
}
/* Strip leading whitespace from the speller command, if any. */
while (alt_speller && *alt_speller && isblank(*alt_speller))
memmove(alt_speller, alt_speller + 1, strlen(alt_speller));
#endif
/* If an rcfile undid the default settings, copy it to the new flags. */
/* If an rcfile undid the default setting, copy it to the new flag. */
if (!ISSET(NO_WRAP))
SET(BREAK_LONG_LINES);
if (!ISSET(SMOOTH_SCROLL))
SET(JUMPY_SCROLLING);
if (!ISSET(MORE_SPACE))
SET(EMPTY_LINE);
/* Simply OR the boolean flags from rcfile and command line. */
for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); i++)
@@ -2235,15 +2183,9 @@ int main(int argc, char **argv)
#endif
}
#ifdef USE_SLANG
/* When using Slang, do not let Slang translate escape sequences to
* key codes, because it does it wrong for the longer sequences. */
SET(RAW_SEQUENCES);
#else
/* When getting untranslated escape sequences, the mouse cannot be used. */
if (ISSET(RAW_SEQUENCES))
UNSET(USE_MOUSE);
#endif
#ifdef ENABLE_HISTORIES
/* Initialize the pointers for the Search/Replace/Execute histories. */
@@ -2355,6 +2297,9 @@ int main(int argc, char **argv)
interface_color_pair[GUIDE_STRIPE] = A_REVERSE;
interface_color_pair[SCROLL_BAR] = A_NORMAL;
interface_color_pair[SELECTED_TEXT] = hilite_attribute;
interface_color_pair[SPOTLIGHTED] = A_REVERSE;
interface_color_pair[MINI_INFOBAR] = hilite_attribute;
interface_color_pair[PROMPT_BAR] = hilite_attribute;
interface_color_pair[STATUS_BAR] = hilite_attribute;
interface_color_pair[ERROR_MESSAGE] = hilite_attribute;
interface_color_pair[KEY_COMBO] = hilite_attribute;
@@ -2434,9 +2379,9 @@ int main(int argc, char **argv)
#endif
/* If there's a +LINE[,COLUMN] argument here, eat it up. */
if (optind < argc - 1 && argv[optind][0] == '+') {
#ifndef NANO_TINY
int n = 1;
#ifndef NANO_TINY
while (isalpha(argv[optind][n])) {
switch (argv[optind][n++]) {
case 'c': SET(CASE_SENSITIVE); break;
@@ -2459,7 +2404,11 @@ int main(int argc, char **argv)
optind++;
} else
#endif
if (!parse_line_column(&argv[optind++][n], &givenline, &givencol))
/* When there is nothing after the "+", understand it as go-to-EOF,
* otherwise parse and store the given number(s).*/
if (argv[optind++][1] == '\0')
givenline = -1;
else if (!parse_line_column(&argv[optind - 1][1], &givenline, &givencol))
statusline(ALERT, _("Invalid line or column number"));
}
@@ -2485,7 +2434,7 @@ int main(int argc, char **argv)
if (!findnextstr(searchstring, FALSE, JUSTFIND, NULL,
ISSET(BACKWARDS_SEARCH), openfile->filetop, 0))
not_found_msg(searchstring);
else if (lastmessage == HUSH)
else if (lastmessage <= REMARK)
wipe_statusbar();
openfile->placewewant = xplustabs();
if (ISSET(USE_REGEXP))
@@ -2520,6 +2469,9 @@ int main(int argc, char **argv)
if (ISSET(VIEW_MODE))
SET(MULTIBUFFER);
}
#else
if (optind < argc)
die(_("Can open just one file\n"));
#endif
prepare_for_display();
@@ -2527,11 +2479,16 @@ int main(int argc, char **argv)
#ifdef ENABLE_NANORC
if (startup_problem != NULL)
statusline(ALERT, startup_problem);
#define NOTREBOUND first_sc_for(MMAIN, do_help) && \
first_sc_for(MMAIN, do_help)->keycode == 0x07
#else
#define NOTREBOUND TRUE
#endif
#ifdef ENABLE_HELP
if (*openfile->filename == '\0' && openfile->totsize == 0 &&
openfile->next == openfile && !ISSET(NO_HELP))
openfile->next == openfile && !ISSET(NO_HELP) && NOTREBOUND)
statusbar(_("Welcome to nano. For basic help, type Ctrl+G."));
#endif
@@ -2548,19 +2505,24 @@ int main(int argc, char **argv)
if (currmenu != MMAIN)
bottombars(MMAIN);
#ifndef NANO_TINY
if (ISSET(MINIBAR) && LINES > 1 && lastmessage < REMARK)
minibar();
else
#endif
/* Update the displayed current cursor position only when there
* is no message and no keys are waiting in the input buffer. */
if (ISSET(CONSTANT_SHOW) && lastmessage == VACUUM && get_key_buffer_len() == 0)
if (ISSET(CONSTANT_SHOW) && lastmessage == VACUUM && LINES > 1 &&
get_key_buffer_len() == 0)
report_cursor_position();
lastmessage = VACUUM;
as_an_at = TRUE;
/* Refresh just the cursor position or the entire edit window. */
if (!refresh_needed) {
place_the_cursor();
wnoutrefresh(edit);
} else
} else if (LINES > 1 || lastmessage == VACUUM)
edit_refresh();
errno = 0;

View File

@@ -1,8 +1,8 @@
/**************************************************************************
* prompt.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 2016, 2018 Benno Schulenberg *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2016, 2018, 2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -57,9 +57,18 @@ void do_statusbar_next_word(void)
* and if we've already seen a word, then it's a word end. */
if (is_word_char(answer + typing_x, FALSE))
seen_word = TRUE;
#ifdef ENABLE_UTF8
else if (is_zerowidth(answer + typing_x))
; /* skip */
#endif
else if (seen_word)
break;
} else {
#ifdef ENABLE_UTF8
if (is_zerowidth(answer + typing_x))
; /* skip */
else
#endif
/* If this is not a word character, then it's a separator; else
* if we've already seen a separator, then it's a word start. */
if (!is_word_char(answer + typing_x, FALSE))
@@ -81,6 +90,10 @@ void do_statusbar_prev_word(void)
if (is_word_char(answer + typing_x, FALSE))
seen_a_word = TRUE;
#ifdef ENABLE_UTF8
else if (is_zerowidth(answer + typing_x))
; /* skip */
#endif
else if (seen_a_word) {
/* This is space now: we've overshot the start of the word. */
step_forward = TRUE;
@@ -97,15 +110,25 @@ void do_statusbar_prev_word(void)
/* Move left one character in the answer. */
void do_statusbar_left(void)
{
if (typing_x > 0)
if (typing_x > 0) {
typing_x = step_left(answer, typing_x);
#ifdef ENABLE_UTF8
while (typing_x > 0 && is_zerowidth(answer + typing_x))
typing_x = step_left(answer, typing_x);
#endif
}
}
/* Move right one character in the answer. */
void do_statusbar_right(void)
{
if (answer[typing_x] != '\0')
if (answer[typing_x] != '\0') {
typing_x = step_right(answer, typing_x);
#ifdef ENABLE_UTF8
while (answer[typing_x] != '\0' && is_zerowidth(answer + typing_x))
typing_x = step_right(answer, typing_x);
#endif
}
}
/* Delete one character in the answer. */
@@ -116,6 +139,10 @@ void do_statusbar_delete(void)
memmove(answer + typing_x, answer + typing_x + charlen,
strlen(answer) - typing_x - charlen + 1);
#ifdef ENABLE_UTF8
if (is_zerowidth(answer + typing_x))
do_statusbar_delete();
#endif
}
}
@@ -123,8 +150,10 @@ void do_statusbar_delete(void)
void do_statusbar_backspace(void)
{
if (typing_x > 0) {
size_t was_x = typing_x;
typing_x = step_left(answer, typing_x);
do_statusbar_delete();
memmove(answer + typing_x, answer + was_x, strlen(answer) - was_x + 1);
}
}
@@ -351,18 +380,19 @@ void put_cursor_at_end_of_answer(void)
typing_x = HIGHEST_POSITIVE;
}
/* Redraw the promptbar and place the cursor at the right spot. */
/* Redraw the prompt bar and place the cursor at the right spot. */
void draw_the_promptbar(void)
{
size_t base = breadth(prompt) + 2;
size_t the_page, end_page, column;
size_t column = base + wideness(answer, typing_x);
size_t the_page, end_page;
char *expanded;
the_page = get_statusbar_page_start(base, base + wideness(answer, typing_x));
the_page = get_statusbar_page_start(base, column);
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]);
/* Color the prompt bar over its full width. */
wattron(bottomwin, interface_color_pair[PROMPT_BAR]);
mvwprintw(bottomwin, 0, 0, "%*s", COLS, " ");
mvwaddstr(bottomwin, 0, 0, prompt);
@@ -373,18 +403,21 @@ void draw_the_promptbar(void)
waddstr(bottomwin, expanded);
free(expanded);
if (base + breadth(answer) != COLS && the_page < end_page)
if (the_page < end_page && base + breadth(answer) - the_page > COLS)
mvwaddch(bottomwin, 0, COLS - 1, '>');
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
wattroff(bottomwin, interface_color_pair[PROMPT_BAR]);
/* Work around a cursor-misplacement bug in VTEs. */
wmove(bottomwin, 0, 0);
wrefresh(bottomwin);
#if defined(NCURSES_VERSION_PATCH) && (NCURSES_VERSION_PATCH < 20210220)
/* Work around a cursor-misplacement bug -- https://sv.gnu.org/bugs/?59808. */
if (ISSET(NO_HELP)) {
wmove(bottomwin, 0, 0);
wrefresh(bottomwin);
}
#endif
/* Place the cursor at the right spot. */
column = base + wideness(answer, typing_x);
wmove(bottomwin, 0, column - get_statusbar_page_start(base, column));
wmove(bottomwin, 0, column - the_page);
wnoutrefresh(bottomwin);
}
@@ -393,7 +426,7 @@ void draw_the_promptbar(void)
void add_or_remove_pipe_symbol_from_answer(void)
{
if (answer[0] == '|') {
memmove(answer, answer + 1, strlen(answer) + 1);
memmove(answer, answer + 1, strlen(answer));
if (typing_x > 0)
typing_x--;
} else {
@@ -465,8 +498,7 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
} else
#endif
/* Allow tab completion of filenames, but not in restricted mode. */
if ((currmenu == MINSERTFILE || currmenu == MWRITEFILE ||
currmenu == MGOTODIR) && !ISSET(RESTRICTED))
if ((currmenu & (MINSERTFILE|MWRITEFILE|MGOTODIR)) && !ISSET(RESTRICTED))
answer = input_tab(answer, &typing_x, refresh_func, listed);
} else
#endif /* ENABLE_TABCOMP */
@@ -659,11 +691,11 @@ int do_yesno_prompt(bool all, const char *msg)
post_one_key(cancelshortcut->keystr, _("Cancel"), width);
}
/* Color the promptbar over its full width and display the question. */
wattron(bottomwin, interface_color_pair[TITLE_BAR]);
/* Color the prompt bar over its full width and display the question. */
wattron(bottomwin, interface_color_pair[PROMPT_BAR]);
mvwprintw(bottomwin, 0, 0, "%*s", COLS, " ");
mvwaddnstr(bottomwin, 0, 0, msg, actual_x(msg, COLS - 1));
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
wattroff(bottomwin, interface_color_pair[PROMPT_BAR]);
wnoutrefresh(bottomwin);
currmenu = MYESNO;

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* prototypes.h -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -36,7 +36,7 @@ extern bool bracketed_paste;
extern bool we_are_running;
extern bool more_than_one;
extern bool report_size;
extern bool ran_a_tool;
extern bool inhelp;
@@ -53,6 +53,7 @@ extern message_type lastmessage;
extern linestruct *pletion_line;
extern bool also_the_last;
extern bool hide_cursor;
extern char *answer;
@@ -203,8 +204,9 @@ bool is_cntrl_char(const char *c);
bool is_word_char(const char *c, bool allow_punct);
char control_mbrep(const char *c, bool isdata);
#ifdef ENABLE_UTF8
int mbwidth(const char *c);
char *make_mbchar(long code, int *length);
int mbtowide(wchar_t *wc, const char *c);
bool is_doublewidth(const char *ch);
bool is_zerowidth(const char *ch);
#endif
int char_length(const char *pointer);
size_t mbstrlen(const char *pointer);
@@ -228,16 +230,12 @@ char *mbrevstrpbrk(const char *head, const char *accept, const char *pointer);
bool has_blank_char(const char *string);
#endif
bool white_string(const char *string);
#ifdef ENABLE_UTF8
bool is_valid_unicode(wchar_t wc);
#endif
/* Most functions in color.c. */
#ifdef ENABLE_COLOR
void set_interface_colorpairs(void);
void prepare_palette(void);
void find_and_prime_applicable_syntax(void);
void set_up_multicache(linestruct *line);
void check_the_multis(linestruct *line);
void precalc_multicolorinfo(void);
#endif
@@ -411,7 +409,6 @@ void block_sigwinch(bool blockit);
#endif
#ifndef NANO_TINY
void handle_sigwinch(int signal);
void compute_the_extra_rows_per_line_from(linestruct *fromline);
void regenerate_screen(void);
void do_toggle(int flag);
#endif
@@ -510,8 +507,7 @@ size_t indent_length(const char *line);
size_t quote_length(const char *line);
bool begpar(const linestruct *const line, int depth);
bool inpar(const linestruct *const line);
void do_justify(bool full_justify);
void do_justify_void(void);
void do_justify(void);
void do_full_justify(void);
#endif
#ifdef ENABLE_SPELLER
@@ -531,9 +527,7 @@ void complete_a_word(void);
void get_homedir(void);
const char *tail(const char *path);
char *concatenate(const char *path, const char *name);
#ifdef ENABLE_LINENUMBERS
int digits(ssize_t n);
#endif
bool parse_num(const char *str, ssize_t *result);
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column);
void recode_NUL_to_LF(char *string, size_t length);
@@ -593,6 +587,7 @@ void set_blankdelay_to_one(void);
char *display_string(const char *buf, size_t column, size_t span,
bool isdata, bool isprompt);
void titlebar(const char *path);
void minibar(void);
void statusline(message_type importance, const char *msg, ...);
void statusbar(const char *msg);
void warn_and_briefly_pause(const char *msg);

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* rcfile.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 2001-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2014 Mike Frysinger *
* Copyright (C) 2019 Brand Huntsman *
* Copyright (C) 2014-2020 Benno Schulenberg *
@@ -60,7 +60,6 @@ static const rcoption rcopts[] = {
#ifdef HAVE_LIBMAGIC
{"magic", USE_MAGIC},
#endif
{"morespace", MORE_SPACE}, /* Deprecated; remove in 2021. */
#ifdef ENABLE_MOUSE
{"mouse", USE_MOUSE},
#endif
@@ -69,9 +68,8 @@ static const rcoption rcopts[] = {
#endif
{"nohelp", NO_HELP},
{"nonewlines", NO_NEWLINES},
{"nopauses", NO_PAUSES}, /* Obsolete; remove in 2021. */
#ifdef ENABLE_WRAPPING
{"nowrap", NO_WRAP}, /* Deprecated; remove in 2021. */
{"nowrap", NO_WRAP}, /* Deprecated; remove in 2024. */
#endif
#ifdef ENABLE_OPERATINGDIR
{"operatingdir", 0},
@@ -95,7 +93,6 @@ static const rcoption rcopts[] = {
{"suspend", SUSPENDABLE}, /* Deprecated; remove in 2022. */
{"suspendable", SUSPENDABLE},
{"tempfile", SAVE_ON_EXIT}, /* Deprecated; remove in 2022. */
{"view", VIEW_MODE},
#ifndef NANO_TINY
{"afterends", AFTER_ENDS},
{"allow_insecure_backup", INSECURE_BACKUP},
@@ -111,10 +108,10 @@ static const rcoption rcopts[] = {
{"jumpyscrolling", JUMPY_SCROLLING},
{"locking", LOCKING},
{"matchbrackets", 0},
{"minibar", MINIBAR},
{"noconvert", NO_CONVERT},
{"showcursor", SHOW_CURSOR},
{"smarthome", SMART_HOME},
{"smooth", SMOOTH_SCROLL}, /* Deprecated; remove in 2021. */
{"softwrap", SOFTWRAP},
{"stateflags", STATEFLAGS},
{"tabsize", 0},
@@ -132,6 +129,9 @@ static const rcoption rcopts[] = {
{"stripecolor", 0},
{"scrollercolor", 0},
{"selectedcolor", 0},
{"spotlightcolor", 0},
{"minicolor", 0},
{"promptcolor", 0},
{"statuscolor", 0},
{"errorcolor", 0},
{"keycolor", 0},
@@ -291,7 +291,7 @@ keystruct *strtosc(const char *input)
s->func = do_gotolinecolumn_void;
#ifdef ENABLE_JUSTIFY
else if (!strcmp(input, "justify"))
s->func = do_justify_void;
s->func = do_justify;
else if (!strcmp(input, "fulljustify"))
s->func = do_full_justify;
else if (!strcmp(input, "beginpara"))
@@ -474,7 +474,8 @@ keystruct *strtosc(const char *input)
else if (!strcmp(input, "cutfromcursor"))
s->toggle = CUT_FROM_CURSOR;
#ifdef ENABLE_WRAPPING
else if (!strcmp(input, "nowrap"))
else if (!strcmp(input, "breaklonglines") ||
!strcmp(input, "nowrap")) /* Deprecated; remove in 2024. */
s->toggle = BREAK_LONG_LINES;
#endif
else if (!strcmp(input, "tabstospaces"))
@@ -622,9 +623,7 @@ bool compile(const char *expression, int rex_flags, regex_t **packed)
regerror(outcome, compiled, message, length);
jot_error(N_("Bad regex \"%s\": %s"), expression, message);
free(message);
}
if (packed == NULL || outcome != 0) {
regfree(compiled);
free(compiled);
} else
@@ -993,9 +992,21 @@ void parse_includes(char *ptr)
free(expanded);
}
const char hues[9][7] = { "pink", "purple", "mauve", "lagoon", "mint",
"lime", "peach", "orange", "latte" };
short indices[9] = { 204, 163, 134, 38, 48, 148, 215, 208, 137 };
#define COLORCOUNT 20
const char hues[COLORCOUNT][8] = { "red", "green", "blue",
"yellow", "cyan", "magenta",
"white", "black", "normal",
"pink", "purple", "mauve",
"lagoon", "mint", "lime",
"peach", "orange", "latte",
"grey", "gray" };
short indices[COLORCOUNT] = { COLOR_RED, COLOR_GREEN, COLOR_BLUE,
COLOR_YELLOW, COLOR_CYAN, COLOR_MAGENTA,
COLOR_WHITE, COLOR_BLACK, THE_DEFAULT,
204, 163, 134, 38, 48, 148, 215, 208, 137,
COLOR_BLACK + 8, COLOR_BLACK + 8 };
/* Return the short value corresponding to the given color name, and set
* vivid to TRUE for a lighter color, and thick for a heavier typeface. */
@@ -1015,35 +1026,16 @@ short color_to_short(const char *colorname, bool *vivid, bool *thick)
*thick = FALSE;
}
if (strcmp(colorname, "green") == 0)
return COLOR_GREEN;
else if (strcmp(colorname, "red") == 0)
return COLOR_RED;
else if (strcmp(colorname, "blue") == 0)
return COLOR_BLUE;
else if (strcmp(colorname, "white") == 0)
return COLOR_WHITE;
else if (strcmp(colorname, "yellow") == 0)
return COLOR_YELLOW;
else if (strcmp(colorname, "cyan") == 0)
return COLOR_CYAN;
else if (strcmp(colorname, "magenta") == 0)
return COLOR_MAGENTA;
else if (strcmp(colorname, "black") == 0)
return COLOR_BLACK;
else if (strcmp(colorname, "normal") == 0)
return THE_DEFAULT;
else
for (int index = 0; index < 9; index++)
if (strcmp(colorname, hues[index]) == 0) {
if (*vivid) {
jot_error(N_("Color '%s' takes no prefix"), colorname);
return BAD_COLOR;
} else if (COLORS < 255)
return THE_DEFAULT;
else
return indices[index];
}
for (int index = 0; index < COLORCOUNT; index++)
if (strcmp(colorname, hues[index]) == 0) {
if (index > 7 && *vivid) {
jot_error(N_("Color '%s' takes no prefix"), colorname);
return BAD_COLOR;
} else if (index > 8 && COLORS < 255)
return THE_DEFAULT;
else
return indices[index];
}
jot_error(N_("Color \"%s\" not understood"), colorname);
return BAD_COLOR;
@@ -1201,14 +1193,11 @@ colortype *parse_interface_color(char *combostr)
{
colortype *trio = nmalloc(sizeof(colortype));
if (parse_combination(combostr, &trio->fg, &trio->bg, &trio->attributes)) {
free(combostr);
return trio;
} else {
free(combostr);
if (!parse_combination(combostr, &trio->fg, &trio->bg, &trio->attributes)) {
free(trio);
return NULL;
}
} else
return trio;
}
/* Read regex strings enclosed in double quotes from the line pointed at
@@ -1242,6 +1231,8 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
/* Now gather any valid regexes and add them to the linked list. */
while (*ptr != '\0') {
regex_t *packed_rgx = NULL;
regexstring = ++ptr;
ptr = parse_next_regex(ptr);
@@ -1249,12 +1240,12 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
return;
/* If the regex string is malformed, skip it. */
if (!compile(regexstring, NANO_REG_EXTENDED | REG_NOSUB, NULL))
if (!compile(regexstring, NANO_REG_EXTENDED | REG_NOSUB, &packed_rgx))
continue;
/* Copy the regex into a struct, and hook this in at the end. */
newthing = nmalloc(sizeof(regexlisttype));
newthing->full_regex = copy_of(regexstring);
newthing->one_rgx = packed_rgx;
newthing->next = NULL;
if (lastthing == NULL)
@@ -1547,8 +1538,6 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
continue;
}
#endif
argument = copy_of(argument);
#ifdef ENABLE_COLOR
if (strcmp(option, "titlecolor") == 0)
color_combo[TITLE_BAR] = parse_interface_color(argument);
@@ -1560,6 +1549,12 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
color_combo[SCROLL_BAR] = parse_interface_color(argument);
else if (strcmp(option, "selectedcolor") == 0)
color_combo[SELECTED_TEXT] = parse_interface_color(argument);
else if (strcmp(option, "spotlightcolor") == 0)
color_combo[SPOTLIGHTED] = parse_interface_color(argument);
else if (strcmp(option, "minicolor") == 0)
color_combo[MINI_INFOBAR] = parse_interface_color(argument);
else if (strcmp(option, "promptcolor") == 0)
color_combo[PROMPT_BAR] = parse_interface_color(argument);
else if (strcmp(option, "statuscolor") == 0)
color_combo[STATUS_BAR] = parse_interface_color(argument);
else if (strcmp(option, "errorcolor") == 0)
@@ -1572,7 +1567,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
#endif
#ifdef ENABLE_OPERATINGDIR
if (strcmp(option, "operatingdir") == 0)
operating_dir = argument;
operating_dir = copy_of(argument);
else
#endif
#ifdef ENABLED_WRAPORJUSTIFY
@@ -1581,25 +1576,21 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
jot_error(N_("Requested fill size \"%s\" is invalid"), argument);
fill = -COLUMNS_FROM_EOL;
}
free(argument);
} else
#endif
#ifndef NANO_TINY
if (strcmp(option, "matchbrackets") == 0) {
if (has_blank_char(argument)) {
if (has_blank_char(argument))
jot_error(N_("Non-blank characters required"));
free(argument);
} else if (mbstrlen(argument) % 2 != 0) {
else if (mbstrlen(argument) % 2 != 0)
jot_error(N_("Even number of characters required"));
free(argument);
} else
matchbrackets = argument;
else
matchbrackets = copy_of(argument);
} else if (strcmp(option, "whitespace") == 0) {
if (mbstrlen(argument) != 2 || breadth(argument) != 2) {
if (mbstrlen(argument) != 2 || breadth(argument) != 2)
jot_error(N_("Two single-column characters required"));
free(argument);
} else {
whitespace = argument;
else {
whitespace = copy_of(argument);
whitelen[0] = char_length(whitespace);
whitelen[1] = char_length(whitespace + whitelen[0]);
}
@@ -1607,43 +1598,39 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
#endif
#ifdef ENABLE_JUSTIFY
if (strcmp(option, "punct") == 0) {
if (has_blank_char(argument)) {
if (has_blank_char(argument))
jot_error(N_("Non-blank characters required"));
free(argument);
} else
punct = argument;
else
punct = copy_of(argument);
} else if (strcmp(option, "brackets") == 0) {
if (has_blank_char(argument)) {
if (has_blank_char(argument))
jot_error(N_("Non-blank characters required"));
free(argument);
} else
brackets = argument;
else
brackets = copy_of(argument);
} else if (strcmp(option, "quotestr") == 0)
quotestr = argument;
quotestr = copy_of(argument);
else
#endif
#ifdef ENABLE_SPELLER
if (strcmp(option, "speller") == 0)
alt_speller = argument;
alt_speller = copy_of(argument);
else
#endif
#ifndef NANO_TINY
if (strcmp(option, "backupdir") == 0)
backup_dir = argument;
backup_dir = copy_of(argument);
else if (strcmp(option, "wordchars") == 0)
word_chars = argument;
word_chars = copy_of(argument);
else if (strcmp(option, "guidestripe") == 0) {
if (!parse_num(argument, &stripe_column) || stripe_column <= 0) {
jot_error(N_("Guide column \"%s\" is invalid"), argument);
stripe_column = 0;
}
free(argument);
} else if (strcmp(option, "tabsize") == 0) {
if (!parse_num(argument, &tabsize) || tabsize <= 0) {
jot_error(N_("Requested tab size \"%s\" is invalid"), argument);
tabsize = -1;
}
free(argument);
}
#else
; /* Properly terminate any earlier 'else'. */

View File

@@ -1,8 +1,8 @@
/**************************************************************************
* search.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 2015-2019 Benno Schulenberg *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2015-2020 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -42,7 +42,7 @@ bool regexp_init(const char *regexp)
char *str = nmalloc(len);
regerror(value, &search_regexp, str, len);
statusline(ALERT, _("Bad regex \"%s\": %s"), regexp, str);
statusline(AHEM, _("Bad regex \"%s\": %s"), regexp, str);
free(str);
return FALSE;
@@ -82,7 +82,7 @@ void search_init(bool replacing, bool retain_answer)
thedefault = nmalloc(strlen(disp) + 7);
/* We use (COLS / 3) here because we need to see more on the line. */
sprintf(thedefault, " [%s%s]", disp,
(breadth(last_search) > COLS / 3) ? "..." : "");
(breadth(last_search) > COLS / 3) ? "..." : "");
free(disp);
} else
thedefault = copy_of("");
@@ -251,7 +251,7 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
line = (ISSET(BACKWARDS_SEARCH)) ? openfile->filebot : openfile->filetop;
if (modus == JUSTFIND) {
statusbar(_("Search Wrapped"));
statusline(REMARK, _("Search Wrapped"));
/* Delay the "Searching..." message for at least two seconds. */
feedback = -2;
}
@@ -322,11 +322,19 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
if (match_len != NULL)
*match_len = found_len;
/* Wipe the "Searching..." message and unsuppress cursor-position display. */
if (feedback > 0) {
wipe_statusbar();
lastmessage = VACUUM;
#ifndef NANO_TINY
if (modus == JUSTFIND && (!openfile->mark || openfile->softmark)) {
spotlighted = TRUE;
light_from_col = xplustabs();
light_to_col = wideness(line->data, found_x + found_len);
if (!ISSET(SHOW_CURSOR))
hide_cursor = TRUE;
edit_refresh();
}
#endif
if (feedback > 0)
wipe_statusbar();
return 1;
}
@@ -356,7 +364,7 @@ void do_research(void)
#endif
if (*last_search == '\0') {
statusbar(_("No current search pattern"));
statusline(AHEM, _("No current search pattern"));
return;
}
@@ -394,7 +402,7 @@ void not_found_msg(const char *str)
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE, FALSE);
size_t numchars = actual_x(disp, wideness(disp, COLS / 2));
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
statusline(AHEM, _("\"%.*s%s\" not found"), numchars, disp,
(disp[numchars] == '\0') ? "" : "...");
free(disp);
}
@@ -420,15 +428,13 @@ void go_looking(void)
/* If we found something, and we're back at the exact same spot
* where we started searching, then this is the only occurrence. */
if (didfind == 1 && openfile->current == was_current &&
openfile->current_x == was_current_x)
statusbar(_("This is the only occurrence"));
else if (didfind == 1 && LINES == 1)
refresh_needed = TRUE;
openfile->current_x == was_current_x)
statusline(REMARK, _("This is the only occurrence"));
else if (didfind == 0)
not_found_msg(last_search);
#ifdef TIMEIT
statusline(HUSH, "Took: %.2f", (double)(clock() - start) / CLOCKS_PER_SEC);
statusline(INFO, "Took: %.2f", (double)(clock() - start) / CLOCKS_PER_SEC);
#endif
edit_redraw(was_current, CENTERING);
@@ -464,8 +470,7 @@ int replace_regexp(char *string, bool create)
/* And if create is TRUE, append the result of the
* subexpression match to the new line. */
if (create) {
strncpy(string, openfile->current->data +
regmatches[num].rm_so, i);
strncpy(string, openfile->current->data + regmatches[num].rm_so, i);
string += i;
}
}
@@ -510,19 +515,6 @@ char *replace_line(const char *needle)
return copy;
}
#ifdef ENABLE_COLOR
/* Reset the multiline coloring info and then recalculate it. */
void wipe_and_recalculate_colorinfo(void)
{
for (linestruct *line = openfile->filetop; line != NULL; line = line->next)
if (line->multidata)
for (short index = 0; index < openfile->syntax->nmultis; index++)
line->multidata[index] = -1;
precalc_multicolorinfo();
}
#endif
/* Step through each occurrence of the search string and prompt the user
* before replacing it. We seek for needle, and replace it with answer.
* The parameters real_current and real_current_x are needed in order to
@@ -667,17 +659,6 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
free(openfile->current->data);
openfile->current->data = copy;
#ifndef NANO_TINY
if (ISSET(SOFTWRAP))
openfile->current->extrarows = extra_chunks_in(openfile->current);
#endif
#ifdef ENABLE_COLOR
/* Check whether the replacement requires a change in the coloring. */
check_the_multis(openfile->current);
if (refresh_needed && !replaceall)
wipe_and_recalculate_colorinfo();
#endif
set_modified();
as_an_at = TRUE;
numreplaced++;
@@ -687,11 +668,6 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
if (numreplaced == -1)
not_found_msg(needle);
#ifdef ENABLE_COLOR
if (refresh_needed)
wipe_and_recalculate_colorinfo();
#endif
#ifndef NANO_TINY
openfile->mark = was_mark;
#endif
@@ -724,8 +700,8 @@ void ask_for_and_do_replacements(void)
size_t begin_x = openfile->current_x;
ssize_t numreplaced;
int response = do_prompt(MREPLACEWITH, "", &replace_history,
/* TRANSLATORS: This is a prompt. */
edit_refresh, _("Replace with"));
/* TRANSLATORS: This is a prompt. */
edit_refresh, _("Replace with"));
#ifdef ENABLE_HISTORIES
/* When not "", add the replace string to the replace history list. */
@@ -747,11 +723,12 @@ void ask_for_and_do_replacements(void)
openfile->firstcolumn = was_firstcolumn;
openfile->current = beginline;
openfile->current_x = begin_x;
refresh_needed = TRUE;
edit_refresh();
if (numreplaced >= 0)
statusline(HUSH, P_("Replaced %zd occurrence",
"Replaced %zd occurrences", numreplaced), numreplaced);
statusline(REMARK, P_("Replaced %zd occurrence",
"Replaced %zd occurrences", numreplaced), numreplaced);
}
/* Go to the specified line and x position. */
@@ -798,7 +775,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool retain_answer,
/* Try to extract one or two numbers from the user's response. */
if (!parse_line_column(answer, &line, &column)) {
statusline(ALERT, _("Invalid line or column number"));
statusline(AHEM, _("Invalid line or column number"));
return;
}
} else {
@@ -946,7 +923,7 @@ void do_find_bracket(void)
ch = mbstrchr(matchbrackets, openfile->current->data + openfile->current_x);
if (ch == NULL) {
statusbar(_("Not a bracket"));
statusline(AHEM, _("Not a bracket"));
return;
}
@@ -989,7 +966,7 @@ void do_find_bracket(void)
}
}
statusbar(_("No matching bracket"));
statusline(AHEM, _("No matching bracket"));
/* Restore the cursor position. */
openfile->current = was_current;
@@ -1004,9 +981,9 @@ void put_or_lift_anchor(void)
update_line(openfile->current, openfile->current_x);
if (openfile->current->has_anchor)
statusbar(_("Placed anchor"));
statusline(REMARK, _("Placed anchor"));
else
statusbar(_("Removed anchor"));
statusline(REMARK, _("Removed anchor"));
}
/* Make the given line the current line, or report the anchoredness. */
@@ -1020,9 +997,9 @@ void go_to_and_confirm(linestruct *line)
edit_redraw(was_current, CENTERING);
statusbar(_("Jumped to anchor"));
} else if (openfile->current->has_anchor)
statusbar(_("This is the only anchor"));
statusline(REMARK, _("This is the only anchor"));
else
statusbar(_("There are no anchors"));
statusline(AHEM, _("There are no anchors"));
}
/* Jump to the first anchor before the current line; wrap around at the top. */

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* text.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2014-2015 Mark Majeres *
* Copyright (C) 2016 Mike Scalora *
* Copyright (C) 2016 Sumedh Pendurkar *
@@ -50,8 +50,8 @@ void do_mark(void)
if (!openfile->mark) {
openfile->mark = openfile->current;
openfile->mark_x = openfile->current_x;
openfile->softmark = FALSE;
statusbar(_("Mark Set"));
openfile->kind_of_mark = HARDMARK;
} else {
openfile->mark = NULL;
statusbar(_("Mark Unset"));
@@ -60,8 +60,8 @@ void do_mark(void)
}
#endif /* !NANO_TINY */
/* Insert a tab. If the TABS_TO_SPACES flag is set, insert the number
* of spaces that a tab would normally take up. */
/* Insert a tab. Or, if --tabstospaces is in effect, insert the number
* of spaces that a tab would normally take up at this position. */
void do_tab(void)
{
#ifdef ENABLE_COLOR
@@ -103,9 +103,6 @@ void indent_a_line(linestruct *line, char *indentation)
openfile->totsize += indent_len;
if (ISSET(SOFTWRAP))
line->extrarows = extra_chunks_in(line);
/* Compensate for the change in the current line. */
if (line == openfile->mark && openfile->mark_x > 0)
openfile->mark_x += indent_len;
@@ -136,12 +133,12 @@ void do_indent(void)
indentation = nmalloc(tabsize + 1);
/* Set the indentation to either a bunch of spaces or a single tab. */
#ifdef ENABLE_COLOR
if (openfile->syntax && openfile->syntax->tab)
indentation = mallocstrcpy(indentation, openfile->syntax->tab);
else
#endif
/* Set the indentation to either a bunch of spaces or a single tab. */
if (ISSET(TABS_TO_SPACES)) {
memset(indentation, ' ', tabsize);
indentation[tabsize] = '\0';
@@ -234,9 +231,6 @@ void unindent_a_line(linestruct *line, size_t indent_len)
openfile->totsize -= indent_len;
if (ISSET(SOFTWRAP))
line->extrarows = extra_chunks_in(line);
/* Adjust the positions of mark and cursor, when they are affected. */
compensate_leftward(line, indent_len);
}
@@ -284,9 +278,6 @@ void handle_indent_action(undostruct *u, bool undoing, bool add_indent)
groupstruct *group = u->grouping;
linestruct *line = line_from_number(group->top_line);
if (group->next != NULL)
die("Multiple groups -- please report a bug\n");
/* When redoing, reposition the cursor and let the indenter adjust it. */
if (!undoing)
goto_line_posx(u->head_lineno, u->head_x);
@@ -387,7 +378,7 @@ void do_comment(void)
comment_seq = openfile->syntax->comment;
if (*comment_seq == '\0') {
statusbar(_("Commenting is not supported for this file type"));
statusline(AHEM, _("Commenting is not supported for this file type"));
return;
}
#endif
@@ -397,7 +388,7 @@ void do_comment(void)
/* If only the magic line is selected, don't do anything. */
if (top == bot && bot == openfile->filebot && !ISSET(NO_NEWLINES)) {
statusbar(_("Cannot comment past end of file"));
statusline(AHEM, _("Cannot comment past end of file"));
return;
}
@@ -424,15 +415,9 @@ void do_comment(void)
/* Comment/uncomment each of the selected lines when possible, and
* store undo data when a line changed. */
for (line = top; line != bot->next; line = line->next) {
if (comment_line(action, line, comment_seq)) {
#ifndef NANO_TINY
if (ISSET(SOFTWRAP))
line->extrarows = extra_chunks_in(line);
#endif
for (line = top; line != bot->next; line = line->next)
if (comment_line(action, line, comment_seq))
update_multiline_undo(line->lineno, "");
}
}
set_modified();
ensure_firstcolumn_is_aligned();
@@ -519,7 +504,7 @@ void do_undo(void)
size_t original_x, regain_from_x;
if (u == NULL) {
statusbar(_("Nothing to undo"));
statusline(AHEM, _("Nothing to undo"));
return;
}
@@ -573,8 +558,6 @@ void do_undo(void)
break;
}
line->data[u->tail_x] = '\0';
if (ISSET(SOFTWRAP))
line->extrarows = extra_chunks_in(line);
intruder = make_new_node(line);
intruder->data = copy_of(u->strdata);
splice_node(line, intruder);
@@ -583,6 +566,8 @@ void do_undo(void)
break;
case REPLACE:
undidmsg = _("replacement");
if ((u->xflags & INCLUDED_LAST_LINE) && !ISSET(NO_NEWLINES))
remove_magicline();
data = u->strdata;
u->strdata = line->data;
line->data = data;
@@ -674,9 +659,6 @@ void do_undo(void)
openfile->mark = NULL;
openfile->placewewant = xplustabs();
if (ISSET(SOFTWRAP))
openfile->current->extrarows = extra_chunks_in(openfile->current);
openfile->totsize = u->wassize;
/* When at the point where the file was last saved, unset "Modified". */
@@ -696,7 +678,7 @@ void do_redo(void)
undostruct *u = openfile->undotop;
if (u == NULL || u == openfile->current_undo) {
statusbar(_("Nothing to redo"));
statusline(AHEM, _("Nothing to redo"));
return;
}
@@ -723,8 +705,6 @@ void do_redo(void)
case ENTER:
redidmsg = _("line break");
line->data[u->head_x] = '\0';
if (ISSET(SOFTWRAP))
line->extrarows = extra_chunks_in(line);
intruder = make_new_node(line);
intruder->data = copy_of(u->strdata);
splice_node(line, intruder);
@@ -755,6 +735,8 @@ void do_redo(void)
break;
case REPLACE:
redidmsg = _("replacement");
if ((u->xflags & INCLUDED_LAST_LINE) && !ISSET(NO_NEWLINES))
new_magicline();
data = u->strdata;
u->strdata = line->data;
line->data = data;
@@ -837,9 +819,6 @@ void do_redo(void)
openfile->mark = NULL;
openfile->placewewant = xplustabs();
if (ISSET(SOFTWRAP))
openfile->current->extrarows = extra_chunks_in(openfile->current);
openfile->totsize = u->newsize;
/* When at the point where the file was last saved, unset "Modified". */
@@ -903,11 +882,6 @@ void do_enter(void)
openfile->mark = newnode;
openfile->mark_x += extra - openfile->current_x;
}
if (ISSET(SOFTWRAP)) {
openfile->current->extrarows = extra_chunks_in(openfile->current);
newnode->extrarows = extra_chunks_in(newnode);
}
#endif
/* Insert the newly created line after the current one and renumber. */
@@ -947,7 +921,7 @@ void discard_until(const undostruct *thisitem)
while (group != NULL) {
groupstruct *next = group->next;
free_chararray(group->indentations,
group->bottom_line - group->top_line);
group->bottom_line - group->top_line + 1);
free(group);
group = next;
}
@@ -1039,6 +1013,8 @@ void add_undo(undo_type action, const char *message)
break;
case REPLACE:
u->strdata = copy_of(thisline->data);
if (thisline == openfile->filebot && answer[0] != '\0')
u->xflags |= INCLUDED_LAST_LINE;
break;
#ifdef ENABLE_WRAPPING
case SPLIT_BEGIN:
@@ -1071,9 +1047,7 @@ void add_undo(undo_type action, const char *message)
break;
case PASTE:
u->cutbuffer = copy_buffer(cutbuffer);
if (thisline == openfile->filebot)
u->xflags |= INCLUDED_LAST_LINE;
break;
/* Fall-through. */
case INSERT:
if (thisline == openfile->filebot)
u->xflags |= INCLUDED_LAST_LINE;
@@ -1108,24 +1082,24 @@ void update_multiline_undo(ssize_t lineno, char *indentation)
/* If there already is a group and the current line is contiguous with it,
* extend the group; otherwise, create a new group. */
if (u->grouping && u->grouping->bottom_line + 1 == lineno) {
size_t number_of_lines;
size_t number_of_lines = lineno - u->grouping->top_line + 1;
u->grouping->bottom_line++;
u->grouping->bottom_line = lineno;
number_of_lines = u->grouping->bottom_line - u->grouping->top_line + 1;
u->grouping->indentations = nrealloc(u->grouping->indentations,
number_of_lines * sizeof(char *));
u->grouping->indentations[number_of_lines - 1] = copy_of(indentation);
} else {
groupstruct *born = nmalloc(sizeof(groupstruct));
born->next = u->grouping;
u->grouping = born;
born->top_line = lineno;
born->bottom_line = lineno;
u->grouping->indentations = nmalloc(sizeof(char *));
u->grouping->indentations[0] = copy_of(indentation);
born->indentations = nmalloc(sizeof(char *));
born->indentations[0] = copy_of(indentation);
born->next = u->grouping;
u->grouping = born;
}
/* Store the file size after the change, to be used when redoing. */
@@ -1213,17 +1187,11 @@ void update_undo(undo_type action)
u->tail_x = strlen(bottomline->data);
}
break;
case PASTE:
u->tail_lineno = openfile->current->lineno;
u->tail_x = openfile->current_x;
break;
case INSERT:
u->tail_lineno = openfile->current->lineno;
u->tail_x = openfile->current_x;
break;
case COUPLE_BEGIN:
break;
case COUPLE_END:
case PASTE:
case INSERT:
u->tail_lineno = openfile->current->lineno;
u->tail_x = openfile->current_x;
break;
@@ -1359,7 +1327,9 @@ bool do_wrap(void)
strncpy(line->data, line->prev->data, lead_len);
openfile->current_x += lead_len;
openfile->totsize += lead_len;
#ifndef NANO_TINY
free(openfile->undotop->strdata);
update_undo(ENTER);
#endif
if (autowhite)
@@ -1455,21 +1425,12 @@ ssize_t break_line(const char *textstart, ssize_t goal, bool snap_at_nl)
* "indentation" of a line is the leading consecutive whitespace. */
size_t indent_length(const char *line)
{
size_t len = 0;
char onechar[MAXCHARLEN];
int charlen;
const char *start = line;
while (*line != '\0') {
charlen = collect_char(line, onechar);
while (*line != '\0' && is_blank_char(line))
line += char_length(line);
if (!is_blank_char(onechar))
break;
line += charlen;
len += charlen;
}
return len;
return (line - start);
}
#endif
@@ -1743,9 +1704,12 @@ void justify_paragraph(linestruct **line, size_t count)
free(lead_string);
}
/* Justify the current paragraph, or the entire buffer when full_justify is
#define ONE_PARAGRAPH FALSE
#define WHOLE_BUFFER TRUE
/* Justify the current paragraph, or the entire buffer when whole_buffer is
* TRUE. But if the mark is on, justify only the marked text instead. */
void do_justify(bool full_justify)
void justify_text(bool whole_buffer)
{
size_t linecount;
/* The number of lines in the original paragraph. */
@@ -1786,7 +1750,7 @@ void do_justify(bool full_justify)
/* When the marked region is empty, do nothing. */
if (startline == endline && start_x == end_x) {
statusline(ALERT, _("Selection is empty"));
statusline(AHEM, _("Selection is empty"));
discard_until(openfile->undotop->next);
return;
}
@@ -1861,7 +1825,7 @@ void do_justify(bool full_justify)
{
/* 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)
if (whole_buffer)
openfile->current = openfile->filetop;
else if (inpar(openfile->current) && !begpar(openfile->current, 0))
do_para_begin(&openfile->current);
@@ -1883,7 +1847,7 @@ void do_justify(bool full_justify)
start_x = 0;
/* Set the end point of the paragraph. */
if (full_justify)
if (whole_buffer)
endline = openfile->filebot;
else {
endline = startline;
@@ -1958,7 +1922,7 @@ void do_justify(bool full_justify)
justify_paragraph(&jusline, linecount);
/* When justifying the entire buffer, find and justify all paragraphs. */
if (full_justify) {
if (whole_buffer) {
while (find_paragraph(&jusline, &linecount)) {
justify_paragraph(&jusline, linecount);
@@ -1970,7 +1934,7 @@ void do_justify(bool full_justify)
#ifndef NANO_TINY
add_undo(PASTE, NULL);
if (full_justify && !openfile->mark && !cutbuffer->has_anchor)
if (whole_buffer && !openfile->mark && !cutbuffer->has_anchor)
openfile->current->has_anchor = FALSE;
#endif
/* Do the equivalent of a paste of the justified text. */
@@ -1998,11 +1962,11 @@ void do_justify(bool full_justify)
/* Show what we justified on the status bar. */
#ifndef NANO_TINY
if (openfile->mark)
statusbar(_("Justified selection"));
statusline(REMARK, _("Justified selection"));
else
#endif
if (full_justify)
statusbar(_("Justified file"));
if (whole_buffer)
statusline(REMARK, _("Justified file"));
else
statusbar(_("Justified paragraph"));
@@ -2015,15 +1979,15 @@ void do_justify(bool full_justify)
}
/* Justify the current paragraph. */
void do_justify_void(void)
void do_justify(void)
{
do_justify(FALSE);
justify_text(ONE_PARAGRAPH);
}
/* Justify the entire file. */
void do_full_justify(void)
{
do_justify(TRUE);
justify_text(WHOLE_BUFFER);
ran_a_tool = TRUE;
}
#endif /* ENABLE_JUSTIFY */
@@ -2106,10 +2070,10 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
if (fileinfo.st_size == 0) {
#ifndef NANO_TINY
if (spelling && openfile->mark)
statusline(ALERT, _("Selection is empty"));
statusline(AHEM, _("Selection is empty"));
else
#endif
statusbar(_("Buffer is empty"));
statusline(AHEM, _("Buffer is empty"));
return;
}
@@ -2144,18 +2108,22 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
if (thepid < 0) {
statusline(ALERT, _("Could not fork: %s"), strerror(errornumber));
free(arguments[0]);
return;
} else if (!WIFEXITED(program_status) || WEXITSTATUS(program_status) > 2) {
statusline(ALERT, _("Error invoking '%s'"), arguments[0]);
free(arguments[0]);
return;
} else if (WEXITSTATUS(program_status) != 0)
statusline(ALERT, _("Program '%s' complained"), arguments[0]);
free(arguments[0]);
/* When the temporary file wasn't touched, say so and leave. */
if (timestamp_sec > 0 && stat(tempfile_name, &fileinfo) == 0 &&
(long)fileinfo.st_mtim.tv_sec == timestamp_sec &&
(long)fileinfo.st_mtim.tv_nsec == timestamp_nsec) {
statusbar(_("Nothing changed"));
statusline(REMARK, _("Nothing changed"));
return;
}
@@ -2203,9 +2171,9 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
adjust_viewport(STATIONARY);
if (spelling)
statusbar(_("Finished checking spelling"));
statusline(REMARK, _("Finished checking spelling"));
else
statusbar(_("Buffer has been processed"));
statusline(REMARK, _("Buffer has been processed"));
}
#endif /* ENABLE_SPELLER || ENABLE_COLOR */
@@ -2340,11 +2308,11 @@ void do_int_speller(const char *tempfile_name)
exit(6);
/* Connect standard input to the temporary file. */
if (dup2(tempfile_fd, STDIN_FILENO) != STDIN_FILENO)
if (dup2(tempfile_fd, STDIN_FILENO) < 0)
exit(7);
/* Connect standard output to the write end of the first pipe. */
if (dup2(spell_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
if (dup2(spell_fd[1], STDOUT_FILENO) < 0)
exit(8);
close(tempfile_fd);
@@ -2365,11 +2333,11 @@ void do_int_speller(const char *tempfile_name)
/* Fork a process to run sort in. */
if ((pid_sort = fork()) == 0) {
/* Connect standard input to the read end of the first pipe. */
if (dup2(spell_fd[0], STDIN_FILENO) != STDIN_FILENO)
if (dup2(spell_fd[0], STDIN_FILENO) < 0)
exit(7);
/* Connect standard output to the write end of the second pipe. */
if (dup2(sort_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
if (dup2(sort_fd[1], STDOUT_FILENO) < 0)
exit(8);
close(spell_fd[0]);
@@ -2387,10 +2355,10 @@ void do_int_speller(const char *tempfile_name)
/* Fork a process to run uniq in. */
if ((pid_uniq = fork()) == 0) {
if (dup2(sort_fd[0], STDIN_FILENO) != STDIN_FILENO)
if (dup2(sort_fd[0], STDIN_FILENO) < 0)
exit(7);
if (dup2(uniq_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
if (dup2(uniq_fd[1], STDOUT_FILENO) < 0)
exit(8);
close(sort_fd[0]);
@@ -2490,7 +2458,7 @@ void do_int_speller(const char *tempfile_name)
else if (WIFEXITED(spell_status) == 0 || WEXITSTATUS(spell_status))
statusline(ALERT, _("Error invoking \"spell\""));
else
statusbar(_("Finished checking spelling"));
statusline(REMARK, _("Finished checking spelling"));
}
/* Spell check the current file. If an alternate spell checker is
@@ -2535,7 +2503,7 @@ void do_spell(void)
blank_bottombars();
if (alt_speller)
if (alt_speller && *alt_speller)
treat(temp_name, alt_speller, TRUE);
else
do_int_speller(temp_name);
@@ -2563,7 +2531,6 @@ void do_linter(void)
int lint_status, lint_fd[2];
pid_t pid_lint;
bool helpless = ISSET(NO_HELP);
static char **lintargs = NULL;
lintstruct *lints = NULL, *tmplint = NULL, *curlint = NULL;
time_t last_wait = 0;
@@ -2573,7 +2540,7 @@ void do_linter(void)
return;
if (!openfile->syntax || !openfile->syntax->linter) {
statusbar(_("No linter is defined for this type of file"));
statusline(AHEM, _("No linter is defined for this type of file"));
return;
}
@@ -2602,19 +2569,21 @@ void do_linter(void)
currmenu = MLINTER;
statusbar(_("Invoking linter..."));
construct_argument_list(&lintargs, openfile->syntax->linter, openfile->filename);
/* Fork a process to run the linter in. */
if ((pid_lint = fork()) == 0) {
char **lintargs = NULL;
/* Redirect standard output and standard error into the pipe. */
if (dup2(lint_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
if (dup2(lint_fd[1], STDOUT_FILENO) < 0)
exit(7);
if (dup2(lint_fd[1], STDERR_FILENO) != STDERR_FILENO)
if (dup2(lint_fd[1], STDERR_FILENO) < 0)
exit(8);
close(lint_fd[0]);
close(lint_fd[1]);
construct_argument_list(&lintargs, openfile->syntax->linter, openfile->filename);
/* Start the linter program; we are using $PATH. */
execvp(lintargs[0], lintargs);
@@ -2641,6 +2610,9 @@ void do_linter(void)
return;
}
/* Block resizing signals while reading from the pipe. */
block_sigwinch(TRUE);
/* Read in the returned syntax errors. */
totalread = 0;
buffersize = pipesize + 1;
@@ -2657,10 +2629,12 @@ void do_linter(void)
*pointer = '\0';
close(lint_fd[0]);
/* Process the linter output. */
block_sigwinch(FALSE);
pointer = lintings;
onelint = lintings;
/* Now parse the output of the linter. */
while (*pointer != '\0') {
if ((*pointer == '\r') || (*pointer == '\n')) {
*pointer = '\0';
@@ -2668,11 +2642,8 @@ void do_linter(void)
char *filename = NULL, *linestr = NULL, *maybecol = NULL;
char *message = copy_of(onelint);
/* At the moment we handle the following formats:
*
* filenameorcategory:line:column:message (e.g. splint)
* filenameorcategory:line,column:message (e.g. pylint)
* filenameorcategory:line:message (e.g. pyflakes) */
/* The recognized format is "filename:line:column: message",
* where ":column" may be absent or be ",column" instead. */
if (strstr(message, ": ") != NULL) {
filename = strtok(onelint, ":");
if ((linestr = strtok(NULL, ":")) != NULL) {
@@ -2705,7 +2676,7 @@ void do_linter(void)
curlint->prev = tmplint;
if (curlint->prev != NULL)
curlint->prev->next = curlint;
curlint->msg = copy_of(message);
curlint->msg = copy_of(strstr(message, ": ") + 2);
curlint->lineno = tmplineno;
curlint->colno = tmpcolno;
curlint->filename = copy_of(filename);
@@ -2733,7 +2704,7 @@ void do_linter(void)
}
if (!parsesuccess) {
statusline(HUSH, _("Got 0 parsable lines from command: %s"),
statusline(REMARK, _("Got 0 parsable lines from command: %s"),
openfile->syntax->linter);
return;
}
@@ -2810,7 +2781,7 @@ void do_linter(void)
free(dontwantfile);
if (restlint == NULL) {
statusbar(_("No messages for this file"));
statusline(REMARK, _("No messages for this file"));
break;
} else {
curlint = restlint;
@@ -2823,7 +2794,10 @@ void do_linter(void)
}
if (tmplint != curlint) {
/* Put the cursor at the reported position, but don't go beyond EOL
* when the second number is a column number instead of an index. */
goto_line_posx(curlint->lineno, curlint->colno - 1);
openfile->current_x = actual_x(openfile->current->data, openfile->placewewant);
titlebar(NULL);
adjust_viewport(CENTERING);
#ifdef ENABLE_LINENUMBERS
@@ -2891,6 +2865,7 @@ void do_linter(void)
refresh_needed = TRUE;
}
lastmessage = VACUUM;
currmenu = MMOST;
titlebar(NULL);
}
@@ -2908,7 +2883,7 @@ void do_formatter(void)
return;
if (!openfile->syntax || !openfile->syntax->formatter) {
statusbar(_("No formatter is defined for this type of file"));
statusline(AHEM, _("No formatter is defined for this type of file"));
return;
}
@@ -2984,9 +2959,12 @@ void do_wordlinechar_count(void)
openfile->current = was_current;
openfile->current_x = was_x;
/* Display the total word, line, and character counts on the status bar. */
statusline(HUSH, _("%sWords: %zu Lines: %zd Chars: %zu"), openfile->mark ?
_("In Selection: ") : "", words, lines, chars);
/* Report on the status bar the number of lines, words, and characters. */
statusline(INFO, _("%s%zd %s, %zu %s, %zu %s"),
openfile->mark ? _("In Selection: ") : "",
lines, P_("line", "lines", lines),
words, P_("word", "words", words),
chars, P_("character", "characters", chars));
}
#endif /* !NANO_TINY */
@@ -2997,7 +2975,7 @@ void do_verbatim_input(void)
char *bytes;
/* TRANSLATORS: Shown when the next keystroke will be inserted verbatim. */
statusbar(_("Verbatim Input"));
statusline(INFO, _("Verbatim Input"));
place_the_cursor();
/* Read in the first one or two bytes of the next keystroke. */
@@ -3006,7 +2984,7 @@ void do_verbatim_input(void)
/* When something valid was obtained, unsuppress cursor-position display,
* insert the bytes into the edit buffer, and blank the status bar. */
if (count > 0) {
if (ISSET(CONSTANT_SHOW))
if (ISSET(CONSTANT_SHOW) || ISSET(MINIBAR))
lastmessage = VACUUM;
if (count < 999)
@@ -3015,7 +2993,7 @@ void do_verbatim_input(void)
wipe_statusbar();
} else
/* TRANSLATORS: An invalid verbatim Unicode code was typed. */
statusline(ALERT, _("Invalid code"));
statusline(AHEM, _("Invalid code"));
free(bytes);
}
@@ -3091,7 +3069,7 @@ void complete_a_word(void)
/* If there is no word fragment before the cursor, do nothing. */
if (start_of_shard == openfile->current_x) {
/* TRANSLATORS: Shown when no text is directly left of the cursor. */
statusbar(_("No word fragment"));
statusline(AHEM, _("No word fragment"));
pletion_line = NULL;
return;
}
@@ -3183,11 +3161,11 @@ void complete_a_word(void)
/* The search has reached the end of the file. */
if (list_of_completions != NULL) {
statusline(ALERT, _("No further matches"));
refresh_needed = TRUE;
edit_refresh();
statusline(AHEM, _("No further matches"));
} else
/* TRANSLATORS: Shown when there are zero possible completions. */
statusline(ALERT, _("No matches"));
statusline(AHEM, _("No matches"));
free(shard);
}

View File

@@ -1,7 +1,7 @@
/**************************************************************************
* utils.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
* Copyright (C) 2016, 2017, 2019 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@@ -76,7 +76,6 @@ char *concatenate(const char *path, const char *name)
return joined;
}
#ifdef ENABLE_LINENUMBERS
/* Return the number of digits that the given integer n takes up. */
int digits(ssize_t n)
{
@@ -106,21 +105,20 @@ int digits(ssize_t n)
}
}
}
#endif
/* Read an integer from str. If it parses okay, store it in *result
* and return TRUE; otherwise, return FALSE. */
bool parse_num(const char *str, ssize_t *result)
/* Read an integer from the given string. If it parses okay,
* store it in *result and return TRUE; otherwise, return FALSE. */
bool parse_num(const char *string, ssize_t *result)
{
char *first_error;
ssize_t value;
char *excess;
/* The manual page for strtol() says this is required. */
/* Clear the error number so that we can check it afterward. */
errno = 0;
value = (ssize_t)strtol(str, &first_error, 10);
value = (ssize_t)strtol(string, &excess, 10);
if (errno == ERANGE || *str == '\0' || *first_error != '\0')
if (errno == ERANGE || *string == '\0' || *excess != '\0')
return FALSE;
*result = value;
@@ -195,22 +193,18 @@ void free_chararray(char **array, size_t len)
#endif
#ifdef ENABLE_SPELLER
/* Is the word starting at the given position in buf and of the given length
* a separate word? That is: is it not part of a longer word?*/
bool is_separate_word(size_t position, size_t length, const char *buf)
/* Is the word starting at the given position in 'text' and of the given
* length a separate word? That is: is it not part of a longer word? */
bool is_separate_word(size_t position, size_t length, const char *text)
{
char before[MAXCHARLEN], after[MAXCHARLEN];
size_t word_end = position + length;
/* Get the characters before and after the word, if any. */
collect_char(buf + step_left(buf, position), before);
collect_char(buf + word_end, after);
const char *before = text + step_left(text, position);
const char *after = text + position + length;
/* If the word starts at the beginning of the line OR the character before
* the word isn't a letter, and if the word ends at the end of the line OR
* the character after the word isn't a letter, we have a whole word. */
return ((position == 0 || !is_alpha_char(before)) &&
(buf[word_end] == '\0' || !is_alpha_char(after)));
(*after == '\0' || !is_alpha_char(after)));
}
#endif /* ENABLE_SPELLER */
@@ -294,7 +288,10 @@ void *nmalloc(size_t howmuch)
{
void *r = malloc(howmuch);
if (r == NULL && howmuch != 0)
if (howmuch == 0)
die("Allocating zero bytes. Please report a bug.\n");
if (r == NULL)
die(_("Nano is out of memory!\n"));
return r;
@@ -306,7 +303,10 @@ void *nrealloc(void *ptr, size_t howmuch)
{
void *r = realloc(ptr, howmuch);
if (r == NULL && howmuch != 0)
if (howmuch == 0)
die("Allocating zero bytes. Please report a bug.\n");
if (r == NULL)
die(_("Nano is out of memory!\n"));
return r;
@@ -349,14 +349,12 @@ char *free_and_assign(char *dest, char *src)
return src;
}
/* When not in softwrap mode, nano scrolls horizontally within a line in
* chunks (a bit smaller than the chunks used in softwrapping). Return the
* column number of the first character displayed in the edit window when the
* cursor is at the given column. Note that (0 <= column -
* get_page_start(column) < COLS). */
/* When not softwrapping, nano scrolls the current line horizontally by
* chunks ("pages"). Return the column number of the first character
* displayed in the edit window when the cursor is at the given column. */
size_t get_page_start(size_t column)
{
if (column + 2 < editwincols || ISSET(SOFTWRAP) || column == 0)
if (column == 0 || column + 2 < editwincols || ISSET(SOFTWRAP))
return 0;
else if (editwincols > 8)
return column - 6 - (column - 6) % (editwincols - 8);
@@ -431,9 +429,6 @@ void new_magicline(void)
openfile->filebot->next = make_new_node(openfile->filebot);
openfile->filebot->next->data = copy_of("");
openfile->filebot = openfile->filebot->next;
#ifndef NANO_TINY
openfile->filebot->extrarows = 0;
#endif
openfile->totsize++;
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,8 +8,8 @@ color red "\<[A-Z_]{2,}\>"
color brightgreen "\.(data|subsection|text)"
color green "\.(align|file|globl|global|hidden|section|size|type|weak)"
color brightyellow "\.(ascii|asciz|byte|double|float|hword|int|long|short|single|struct|word)"
color brightred "^[[:space:]]*[.0-9A-Za-z_]*:"
color brightcyan "^[[:space:]]*#[[:space:]]*(define|undef|include|ifn?def|endif|elif|else|if|warning|error)"
color brightred "^[[:blank:]]*[.0-9A-Za-z_]*:"
color brightcyan "^[[:blank:]]*#[[:blank:]]*(define|undef|include|ifn?def|endif|elif|else|if|warning|error)"
# Strings.
color brightyellow "<[^= ]*>" ""(\\.|[^"])*""

View File

@@ -23,7 +23,7 @@ color red ""[^"]*"" "'[^']*'"
color green "`[^`]*`"
# Error lines:
color brightred "^[[:space:]]*\*\*\*.*"
color brightred "^[[:blank:]]*\*\*\*.*"
# Brackets:
color magenta "\[|\]|\(|\)"

View File

@@ -31,7 +31,7 @@ color magenta "\<(bindtextdomain|dcgettext|dcngettext)\>"
# Strings.
color brightyellow "<[^= ]*>" ""(\\.|[^"])*""
# Comments.
color brightblue "(^|[[:space:]])#.*$"
color brightblue "(^|[[:blank:]])#.*$"
# Trailing whitespace.
color ,green "[[:space:]]+$"

View File

@@ -1,14 +1,15 @@
## Syntax highlighting for C and C++ files.
syntax c "\.([ch](pp|xx)?|C|cc|c\+\+|cu|H|hh|ii?)$"
header "-\*-.*\<C(\+\+)?((;|\s).*)?-\*-"
header "-\*-.*\<C(\+\+)?((;|[[:blank:]]).*)?-\*-"
magic "^(C|C\+\+) (source|program)"
comment "//"
# Constants.
color brightred "\<[A-Z_][0-9A-Z_]*\>"
# Labels.
color brightmagenta "^[[:space:]]*[A-Z_a-z]+:[[:space:]]*$"
color brightmagenta "^[[:blank:]]*[A-Z_a-z][0-9A-Z_a-z]*:[[:blank:]]*$"
color normal ":[[:blank:]]*$"
# Types and related keywords.
color green "\<(auto|bool|char|const|double|enum|extern|float|inline|int|long|restrict|short|signed|sizeof|static|struct|typedef|union|unsigned|void)\>"
@@ -25,15 +26,15 @@ color magenta "\<(break|continue|goto|return)\>"
color brightmagenta "'([^'\]|\\(["'\abfnrtv]|x[0-9A-Fa-f]{1,2}|[0-3]?[0-7]{1,2}))'"
# GCC builtins.
color cyan "__attribute__[[:space:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__"
color cyan "__attribute__[[:blank:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__"
# 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 ""([^"]|\\")*"" "#[[:space:]]*include[[:space:]]+<[^[:blank:]=]*>"
color brightyellow ""([^"]|\\")*"" "#[[:blank:]]*include[[:blank:]]*<[^>]+>"
# Preprocessor directives.
color brightcyan start="^[[:space:]]*#[[:space:]]*(if(n?def)?|elif|warning|error|pragma)\>" end="(\`|[^\\])$"
color brightcyan "^[[:space:]]*#[[:space:]]*((define|else|endif|include(_next)?|line|undef)\>|$)"
color brightcyan start="^[[:blank:]]*#[[:blank:]]*(if(n?def)?|elif|warning|error|pragma)\>" end="(\`|[^\\])$"
color brightcyan "^[[:blank:]]*#[[:blank:]]*((define|else|endif|include(_next)?|line|undef)\>|$)"
# Comments.
color brightblue "//.*"

View File

@@ -13,7 +13,7 @@ color red "^(19|20)[0-9-]{8}"
color yellow "<[^>]*@[^>]*>"
# Command-line options.
color cyan "[[:space:]]-[a-zA-Z\$]" "--[8a-z-]+"
color cyan "[[:blank:]]-[a-zA-Z\$]" "--[8a-z-]+"
# Bug and patch numbers.
color cyan "(BZ|bug|patch)[ ]#[0-9]+" "PR [[:alnum:]]+/[0-9]+"
# Probable constants, for variety.

View File

@@ -3,17 +3,17 @@
syntax cmake "(CMakeLists\.txt|\.cmake)$"
comment "#"
color green "^[[:space:]]*[0-9A-Za-z_]+"
icolor brightyellow "^[[:space:]]*(include|include_directories|include_external_msproject)\>"
color green "^[[:blank:]]*[0-9A-Za-z_]+"
icolor brightyellow "^[[:blank:]]*(include|include_directories|include_external_msproject)\>"
icolor brightgreen "^[[:space:]]*((else|end)?if|else|(end)?while|(end)?foreach|break)\>"
color brightgreen "\<(NOT|COMMAND|POLICY|TARGET|EXISTS|IS_(DIRECTORY|ABSOLUTE)|DEFINED)[[:space:]]"
color brightgreen "[[:space:]](OR|AND|IS_NEWER_THAN|MATCHES|(STR|VERSION_)?(LESS|GREATER|EQUAL))[[:space:]]"
icolor brightgreen "^[[:blank:]]*((else|end)?if|else|(end)?while|(end)?foreach|break)\>"
color brightgreen "\<(NOT|COMMAND|POLICY|TARGET|EXISTS|IS_(DIRECTORY|ABSOLUTE)|DEFINED)[[:blank:]]"
color brightgreen "[[:blank:]](OR|AND|IS_NEWER_THAN|MATCHES|(STR|VERSION_)?(LESS|GREATER|EQUAL))[[:blank:]]"
icolor brightred "^[[:space:]]*((end)?(function|macro)|return)"
icolor brightred "^[[:blank:]]*((end)?(function|macro)|return)"
icolor cyan start="\$(ENV)?\{" end="\}"
color magenta "\<(APPLE|UNIX|WIN32|CYGWIN|BORLAND|MINGW|MSVC(_IDE|60|71|80|90)?)\>"
color brightblue "(^|[[:space:]])#.*"
color brightblue "(^|[[:blank:]])#.*"
color ,green "[[:space:]]+$"

View File

@@ -5,7 +5,7 @@ syntax default
comment "#"
# Comments.
color cyan "^[[:space:]]*#.*"
color cyan "^[[:blank:]]*#.*"
# Spaces in front of tabs.
color ,red " + +"

View File

@@ -30,4 +30,4 @@ color blue ":(\w|[?-])+"
color yellow start="^[[:blank:]]+"" end="[^\]""
color yellow ""(\\.|[^"])*""
# Comments
color cyan "(^|[[:space:]]);.*"
color cyan "(^|[[:blank:]]);.*"

View File

@@ -1,5 +1,8 @@
## Syntax highlighting for Go.
## Original author: Robert Clausecker
## License: CC0 (public domain)
syntax go "\.go$"
comment "//"
@@ -8,7 +11,7 @@ formatter gofmt -w
# Types.
color green "\<(bool|u?int(8|16|32|64)?|float(32|64)|complex(64|128)|byte|rune|uintptr|string|error)\>"
color green "\<(chan|const|func|interface|map|struct|type|var)\>"
color green "<-[[:space:]]*chan\>|\<chan[[:space:]]*<-"
color green "<-[[:blank:]]*chan\>|\<chan[[:blank:]]*<-"
# Predefined functions.
color blue "\<(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)\>"
@@ -33,14 +36,14 @@ color red "\<[0-9]+i\>"
color red "\<(true|false|nil|iota|_)\>"
color red "'(\\.|[^'])+'"
color red ""(\\.|[^"])*""
color red start=""(\\.|[^"])*\\[[:space:]]*$" end="^(\\.|[^"])*""
color red start=""(\\.|[^"])*\\[[:blank:]]*$" end="^(\\.|[^"])*""
# Comments.
color brightblue "//.*"
color brightblue start="/\*" end="\*/"
# Special comments.
color brightcyan "//[[:space:]]*\+build[[:space:]]+(([a-zA-Z_0-9]+[[:space:]]*)+,[[:space:]]*)*[a-zA-Z_0-9]+"
color brightcyan "//[[:blank:]]*\+build[[:blank:]]+(([a-zA-Z_0-9]+[[:blank:]]*)+,[[:blank:]]*)*[a-zA-Z_0-9]+"
# Trailing whitespace.
color ,green "[[:space:]]+$"

View File

@@ -13,7 +13,7 @@ color brightmagenta "\\f(.|\(..)" "\\s(\+|\-)?[0-9]"
color cyan "\\(\\)?n(.|\(..)"
color cyan start="\\(\\)?n\[" end="]"
# Requests
color brightgreen "^\.[[:space:]]*[^[:space:]]*"
color brightgreen "^\.[[:blank:]]*[^[:space:]]*"
# Comments
color yellow "^\.\\".*"
# Strings

View File

@@ -21,4 +21,4 @@ color blue "#?:(\w|[?-])+"
color yellow start="^[[:blank:]]+"" end="[^\]""
color yellow ""(\\.|[^"])*""
# Comments
color cyan "(^|[[:space:]]);.*"
color cyan "(^|[[:blank:]]);.*"

View File

@@ -19,7 +19,7 @@ color cyan "\<(true|false|null|undefined)\>"
# Strings.
color brightmagenta ""(\\.|[^"])*"" "'(\\.|[^'])*'" "`(\\.|[^`])*`"
# Comments.
color brightblue "(^|[[:space:]])//.*"
color brightblue "(^|[[:blank:]])//.*"
color brightblue start="/\*" end="\*/"
# Trailing whitespace.

View File

@@ -8,18 +8,18 @@ syntax json "\.json$"
comment ""
# Numbers (used as value).
color green ":[[:space:]]*\-?(0|[1-9][0-9]*)(\.[0-9]+)?([Ee]?[-+]?[0-9]+)?"
color green ":[[:blank:]]*\-?(0|[1-9][0-9]*)(\.[0-9]+)?([Ee]?[-+]?[0-9]+)?"
# Values (well, any string).
color brightmagenta "".+""
# Hex numbers (used as value).
color green ":[[:space:]]*"#[0-9abcdefABCDEF]+""
color green ":[[:blank:]]*"#[0-9abcdefABCDEF]+""
# Escapes.
color green "\\\\" "\\"" "\\[bfnrt]" "\\u[0-9abcdefABCDEF]{4})"
# Special words.
color green "\<(true|false|null)\>"
# Names (very unlikely to contain a quote).
color brightblue ""[^"]+"[[:space:]]*:"
color brightblue ""[^"]+"[[:blank:]]*:"
# Brackets, braces, and separators.
color brightblue "\[" "\]"
@@ -27,7 +27,7 @@ color brightred "\{" "\}"
color brightred "," ":"
# Comments.
color cyan "(^|[[:space:]]+)(//|#).*"
color cyan "(^|[[:blank:]]+)(//|#).*"
# Trailing whitespace.
color ,green "[[:space:]]+$"

View File

@@ -20,7 +20,7 @@ color normal "\.\.\."
color brightblue "\<(do|end|while|repeat|until|if|elseif|then|else|for|in|function|local|return|break)\>"
# Keywords
color brightyellow "\<(_G|_VERSION|assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|load|loadfile|module|next|pairs|pcall|print|rawequal|rawget|rawlen|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)\s*\("
color brightyellow "\<(_G|_VERSION|assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|load|loadfile|module|next|pairs|pcall|print|rawequal|rawget|rawlen|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)[[:blank:]]*\("
# Standard library
color brightyellow "\<coroutine\.(create|isyieldable|resume|running|status|wrap|yield)\>"

View File

@@ -18,7 +18,7 @@ color blue "\$+[{(][a-zA-Z0-9_-]+[})]"
color brightblue "^[^ ]+:"
# Comments.
color green "(^|[[:space:]]+)#.*"
color green "(^|[[:blank:]]+)#.*"
# Trailing whitespace.
color ,green "[[:space:]]+$"

View File

@@ -4,8 +4,14 @@
syntax nanohelp
# Key combos:
color cyan "\^[]/4-8@A-Z\^_`◀▶▲▼]" "[◀▶▲▼]" "\<(M|S[Hh]-[Mm])-." "\<F([1-9]|1[0-9]|2[0-4])"
color cyan "\^[]/4-8@A-Z\^_`◂▸▴▾-]" "[◂▸▴▾]" "\<(M|S[Hh]-[Mm])-[^")”»“」]" "\<F([1-9]|1[0-9]|2[0-4])"
color cyan "\<((Sh-)?Tab|Enter|Ins|(Sh-\^?)?Del|Space|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
# Colorize M-) and M-" only when between parentheses...
color cyan "\(M-(\)|")\)"
color normal " \(|\) "
# ...or when at start of line.
color cyan "^M-(\)|")"
# Quoted indicators:
color brightred "'(\^|M-)'"

View File

@@ -6,27 +6,31 @@ comment "#"
# Everything that does not get recolored is invalid
color brightred ".*"
# Color names
color yellow "^[[:blank:]]*(i?color|set[[:blank:]]+((error|function|key|mini|number|prompt|scroller|selected|spotlight|status|stripe|title)color))[[:blank:]]+(bold,)?(italic,)?(((bright|light)?(white|black|red|blue|green|yellow|magenta|cyan))|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte|grey|gray)?(,(((light)?(white|black|red|blue|green|yellow|magenta|cyan))|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte|grey|gray))?\>"
# Keywords
color brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|boldtext|breaklonglines|casesensitive|constantshow|cutfromcursor|emptyline|historylog|indicator|jumpyscrolling|linenumbers|locking|magic|mouse|multibuffer|noconvert|nohelp|nonewlines|positionlog|preserve|quickblank|rawsequences|rebinddelete|regexp|saveonexit|showcursor|smarthome|softwrap|stateflags|suspendable|tabstospaces|trimblanks|unix|view|wordbounds|zap)\>"
color yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|scroller|selected|status|stripe|title)color)[[:space:]]+(bold,)?(italic,)?(bright|light)?(white|black|red|blue|green|yellow|magenta|cyan|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte)?(,(light)?(white|black|red|blue|green|yellow|magenta|cyan|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte))?\>"
color brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|scrollercolor|selectedcolor|speller|statuscolor|stripecolor|titlecolor|whitespace|wordchars)[[:space:]]+"
color brightgreen "^[[:space:]]*set[[:space:]]+(fill[[:space:]]+-?[[:digit:]]+|(guidestripe|tabsize)[[:space:]]+[1-9][0-9]*)\>"
color brightgreen "^[[:space:]]*bind[[:space:]]+((\^([A-Za-z]|[]/@\^_`]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([][!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+([a-z]+|".*")[[:space:]]+(main|help|search|replace(with)?|yesno|gotoline|writeout|insert|browser|whereisfile|gotodir|execute|spell|linter|all)([[:space:]]+#|[[:space:]]*$)"
color brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([A-Za-z]|[]/@\^_`]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([][!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
color brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|formatter|linter|tabgives)[[:space:]]+.*"
color brightgreen "^[[:space:]]*(syntax[[:space:]]+[^[:blank:]]+|(formatter|linter)[[:space:]]+.+)"
color green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|formatter|linter|tabgives|extendsyntax)\>"
color brightgreen "^[[:blank:]]*(set|unset)[[:blank:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|boldtext|bookstyle|breaklonglines|casesensitive|constantshow|cutfromcursor|emptyline|historylog|indicator|jumpyscrolling|linenumbers|locking|magic|minibar|mouse|multibuffer|noconvert|nohelp|nonewlines|positionlog|preserve|quickblank|rawsequences|rebinddelete|regexp|saveonexit|showcursor|smarthome|softwrap|stateflags|suspendable|tabstospaces|trimblanks|unix|wordbounds|zap)\>"
color brightgreen "^[[:blank:]]*set[[:blank:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|minicolor|numbercolor|operatingdir|promptcolor|punct|quotestr|scrollercolor|selectedcolor|speller|spotlightcolor|statuscolor|stripecolor|titlecolor|whitespace|wordchars)[[:blank:]]+"
color brightgreen "^[[:blank:]]*set[[:blank:]]+(fill[[:blank:]]+-?[[:digit:]]+|(guidestripe|tabsize)[[:blank:]]+[1-9][0-9]*)\>"
color brightgreen "^[[:blank:]]*bind[[:blank:]]+((\^([A-Za-z]|[]/@\^_`-]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([][!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:blank:]]+([a-z]+|".*")[[:blank:]]+(main|help|search|replace(with)?|yesno|gotoline|writeout|insert|browser|whereisfile|gotodir|execute|spell|linter|all)([[:blank:]]+#|[[:blank:]]*$)"
color brightgreen "^[[:blank:]]*unbind[[:blank:]]+((\^([A-Za-z]|[]/@\^_`-]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([][!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:blank:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:blank:]]+#|[[:blank:]]*$)"
color brightgreen "^[[:blank:]]*extendsyntax[[:blank:]]+[[:alpha:]]+[[:blank:]]+(i?color|header|magic|comment|formatter|linter|tabgives)[[:blank:]]+.*"
color brightgreen "^[[:blank:]]*(syntax[[:blank:]]+[^[:space:]]+|(formatter|linter)[[:blank:]]+.+)"
color green "^[[:blank:]]*((un)?(bind|set)|include|syntax|header|magic|comment|formatter|linter|tabgives|extendsyntax)\>"
# Strings
color brightmagenta "([[:space:]]|(start|end)=)".+"([[:space:]]|$)"
color brightmagenta "([[:blank:]]|(start|end)=)".+"([[:blank:]]|$)"
# Colors
color yellow "^[[:space:]]*i?color[[:space:]]*(bold,)?(italic,)?(bright|light)?(white|black|red|blue|green|yellow|magenta|cyan|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte)?(,(light)?(white|black|red|blue|green|yellow|magenta|cyan|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte))?\>"
color magenta "^[[:space:]]*i?color\>" "\<(start|end)="
# Control codes
color bold,pink "[[:cntrl:]]"
# Color commands
color magenta "^[[:blank:]]*i?color\>" "\<(start|end)="
# Comments
color brightblue "(^|[[:space:]]+)#.*"
color cyan "^[[:space:]]*##.*"
color brightblue "(^|[[:blank:]]+)#.*"
color cyan "^[[:blank:]]*##.*"
# Trailing whitespace
color ,green "[[:space:]]+$"

View File

@@ -20,7 +20,7 @@ color red "\<(drop|reject)\>"
color brightblue "\<(accept|continue|(d|s)nat|goto|jump|masquerade|return)\>"
# Comments
color cyan "(^|[[:space:]])#.*"
color cyan "(^|[[:blank:]])#.*"
# Trailing whitespace
color ,green "[[:space:]]+$"

View File

@@ -15,13 +15,13 @@ color brightgreen "\<(goto|continue|break|return)\>"
color brightgreen "@(encode|end|implementation|interface)|selector)\>"
# GCC builtins.
color cyan "__attribute__[[:space:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__"
color cyan "__attribute__[[:blank:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__"
# Selector/method.
color brightmagenta "(^|[[:space:]])\[.*[[:space:]].*\]"
color brightmagenta "(^|[[:blank:]])\[.*[[:blank:]].*\]"
color white ":[[:alnum:]]*"
color magenta "[[:alnum:]]*:"
color white "\[[^][:space:]]*\]"
color white "\[[^][:blank:]]*\]"
# Strings.
color brightblack "'([^'\]|(\\["'abfnrtv\\]))'" "'\\(([0-3]?[0-7]{1,2}))'" "'\\x[0-9A-Fa-f]{1,2}'"
@@ -29,7 +29,7 @@ color brightblack "<[^= ]*>" ""(\\.|[^"])*""
color brightblue "@"(\\.|[^"])*""
# Preprocessor commands.
color brightblue "^[[:space:]]*#[[:space:]]*(define|include|import|(un|ifn?)def|endif|el(if|se)|if|warning|error)"
color brightblue "^[[:blank:]]*#[[:blank:]]*(define|include|import|(un|ifn?)def|endif|el(if|se)|if|warning|error)"
# Comments.
color yellow "//.*"

View File

@@ -12,13 +12,13 @@ color magenta "\<(continue|else|elsif|do|for|foreach|if|unless|until|while|eq|ne
color cyan "[$%&@]([A-Za-z_][0-9A-Za-z_]*|\^[][A-Z?\^_]|[0-9]+)\>"
color cyan "[$%&@]\{(\^?[A-Za-z_][0-9A-Za-z_]*|\^[][?\^][0-9]+)\}"
color cyan "[$%&@]([][!"#'()*+,.:;<=>?`|~-]|\{[][!-/:-@\`|~]\})|\$[$%&@]"
color cyan "(^|[[:space:]])[$%@][/\]"
color cyan "(^|[[:blank:]])[$%@][/\]"
color yellow "".*"|qq\|.*\|"
color white "[sm]/.*/"
color white start="(^use| = new)" end=";"
# Comments.
color green "(^|[[:space:]])#.*"
color green "(^|[[:blank:]])#.*"
color yellow start="<< 'STOP'" end="STOP"

View File

@@ -5,7 +5,7 @@ magic "PHP script"
comment "//"
# PHP markings.
color brightgreen "(<\?(php)?|\?>)"
color brightgreen "(<\?(php|=)?|\?>)"
# Function names.
color white "\<[A-Za-z_][A-Za-z_0-9]*\("
@@ -28,7 +28,7 @@ color magenta "\<(break|continue|goto|return)\>"
color brightyellow ""(\.|[^"])*"" "'(\.|[^'])*'"
# Comments.
color brightblue "(^|[[:space:]]+)//.*"
color brightblue "(^|[[:blank:]]+)//.*"
color brightblue start="/\*" end="\*/"
# Trailing whitespace.

View File

@@ -22,7 +22,7 @@ color brightblue "^(msgid|msgid_plural|msgstr)\>"
color red " fuzzy(,|$)"
color yellow " (no-)?[-[:alpha:]]+-format(,|$)"
# Format specifiers.
color brightmagenta "%([1-9]\$)?[a-z]*"
color brightmagenta "%([1-9]\$)?[#0 +'I-]?(\*([1-9]\$)?|[1-9](\.[0-9]?)?)?[hlLjzt]?[diouxXeEfFgGaAcspnm%]"
# Quotes and escaped characters.
color yellow """
color cyan "\\([abcefnrtv"\]|x[0-9abcdefABCDEF]{2}|[0-7]{3})"

View File

@@ -1,7 +1,7 @@
## Syntax highlighting for Bourne shell scripts.
syntax sh "(\.sh|(\.|/)(a|ba|c|da|k|mk|pdk|tc|z)sh(rc|_profile)?|/(etc/|\.)profile)$"
header "^#!.*/(((a|ba|c|da|k|mk|pdk|tc|z)?sh)|(busybox|env) +sh|openrc-run|runscript)"
header "^#!.*/((env[[:blank:]]+)?((a|ba|c|da|k|mk|pdk|tc|z)?sh)|busybox[[:blank:]]+sh|openrc-run|runscript)\>"
header "-\*-.*shell-script.*-\*-"
magic "(POSIX|Bourne-Again) shell script.*text"
comment "#"
@@ -27,10 +27,10 @@ color normal "[.-]tar\>"
# Basic variable names (no braces).
color brightred "\$[-0-9@*#?$!]" "\$[[:alpha:]_][[:alnum:]_]*"
# More complicated variable names; handles braces and replacements and arrays.
color brightred "\$\{[#!]?([-@*#?$!]|[0-9]+|[[:alpha:]_][[:alnum:]_]*)(\[([[:space:]]*[[:alnum:]_]+[[:space:]]*|@)\])?(([#%/]|:?[-=?+])[^}]*\}|\[|\})"
color brightred "\$\{[#!]?([-@*#?$!]|[0-9]+|[[:alpha:]_][[:alnum:]_]*)(\[([[:blank:]]*[[:alnum:]_]+[[:blank:]]*|@)\])?(([#%/]|:?[-=?+])[^}]*\}|\[|\})"
# Comments.
color cyan "(^|[[:space:]])#.*"
color cyan "(^|[[:blank:]])#.*"
# Strings.
color brightyellow ""(\\.|[^"])*"" "'(\\.|[^'])*'"

View File

@@ -1,22 +1,27 @@
## Syntax highlighting for Tcl files.
## Syntax highlighting for Tcl and Expect scripts.
syntax tcl "\.tcl$"
syntax tcl "\.(tcl|exp)$"
magic "Tcl(/Tk)? script"
comment "#"
# Standard Tcl [info commands]:
color green "\<(after|append|array|auto_execok|auto_import|auto_load|auto_load_index|auto_qualify|binary|break|case|catch|cd|clock|close|concat|continue|encoding|eof|error|eval|exec|exit|expr|fblocked|fconfigure|fcopy|file|fileevent|flush|for|foreach|format|gets|glob|global|history|if|incr|info|interp|join|lappend|lindex|linsert|list|llength|load|lrange|lreplace|lsearch|lset|lsort|namespace|open|package|pid|puts|pwd|read|regexp|regsub|rename|return|scan|seek|set|socket|source|split|string|subst|switch|tclLog|tell|time|trace|unknown|unset|update|uplevel|upvar|variable|vwait|while)\>"
# Basic Tcl subcommands:
color green "\<array (anymore|donesearch|exists|get|names|nextelement|set|size|startsearch|statistics|unset)\>"
color green "\<string (bytelength|compare|equal|first|index|is|last|length|map|match|range|repeat|replace|to|tolower|totitle|toupper|trim|trimleft|trimright|will|wordend|wordstart)\>"
# Extended TclX [info commands]:
color green "\<(alarm|auto_load_pkg|bsearch|catclose|catgets|catopen|ccollate|cconcat|cequal|chgrp|chmod|chown|chroot|cindex|clength|cmdtrace|commandloop|crange|csubstr|ctoken|ctype|dup|echo|execl|fcntl|flock|fork|fstat|ftruncate|funlock|host_info|id|infox|keyldel|keylget|keylkeys|keylset|kill|lassign|lcontain|lempty|lgets|link|lmatch|loadlibindex|loop|lvarcat|lvarpop|lvarpush|max|min|nice|pipe|profile|random|readdir|replicate|scancontext|scanfile|scanmatch|select|server_accept|server_create|signal|sleep|sync|system|tclx_findinit|tclx_fork|tclx_load_tndxs|tclx_sleep|tclx_system|tclx_wait|times|translit|try_eval|umask|wait)\>"
# Syntax:
color brightblue "\<proc[[:space:]]|\{|\}"
color brightblue "\<proc[[:blank:]]|\{|\}"
color green "\(|\)|\;|`|\\|\$|<|>|!|=|&|\|"
color brightyellow ""(\\.|[^"])*"" "'(\\.|[^'])*'"
color brightred "\$\{?[0-9A-Za-z_!@#$*?-]+\}?"
# Trailing whitespace:
color ,green "[[:space:]]+$"
# Comments:
color cyan "^[[:space:]]*#.*"
color cyan "^[[:blank:]]*#.*"