Compare commits

...

285 Commits

Author SHA1 Message Date
9a96973b00 Merge branch 'master' of https://git.savannah.gnu.org/git/nano into line-folding 2025-04-02 15:23:18 -07:00
Benno Schulenberg
186896f072 po: update translations and regenerate POT file and PO files 2025-04-02 11:07:28 +02:00
Benno Schulenberg
78eb483bc2 bump version numbers and add a news item for the 8.4 release 2025-04-02 09:29:24 +02:00
Benno Schulenberg
c7033324a9 gnulib: update to its current upstream state 2025-03-24 10:27:28 +01:00
Benno Schulenberg
334604a591 syntax: po: colorize also format specifiers like "%.6f" 2025-03-17 12:48:04 +01:00
Benno Schulenberg
7905ba80ea docs: add a suggestion to the FAQ on how to configure nano for git 2025-03-17 12:47:15 +01:00
Benno Schulenberg
ccff4685df docs: in the FAQ, replace an old item with an item about Byte Order Marks 2025-03-15 12:08:20 +01:00
Benno Schulenberg
0167f78dca feedback: warn when the cursor sits on a Byte Order Mark (BOM)
The ceck is only done at the start of a line, because in other places
the BOM will be glued to the preceding character.

This partially addresses https://bugs.debian.org/964901.
Reported-by: Nils König <oneric@oneric.de>
2025-03-15 09:17:01 +01:00
Benno Schulenberg
282ec08e5e docs: change two interface colors in the sample nanorc
For esthetics, and to showcase possibilities.
2025-03-14 11:48:29 +01:00
Benno Schulenberg
5efb7f31df tweaks: add a translator hint for the three changed file-writing prompts 2025-03-14 08:07:23 +01:00
Benno Schulenberg
bf39ffe903 prompt: accept tabs in an external paste as literal tabs
This fixes https://savannah.gnu.org/bugs/?66892.

Buglet existed since before version 2.0.0.
2025-03-12 16:59:58 +01:00
Benno Schulenberg
f2c30aa437 prompt: beep when an external paste contains a command code
Until the previous commit, nano used to beep for any command code
in an external paste.  It's better to continue doing that.

(When pasting multiple lines, it's debatable whether nano should
beep for each discarded CR.  But for any other command code, it
definitely should beep.  Maybe it should even show a message.)
2025-03-11 16:27:08 +01:00
Benno Schulenberg
bf12c90b07 input: implement bracketed pastes in a different manner
Ask ncurses to recognize the escape sequences that mark the start
and end of a bracketed paste, and thus benefit from the waiting that
ncurses does for an escape sequence to complete.  This helps prevent
nano from failing to recognize an end-of-paste sequence (resulting
in hanging or inserting some sequence characters into the buffer).

This addresses https://savannah.gnu.org/bugs/?66858 in a better way.
Reported-by: Doug Smythies <dsmythies@telus.net>
2025-03-10 17:17:07 +01:00
Benno Schulenberg
615570cf5e tweaks: remove two commented-out lines and two unused variables
And harmonize some whitespace.
2025-03-09 10:25:45 +01:00
Benno Schulenberg
aff9f4742c input: remove single-keycode detection from the bracketed-paste routine
It interferes with an upcoming change.
2025-03-08 12:08:30 +01:00
Benno Schulenberg
31a2cc9d76 tweaks: swap two fragments of code, to allow unwrapping a line 2025-03-08 12:07:49 +01:00
Benno Schulenberg
9c6a62d319 tweaks: remove an unwanted newline from a debugging message 2025-03-06 12:19:29 +01:00
Benno Schulenberg
38c8845b05 input: remove a special-case workaround
Let the more general flaw handling (added in commit 41c1b962, and
amended in the previous commit) handle also this case: it's better
to let the user know that they are using poor pasting software than
to silently work around the issue.

This effectively reverts commit 555a9878 from last week.
2025-03-06 09:42:53 +01:00
Benno Schulenberg
934d122dd4 input: robustness is good, but dropping a key code is not a good idea
If (on a bogged-down computer) a paste goes so slow that the bytes
come in one by one, nano shouldn't discard any of them -- the user
is unlikely to appreciate this.  Just switch the bracketed paste
off, for the possibility that the closing sequence went missing,
and accept that this closing sequence gets pasted into the buffer.
2025-03-06 09:42:43 +01:00
Benno Schulenberg
f8de98f7cd tweaks: condense a fragment of code 2025-03-04 16:44:32 +01:00
Benno Schulenberg
ef7f825d97 input: adjust file browser and help viewer for changed bracketed pastes
Since the previous commit, the escape-sequence-parsing code does not
set 'bracketed_paste' to FALSE any more when the closing sequence is
deficient.  So, the browser and viewer need to do that themselves.

Also, instead of just beeping and wordlessly discarding a paste when
it's done in the file browser or help viewer, report that it is being
ignored.  This is much more friendly.
2025-03-04 16:44:32 +01:00
Benno Schulenberg
41c1b9623e input: make bracketed paste more robust against loss of closing sequence
A bracketed paste should be one large batch (or several batches)
of bytes, not single bytes coming in one by one.  When the latter
happens, assume the end-of-paste sequence got swallowed somehow,
stop the bracketed paste and display a warning, while discarding
the first byte that came in alone.

This change was inspired by this report from Doug Smythies:
  https://lists.gnu.org/archive/html/nano-devel/2025-02/msg00001.html
2025-03-04 16:44:32 +01:00
Benno Schulenberg
555a987844 input: wait a bit for "~" when bracketed-paste sequence is incomplete
When pasting something into nano over OpenSSH_for_Windows, the final
tilde of the end-of-paste sequence can lag some 29 ms behind the rest
of the sequence, causing ncurses to split it off into a next batch of
bytes.  Accommodate for this by noticing the missing tilde and then
waiting at most one second for it to arrive.  This prevents the tilde
from appearing spuriously in the buffer after the paste.

This addresses https://savannah.gnu.org/bugs/?66858.
Reported-by: Doug Smythies <dsmythies@telus.net>
2025-03-04 16:44:32 +01:00
1d4ac090d8 Merge branch 'master' of https://git.savannah.gnu.org/git/nano into line-folding 2025-02-28 11:42:40 -08:00
Benno Schulenberg
c1df6dfd05 execute: retain what the user typed before a tool was invoked
When the user types something at the Execute prompt and then invokes
one of the six tools or special functions (that don't take any input),
stash the typed string and restore it upon the next invocation of the
Execute menu.  This way the typed string is not lost when the tool or
special function was invoked by accident -- which it likely was, as
those tools and functions don't take any input from the prompt.

This addresses https://savannah.gnu.org/bugs/?66637.
Suggested-by: Evgeny Pestov <fsdhfhhf@gmail.com>
2025-02-28 17:12:43 +01:00
Benno Schulenberg
163c569919 syntax: po: colorize also format specifiers like "%<PRIu64>" 2025-02-28 11:34:42 +01:00
Benno Schulenberg
63a7be115a syntax: po: colorize also a 'msgctxt' line, and the 'c++-format' flag 2025-02-20 13:49:03 +01:00
Benno Schulenberg
fed31f2a79 syntax: po: colorize also Python's "%(name)x" format specifiers 2025-02-17 13:58:35 +01:00
Benno Schulenberg
5d496b3152 syntax: po: colorize also the Python-specific conversion specifier "%r" 2025-02-16 09:44:18 +01:00
Benno Schulenberg
f5a2b8983d syntax: groff: highlight the zeroeth macro argument too
It is used in some .tmac files.
2025-02-15 17:47:20 +01:00
Benno Schulenberg
8f44800588 tweaks: add missing closing quotes, as reported by mandoc -T lint ... 2025-02-15 17:44:16 +01:00
Benno Schulenberg
68c9b6af07 tweaks: prevent some more keywords from getting hyphenated 2025-02-14 17:22:38 +01:00
Benno Schulenberg
8536b4bfcb tweaks: prevent some color keywords from getting hyphenated in man page 2025-02-14 16:50:16 +01:00
Benno Schulenberg
0694c616a2 syntax: man: highlight some escapes, like \& and \(em, specially
This helps prevent reading things like \e and \(em as text.
2025-02-14 16:42:45 +01:00
Benno Schulenberg
8e456bab9f docs: use proper emdashes instead of double hyphens: "--" => "\(em"
Also, remove redundant double quotes, protect single quotes from
possibly getting misinterpreted, and protect periods from getting
treated as end-of-sentence.  Also, use \e instead of \\.

(Overlong lines are left alone -- they don't bother me.)

This partially addresses https://bugs.debian.org/1095957.
Reported-by: Bjarni Ingi Gislason <bjarniig@simnet.is>
2025-02-14 16:29:13 +01:00
Benno Schulenberg
aa663ae386 tweaks: consistently use "\fR" for switching back to normal, roman font 2025-02-12 09:34:29 +01:00
Benno Schulenberg
01c8ffd61f tweaks: avoid running tolower() on an out-of-range value
Functions like tolower() expect characters in the range -1..255.

Reference: https://savannah.gnu.org/bugs/?50289.

The other occurrences of toupper(), tolower(), and isxdigit() that
don't do a cast are fine, because the values of 'code' or 'keycode'
are already guaranteed to be in range by the surrounding code.
2025-02-12 09:34:06 +01:00
Benno Schulenberg
58c7358cb3 tweaks: change the man-page markup of options that take an argument
This is an attempt to work around a bug in the Debian HTML-renderer of
manual pages: see how after "-C" everything is in italics [1], instead
of just the "directory" arguments.  (The renderer for Arch Linux does
even worse, showing the first argument in bold italics [2].)

The old markup was fine, though, as `groff` had no problem generating
properly formatted HTML [3].

[1] https://manpages.debian.org/bookworm/nano/nano.1.en.html
[2] https://man.archlinux.org/man/nano.1.en
[3] https://nano-editor.org/dist/v7/nano.1.html
2025-02-10 16:34:15 +01:00
Benno Schulenberg
1a150bf544 syntax: po: colorize also the %llu and %hhi format specifiers
And colorize %% only by itself, not combined with anything.
2025-02-10 11:04:06 +01:00
Benno Schulenberg
98bab0db07 docs: improve the description of the constantshow bindable function
And of the '--constantshow' and 'set constantshow' options.
2025-01-20 15:25:40 +01:00
Brand Huntsman
b9c65193af files: improve the wording of the normal file-writing prompts
Make them similar to the prompts for writing out a selection.

Signed-off-by: Brand Huntsman <alpha@qzx.com>

(The change was first proposed seven years ago as part of a patch set:
  https://lists.gnu.org/archive/html/nano-devel/2018-02/msg00144.html,
then reposted by myself:
  https://lists.gnu.org/archive/html/nano-devel/2018-02/msg00147.html,
and then... forgotten.)
2025-01-17 11:11:04 +01:00
Benno Schulenberg
20403ef8bb copyright: update the years for the FSF 2025-01-14 11:00:11 +01:00
Benno Schulenberg
e26cdd3dab tweaks: remove three redundant pairs of parentheses from a nanorc regex 2025-01-12 12:32:27 +01:00
Benno Schulenberg
2065713e5c docs: replace a word that is better not used in the plural
Noted by https://fossies.org/linux/misc/nano-8.3.tar.xz/codespell.html.
2024-12-24 17:14:23 +01:00
Benno Schulenberg
a9cf841042 po: update translations and regenerate POT file and PO files 2024-12-21 11:55:15 +01:00
Benno Schulenberg
46466530a5 bump version numbers and add a news item for the 8.3 release 2024-12-21 11:23:05 +01:00
Benno Schulenberg
94ed548366 gnulib: update to its current upstream state 2024-12-20 12:15:44 +01:00
Benno Schulenberg
1e4c69baa7 tweaks: adjust another translator hint, and add two more
The "Prev Line"/"Next Line" tags are shown in the help viewer,
so on an 80-column terminal they may be only 10 cells wide.
2024-12-16 11:16:10 +01:00
Benno Schulenberg
f04c1a6ab5 syntax: markdown: accept also digit 0 in a list marker
For ordered lists, 10., 20., 30., ... were not getting colorized.

Also, https://daringfireball.net/projects/markdown/dingus
accepts 0. by itself just fine as marker.

This addresses https://savannah.gnu.org/patch/?10492.
2024-12-15 11:39:06 +01:00
Benno Schulenberg
6393edf40a tweaks: add a small clarifying comment 2024-12-11 17:12:50 +01:00
Lukáš Zaoral
7fd38e88c1 memory: avoid a leak when linter aborts after producing parsable output
Any collected messages should be freed also after an
abnormal exit of the linter.

Buglet existed since version 2.4.1, commit f225991b.
2024-12-11 08:22:17 +01:00
Benno Schulenberg
ee66c13487 tweaks: adjust a translator hint, and add another one
For the affected four "tags" only 10 character cells are available
(on an 80-column terminal) since they are used in the help viewer.

For the other two "tags" 15 cells are available, as they are shown
only when the terminal is at least 380 columns wide.

Indirectly-reported-by: Rafael Fontenelle <rafaelff@gnome.org>
2024-11-24 17:41:04 +01:00
Benno Schulenberg
250192c603 tweaks: drop six unneeded casts
The cast is implied by the type of the assignee.
2024-11-24 17:41:02 +01:00
Benno Schulenberg
9d181a1cc6 build: fix a compilation error with gcc-15
Assigning a pointer to a boolean variable without a cast
is not accepted any more.

This addresses https://savannah.gnu.org/bugs/?66467.
Reported-by: Rudi Heitbaum <rudi@heitbaum.com>
2024-11-20 13:06:22 +01:00
LIU Hao
07a92c3988 syntax: asm: add end-of-word anchors to the keywords
Previously some of these regexes could color part of a directive;
for example, the `.int` part of `.intel_syntax`.

Signed-off-by: LIU Hao <lh_mouse@126.com>
2024-11-05 17:12:25 +01:00
Benno Schulenberg
e9b0a57490 docs: put a space after "|" and before "{enter}" in the sample nanorc
This makes the example bindings slightly more legible.

Also improve a comment.
2024-11-04 16:22:07 +01:00
Benno Schulenberg
2fca581095 syntax: groff: correct the mistaken .rof extension to .roff
Buglet existed since version 2.9.8, commit cdd637d6.
2024-10-23 11:14:48 +02:00
Benno Schulenberg
53afd90ad4 syntax: groff: recognize also the .mom extension
This addresses https://savannah.gnu.org/bugs/?66369.
Reported-by: Elfener <elfenermarcell@gmail.com>
2024-10-23 11:07:05 +02:00
Benno Schulenberg
d9ea07515b docs: clarify the possible effects of a misuse of braced function names
And fix a nearby grammatical mistake that was
caused by commit 77a8841d from four months ago.

Inspired-by: Max Gammache <bigjango13@gmail.com>
2024-10-20 17:19:27 +02:00
Benno Schulenberg
de82920819 docs: add Shift+PgUp/PgDown to the FAQ item about urxvt modified keys
So that those keystrokes will select text per screenful also on urxvt.

Inspired-by: Sébastien Desreux <seb@h-k.fr>
2024-10-12 12:57:15 +02:00
Benno Schulenberg
9a842e4bf2 tweaks: add a translator hint
This should help translators to avoid mistakenly interpreting
"Home" and "End" as names of keys.
2024-10-11 11:59:01 +02:00
9cfda05f71 Merge remote-tracking branch 'upstream/master' into line-folding 2024-10-06 17:43:50 -07:00
Benno Schulenberg
1862995aab syntax: spec: colorize all canonical architecture names
The list of canonical names was found in:
  https://github.com/rpm-software-management/rpm/blob/master/rpmrc.in

The canonical names were extracted with:

  grep arch_canon rpmrc.in | sed 's/^.*:\s*//' | sed 's/\s*..\?$//'

and then sorted and condensed into a regular expression.

Inspired-by: Funda Wang <fundawang@gmail.com>
2024-09-22 12:34:28 +02:00
Benno Schulenberg
468613c9db syntax: makefile: colorize also multiple targets
Multiple targets are separated by spaces.  Furthermore, there
may be spaces before the first target and before the colon.
2024-09-06 13:56:56 +02:00
Benno Schulenberg
28642cd047 po: update translations and regenerate POT file and PO files 2024-09-05 11:41:30 +02:00
Benno Schulenberg
f96f3546c7 bump version numbers and add a news item for the 8.2 release 2024-09-05 09:18:12 +02:00
Benno Schulenberg
205066ed12 gnulib: update to its current upstream state 2024-09-04 14:52:27 +02:00
Benno Schulenberg
7e8ee46c09 syntax: autoconf: colorize the keywords 'case', 'esac', and 'ifelse' too
Case statements occur a lot in gnulib's m4 files,
and 'ifelse' is simply part of the m4 language.
2024-08-28 17:12:17 +02:00
Collin Funk
d1e2febb6d build: update a symbol that was renamed in gnulib
As noted in a gnulib NEWS item of 2023-01-07, linking now happens
against $(CLOCK_TIME_LIB) instead of $(LIB_CLOCK_GETTIME).
2024-08-27 10:20:56 +02:00
Benno Schulenberg
3d0273de45 tweaks: improve or rewrap six comments, and add two missing ones
Also, stop initializing three variables that don't need it.
2024-08-17 10:37:41 +02:00
Benno Schulenberg
109386dfe8 syntax: nanorc: an unquoted argument of 'include' may not contain blanks
Anything after the first "word" after 'include' will be ignored
and should thus remain colorized in bright red.
2024-08-16 15:49:28 +02:00
Benno Schulenberg
ebddb49041 docs: do not quote the argument of 'include' statements in sample nanorc
This avoids those arguments getting colorized as if they were regexes
(when the relevant lines are uncommented), and instead allows them to
get colorized in bold purple by a dedicated rule.
2024-08-16 15:42:37 +02:00
Benno Schulenberg
b5f320a2f9 tweaks: delete three redundant checks from the undo/redo code
Since commit 50954a4b from two years ago, a replacing session will
not ever change the final empty line, and thus a fresh magic line
will never need to be undone or redone.

This complements commit c6a26641 from five months ago.
2024-08-12 08:41:58 +02:00
Benno Schulenberg
7568bd9af5 docs: trim stuff that is more than four years old from the changelog
A detailed list of changes is useful for just a small number of users,
and only when the changes are fairly recent.
2024-08-12 08:39:57 +02:00
Benno Schulenberg
0384c251ff docs: mention former maintainership last among an author's contributions 2024-08-10 17:36:31 +02:00
Benno Schulenberg
b812ad2926 tweaks: unwrap three lines that don't need to be wrapped
(These lines were noticed while checking that all
calls of nrealloc() use a size bigger than zero.)
2024-08-04 16:09:42 +02:00
Benno Schulenberg
fe0b928b39 tweaks: move a condition to the only place that needs it
Most calls of draw_all_subwindows() are made while in the edit window.
The only call that could occur while in the file browser is the one in
regenerate_screen().  So only this call needs to be guarded against
being made while the file list is being shown.
2024-07-31 10:04:00 +02:00
Benno Schulenberg
4b1a81e773 docs: mention the availability of ^Y, ^N, and ^A at a Yes-No prompt 2024-07-28 13:55:31 +02:00
Benno Schulenberg
af2f218192 bindings: at a Yes-No-All prompt, accept also ^A for "All"
This can be useful when replacing text in a Japanese locale,
avoiding the need to guide the input method to produce "A".

Inspired-by: Takeshi Hamasaki <hmatrjp@users.sourceforge.jp>
2024-07-28 13:54:41 +02:00
Benno Schulenberg
572247dbd8 tweaks: reshuffle a seldom-used function to the end of an if-else series 2024-07-22 15:43:37 +02:00
Benno Schulenberg
c5a0e6b60c syntax: awk: colorize escape sequences specially 2024-07-21 14:32:56 +02:00
9c2ec9f3af Merge remote-tracking branch 'upstream/master' into line-folding 2024-07-19 13:41:12 -07:00
Benno Schulenberg
d7e8665782 syntax: awk: rewrite a regex more densely, and add the missing ~ operator
Also, improve the comment.
2024-07-18 16:14:25 +02:00
Benno Schulenberg
7c86c1a185 syntax: awk: add a missing "|" between "\?" and ":"
The "\?" and ":" are meant to match the ? and : in this construct:

    condition ? thenthis : otherwisethis

The missing "|" seems to have been a typo.
2024-07-18 13:02:54 +02:00
Benno Schulenberg
4b03cc60cf moving: for Alt+Home/Alt+End, refresh the screen when the mark is on
When the mark is on, moving the cursor to the top or bottom row should
highlight the relevant area -- thus requiring a call of edit_refresh()
to be scheduled.

Also, drop two calls of place_the_cursor(), as that is done anyhow in
the main loop, either directly, or indirectly through edit_refresh().

This fixes https://savannah.gnu.org/bugs/?65992.
Reported-by: Tasos Papastylianou <tpapastylianou@hotmail.com>

Bug existed since version 8.0, since Alt+Home/Alt+End were introduced.
2024-07-17 17:23:12 +02:00
Benno Schulenberg
c356db9f44 macro: insert it in keystroke buffer without discarding latter's contents
Instead of simply overwriting the current contents of the keystroke
buffer with the contents of the macro buffer, insert the latter's
contents at the head of the keystroke buffer.

This allows using {runmacro} in a string bind, and allows typing ahead
over a laggy connection after invoking `runmacro` (normally with M-;).

This fixes https://savannah.gnu.org/bugs/?65991.
Reported-by: Tasos Papastylianou <tpapastylianou@hotmail.com>

Bug exists since version 2.9.4, since string binds were introduced.
2024-07-16 16:44:48 +02:00
Benno Schulenberg
c53839cefa tweaks: rename a symbol, away from an obscure abbreviation
Also, reshuffle its definition, and change its value to match
other special codes.
2024-07-15 09:38:01 +02:00
Benno Schulenberg
887803cb67 bindings: let the central numpad key (with Ctrl) center the current line
When NumLock is off, let Ctrl plus the central key on the numeric keypad
center the current line.

(This binding is not advertised anywhere
-- it's left as a little Easter egg.)
2024-07-15 09:37:48 +02:00
Benno Schulenberg
f69a08fc63 syntax: man: colorize also the .MT .ME .EX .EE .SY .OP and .YS macros
Furthermore, colorize .LP .P and .PP like .TP, as paragraph macros,
instead of inconsistenly as if they specified type faces.
2024-07-15 07:48:14 +02:00
Benno Schulenberg
4ddd61cfde po: update translations and regenerate POT file and PO files 2024-07-12 11:23:42 +02:00
Benno Schulenberg
fe39d137c7 bump version numbers and add a news item for the 8.1 release 2024-07-12 10:57:24 +02:00
Benno Schulenberg
ade975891b tweaks: add a space after a '+', for consistent formatting 2024-07-07 17:11:30 +02:00
Benno Schulenberg
479e56bdd6 tweaks: slightly reword a phrase in the explanation of --colonparsing 2024-07-07 14:27:02 +02:00
Benno Schulenberg
e5d36de24c tweaks: discard a bracketed paste in the help viewer with fewer beeps
The same change was made for the file browser two years ago,
in commit b561c386.
2024-07-07 14:25:04 +02:00
Benno Schulenberg
d824c4e633 docs: properly escape a literal '@' in the texi document
This avoids a failing `make pdf`.

Problem existed since commit 4930fbbb from five weeks ago.
2024-07-01 15:45:51 +02:00
Benno Schulenberg
f499635461 gnulib: update to its current upstream state
Also, stop distributing 'wchar_t.m4', as it was removed from gnulib
two weeks ago.
2024-07-01 11:07:03 +02:00
Benno Schulenberg
e8cf0f37f1 docs: add 'set colonparsing' to the sample nanorc 2024-06-18 15:55:00 +02:00
Benno Schulenberg
12a0c0f690 tweaks: rewrap some lines, for more even lengths
Also, slightly improve a few descriptions.
2024-06-18 10:53:28 +02:00
Benno Schulenberg
77a8841d25 tweaks: elide unhelpful occurrences of the word "will"
In most cases, "will" is just a filler word and doesn't improve clarity.

And in the bargain improve two descriptions.
2024-06-18 09:56:01 +02:00
Benno Schulenberg
7d8f13b9f7 build: use the standard autoreconf invocation
As version 0.20 of `autopoint` no longer overwrites 'extern-inline.m4',
there is no need any more for the custom calls of the various parts of
`autoreconf`.

This effectively reverts commit 4a1db96d from two and a half years ago.
2024-06-17 11:07:40 +02:00
Benno Schulenberg
ec177c84b3 build: require version 0.20 of gettext for building nano from git
Gettext-0.20 is the first version where its `autopoint` does not
overwrite the newer 'extern-inline.m4' from gnulib.

Version 0.20 is five years old, so most users will be on a distro
that includes that version of gettext or a newer one.
2024-06-17 09:50:08 +02:00
Benno Schulenberg
3809c67bb2 docs: add the Alt+Home/Alt+End shortcuts to the cheatsheet
Also, reshuffle Alt+T for balance, slightly reword the description
of Alt+A (as it differs in nature from the other toggles), and add
some spaces for better alignment.
2024-06-17 09:10:07 +02:00
Benno Schulenberg
dff779e3ad tweaks: in FAQ, use 'id' attribute instead of empty anchor with 'name'
The 'name' attribute for the <a> tag is deprecated -- 'id' is the
standard attribute that can be used in almost every tag.
2024-06-17 09:09:37 +02:00
Benno Schulenberg
ef1c9b9f2b tweaks: implement do_center() with a single call instead of three
This works because the main loop sets 'cycling_aim' to zero
whenever the current keystroke is not bound to `cycle`.
2024-06-15 09:57:06 +02:00
Benno Schulenberg
90e62db26e help: regroup the center item, placing it with the new cycle 2024-06-15 09:57:06 +02:00
Benno Schulenberg
498154804c bindings: let ^L put the cursor line at center, then top, then bottom
Something similar can be achieved with:

  bind ^T "{center}{bottomrow}{center}{toprow}" main
  bind ^B "{center}{toprow}{center}{bottomrow}" main

But that requires allocating two extra shortcuts, and it works right only
when the edit window has an odd number of rows, not with an even number.
Also, this new ^L behavior is available by default, out-of-the-box.
2024-06-15 09:57:06 +02:00
Benno Schulenberg
34dda64610 docs: explain the behavior of the new function cycle
Also colorize {cycle} when found in a nanorc file.
2024-06-15 09:57:06 +02:00
Benno Schulenberg
d1c723bc14 new feature: add bindable function cycle that pushes cursor line around
On the first call, `cycle` centers the line with the cursor, on the
second consecutive call it pushes that line to the top of the viewport,
and on the third consecutive call to the bottom of the viewport.
2024-06-15 09:57:06 +02:00
Benno Schulenberg
d477bfd4ee tweaks: drop two redundant conditions
The function do_tab() is only ever called when in the main edit window,
and never called while a bracketed paste is in progress.

(The two conditions were thoughtlessly copied when this fragment of code
was moved here three commits ago.)
2024-06-10 14:07:30 +02:00
Benno Schulenberg
6c81f60914 moving: use edit_scroll() only when scrolling one row is enough
When softwrapping with a tabsize larger than the width of the viewport,
scrolling one row when the cursor goes offscreen might not be enough,
so in that case use edit_redraw() instead.

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

Bug existed since version 2.9.6, commit 0d9080a2.
2024-06-10 08:15:28 +02:00
Benno Schulenberg
aa844ada4e tweaks: remove the now unneeded special keycode INDENT_KEY 2024-06-09 16:48:06 +02:00
Benno Schulenberg
9b7a813069 text: do not check for <Tab> + mark while getting input but in do_tab()
This allows a {tab} in a string bind to indent a marked region.

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

Problem existed since version 7.0, since braced function names
were introduced.
2024-06-09 16:42:14 +02:00
baadfa34f1 Merge branch 'master' of https://git.savannah.gnu.org/git/nano into line-folding 2024-06-09 07:27:29 -07:00
Benno Schulenberg
bc09f0992e tweaks: reshuffle some lines, to put vaguely related things together
And to slightly reduce the number of #ifdefs.
2024-06-08 17:08:17 +02:00
Benno Schulenberg
00e2309987 tweaks: make the inclusion condition for do_center() more strict
There is no reason why --enable-help should cause the centering function
to be included in a tiny version.
2024-06-08 16:56:52 +02:00
Benno Schulenberg
a98f82e27b startup: no not activate --modernbindings when name starts with "e"
Activating --modernbindings when the binary's name starts with "e"
interferes with Debian's alternatives system that symlinks `editor`
to `nano` in a default install.

(Also: why "e"?  It would have made more sense to check for "m",
similar to the checking for "r" for a restricted nano.)

This reverts commit 580eaf29 from fifteen months ago.

This addresses https://savannah.gnu.org/bugs/?65810.
Reported-by: Colin Snover <nano@zetafleet.com>
2024-06-08 12:14:08 +02:00
Benno Schulenberg
c70e6919c2 syntaxes: mention the original author of most of the syntax files
The names of the authors were retrieved from:

  git log -p --follow  syntax/<name>.nanorc

and from:

  git log -p --follow --all --  doc/nanorc.sample

For some files the original author is unclear, or
the file is/was too small to mention an author for.
2024-06-08 12:10:25 +02:00
Jaroslav Fowkes
abdf069ce3 syntax: fortran: fix a typo (a missing backslash)
The typo prevented several keywords from getting colorized.

This addresses https://savannah.gnu.org/patch/?10459.

Bug existed since version 2.1.6, commit 513157df,
since the Fortran syntax was introduced.
2024-06-07 15:34:03 +02:00
Benno Schulenberg
6be1f7e95a docs: avert hyphenation of the technical words "ncurses" and "terminfo"
This prevents an observed wrong hyphenation: "ter-minfo".

Also, add markup for "terminfo", like "ncurses" already has.
2024-06-07 14:57:02 +02:00
Benno Schulenberg
a1159ff484 syntax: man: colorize some of the things that manipulate hyphenation
Reference:
  https://www.gnu.org/software/groff/manual/groff.html.node/Manipulating-Hyphenation.html
2024-06-06 13:29:01 +02:00
Benno Schulenberg
0c2caa50cc docs: correct the description of --bold, as function tags are unaffected
The succinct function descriptions in the help lines are not shown in
reverse video by default, so they are not bolded by -D/--bold either.

Also, mention 'promptcolor' and 'minicolor' where they were missing.
2024-06-04 17:01:11 +02:00
Benno Schulenberg
dcbbbf8134 input: make sure that a string-bind return value is non-negative
A negative value would lead to misinterpretation by parse_kbinput().

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

Bug existed since version 8.0, commit 51c9f727.
2024-06-03 15:40:03 +02:00
Benno Schulenberg
05602e29cd syntax: patch: recognize also the .rej extension
The addition was inspired by `davidhcefx`.
2024-06-02 17:16:22 +02:00
Benno Schulenberg
cd53f7cf8c docs: don't say any more that -z was removed, as it has been repurposed 2024-06-02 09:23:09 +02:00
Benno Schulenberg
689748843c files: with --rectrict, prevent invoking the browser and toggling backups
Prevent also the toggling of Append and Prepend.  All four functions
should not be available in restricted mode, and are absent from the
WriteOut menu in that mode, but using {browser}, {backup}, {append}
or {prepend} in a string bind allowed to bypass the menu checks.

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

Problem existed since version 7.0, since braced function names
were introduced.
2024-06-01 11:31:09 +02:00
Benno Schulenberg
ea07eb6aa3 help: show option -Y/--syntax in --help output also in restricted mode
Since version 3.2, commit 5ca444e5, nano reads the nanorc files also
in restricted mode (when not also --ignorercfiles is given), meaning
that syntaxes are available and that a specific syntax can be selected
on the command line.  So, the --help output in restricted mode should
list the relevant option: -Y<name> / --syntax=<name>.

(This should have been part of commit b81995af from six years ago.)
2024-06-01 11:00:49 +02:00
Benno Schulenberg
5251ce1b20 tweaks: simplify a condition, to match the same condition five lines back 2024-06-01 09:30:44 +02:00
Benno Schulenberg
b3780aab33 docs: remove the 'filename:linenumber' format from the synopsis
(This should have been part of commit 4930fbbb from five days ago.)
2024-05-31 16:48:08 +02:00
Benno Schulenberg
5bc6d0ef2e tweaks: extend the deprecation period of 'set nowrap' and prefix 'bright' 2024-05-31 16:41:46 +02:00
Benno Schulenberg
b92cbf5f09 rcfile: remove old bindable function 'nowrap', alias of 'breaklonglines'
The bindable function 'nowrap' has been deprecated for three years,
since version 5.5, commit e14127b8.

(The obsolete options --nowrap and 'set nowrap' continue to exist.)
2024-05-31 15:57:01 +02:00
Benno Schulenberg
c26f901ba9 options: remove the deprecated synonym -$ of -S/--softwrap
The old short option -$ has been deprecated for four years,
since version 5.0, commit 7d3aad40.
2024-05-31 12:45:18 +02:00
Benno Schulenberg
a590645cde docs: document the new --listsyntaxes (-z) option 2024-05-31 11:14:24 +02:00
Benno Schulenberg
49c2f5dea9 new feature: option -z lists the names of available syntaxes
When one has installed additional syntaxes, one tends to forget
what exactly is there.  So it's nice to be able to list them.

The syntaxes are listed in the reverse order in which they were
read: the most recent first.

The long form of the option is, of course, --listsyntaxes,
which can be abbreviated to --list.

This fulfills https://savannah.gnu.org/bugs/?65779.
The feature was suggested by `davidhcefx`.
2024-05-31 11:14:24 +02:00
Benno Schulenberg
b408147f48 tweaks: exclude the colon-parsing code from the tiny version
The option --colonparsing is not available in the tiny version,
so there is no need for the code either.
2024-05-28 17:12:30 +02:00
Benno Schulenberg
4930fbbba7 docs: explain the details of --colonparsing / -@ / 'set colonparsing'
Also, remove the earlier explanation, when colon parsing was still
done by default.
2024-05-26 17:11:09 +02:00
Benno Schulenberg
02dd0b4ed5 options: require --colonparsing/-@ to parse colon+number after a filename
Stop doing colon parsing by default, to avoid surprises and frustration
for users that have filenames that end in a colon plus digits.

The equivalent rcfile option is, of course, 'set colonparsing'.

Using +1, or similar, before the filename disables any colon parsing
and the filename is taken as is.
2024-05-25 16:48:35 +02:00
Benno Schulenberg
add945e717 files: look for digits and colons starting from the end of the filename
Starting from the end of the provided filename avoids needlessly looking
at colons that are somewhere in the middle of the path or the filename.

It also avoids inconsistenly interpreting a specified line number as a
column number when the filename itself ends with a colon plus digits
and the filename without the colon plus digits exists too.

This also removes the eliding of a backslash before a colon, which
would mangle the filename if the name actually contained a backslash
followed by a colon.

Negative line and column numbers are no longer allowed when using the
colon notation.

This fixes https://savannah.gnu.org/bugs/?65781,
and fixes https://savannah.gnu.org/bugs/?65782.

Problems existed since version 8.0, since colon parsing was introduced.
2024-05-25 16:48:24 +02:00
Benno Schulenberg
259a3c70e3 general: disable the type-ahead checking that ncurses normally does
While updating the screen, ncurses by default polls the input source
now and then to see if there is new input, and if so, stops updating
the screen and waits for the next call of doupdate() or refresh().

  https://lists.gnu.org/archive/html/bug-ncurses/2024-05/msg00077.html

Disable this polling, as it is just a waste of time, and there *might*
be situations where the intruding keystroke does not actually trigger
a new update, which could result in a half-updated screen.
2024-05-20 17:14:09 +02:00
Benno Schulenberg
2445e77535 files: avoid mistakenly setting the column number to a given line number
When the file 'foo:24' exists (but not 'foo') and the user wants to
use the colon notation to place the cursor on a certain line, then
nano would first interpret the given line number as a column number,
before noticing that 'foo' does not exist and then skipping the first
colon.  So, when such a misinterpretation occurs, the column number
needs to be reset to zero.
2024-05-18 16:02:09 +02:00
Benno Schulenberg
d64235eb6e tweaks: reshuffle a declaration, adjust a comment, normalize indentation 2024-05-18 16:02:09 +02:00
Benno Schulenberg
54c8cb8c81 files: when a filename with a colon and digits exists, open that file
When the user specifies, on the command line, a filename that ends with
a colon plus digits, and that filename exists in the file system, then
open that file, instead of interpreting the digits as a line number.

Also, if the filename stripped of the colon plus digits does not exist,
then do not interpret the digits as a line number either but treat them
as part of the file name.

Before this change, the user would have to escape the colon whenever
they wanted to open a file whose name ended with a colon plus digits.
Now the user needs to escape the colon only when 'foo' exists and they
want to create, say, 'foo:24'.

Problem-was-reported-by: Ralph Corderoy <ralph@inputplus.co.uk>
  https://lists.gnu.org/archive/html/nano-devel/2024-05/msg00001.html
Mitigation-was-suggested-by: Mike Scalora <mike@scalora.org>
  https://lists.gnu.org/archive/html/nano-devel/2024-05/msg00008.html
2024-05-18 16:02:09 +02:00
758130f5b9 Merge in upstream changes 2024-05-14 19:11:00 -07:00
Benno Schulenberg
803a16cbcd input: drop recognition of the urxvt escape sequences for M-Home/M-End
Nano does not recognize the urxvt escape sequences for other
<Alt+cursorkey> combinations either.  And with the previous
two commits, the urxvt user can now "help themselves".

This reverts commit 363a4378 from three days ago.
2024-05-14 16:39:34 +02:00
Benno Schulenberg
0b43c8da11 docs: extend the FAQ item about urxvt modified keys, with M-Home/M-End 2024-05-14 16:39:14 +02:00
Benno Schulenberg
c446904c19 input: recognize the raw Xterm escape sequences for Alt+Home and Alt+End
This makes those keystrokes work too when --raw is used.

But more importantly: these raw sequences can be used in an
~/.Xresources file to override the odd behavior of urxvt for
those keystrokes, making the previous commit redundant.
2024-05-12 10:27:35 +02:00
Benno Schulenberg
363a4378b7 input: provide for urxvt setting a high bit or sending an extra escape
When pressing Alt+Home/Alt+End on urxvt, urxvt either sets the high bit
of the last byte in the sequence for Home/End (when Meta8 is True), or
sends an extra escape before that same sequence (when Meta8 is False).
Accommodate for this bug by recognizing the produced code sequences.

Indirectly-reported-by: Sébastien Desreux <seb@h-k.fr>
  https://lists.gnu.org/archive/html/nano-devel/2024-05/msg00007.html
2024-05-11 16:28:04 +02:00
Benno Schulenberg
f70f528730 build: check for the correct function in an #ifdef
Problem existed since version 7.0, commit 19c8cea8,
that replaced calls of wait() with calls of waitpid().
2024-05-05 10:43:23 +02:00
Benno Schulenberg
2334dedba6 tweaks: make a comment more accurate, and unabbreviate a variable name 2024-05-05 10:27:21 +02:00
Benno Schulenberg
e9c7dfa992 minibar: do not falsely report that a new, empty file is in Mac format
The 'openfile->fmt' element gets initialized to 'UNSPECIFIED',
so the code has to take that possibility into account.

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

Bug existed since version 8.0, commit fe4f74f6.
2024-05-03 12:12:09 +02:00
Benno Schulenberg
33eaf3e947 po: update translations and regenerate POT file and PO files 2024-05-01 10:42:51 +02:00
Benno Schulenberg
ce5513b009 bump version numbers and add a news item for the 8.0 release 2024-05-01 10:10:15 +02:00
Benno Schulenberg
a98b03e46e tweaks: rewrap two old news items 2024-04-28 16:49:09 +02:00
Benno Schulenberg
e4c3ffcd38 tweaks: rename a variable, away from an abbreviation 2024-04-28 13:45:08 +02:00
Benno Schulenberg
5e7a3c2e7e files: run chmod and chown on the descriptor, not on the filename
This closes a window of opportunity where the emergency file could be
replaced by a malicious symlink.

The issue was reported by `MartinJM` and `InvisibleMeerkat`.

Problem existed since version 2.2.0, commit 123110c5, when chmodding
and chowning of the emergency .save file was added.
2024-04-28 10:56:21 +02:00
Benno Schulenberg
c020d53e23 input: snip the recordmacro and runmacro keystrokes in a better way
When recording a macro over a laggy connection or on a slow, overloaded
computer, several keystrokes could be recorded in one burst, and if any
but the last of those keystrokes was the shortcut for `runmacro`, then
running the macro would lead to an infinite loop and nano would hang.

This new implementation of snipping the "last keystroke" will, however,
snip *too many* keystrokes when several of them were recorded at once
and `runmacro` or `recordmacro` was among them, resulting in a cropped
and thus misrecorded macro.  But... that's better than hanging.

In general, though, the user should be slow and deliberate when
recording a macro: waiting for nano to have processed the last
keystroke before typing the next.

This fixes https://savannah.gnu.org/bugs/?65649.
The issue was reported by `correctmost`.

Problem existed since version 2.9.0, since macros were introduced.
2024-04-27 17:17:03 +02:00
Benno Schulenberg
cb02937714 wrapping: delete only single characters, not a possibly marked region
These calls of do_delete() were meant to delete just one character,
but over time do_delete() morphed into doing also other things...
Change the calls to invoke the correct function instead.

(This also avoids snipping any zero-width characters that come after
a snipped space, as that is probably not what the user wants.)

This fixes https://savannah.gnu.org/bugs/?65636.
The issue was reported by `correctmost`.

Bug existed since version 3.2, commit ae3ec178,
when --zap was introduced.
2024-04-25 11:01:42 +02:00
Benno Schulenberg
1327e296c2 tweaks: rename a function, for contrast, and update antiquated comments 2024-04-25 10:34:03 +02:00
Benno Schulenberg
d53521a631 syntax: sh: recognize more shells than sh on a shebang line for busybox
Also, elide an unneeded pair of parentheses.

Original-patch-by: Sertonix <sertonix@posteo.net>
  https://lists.gnu.org/archive/html/nano-devel/2024-04/msg00026.html
2024-04-22 10:29:02 +02:00
Benno Schulenberg
5beb14cffe softwrap: realign start-of-screen when redoing an automatic hard-wrap
Redoing an automatic hard-wrap while one or more chunks of the affected
line are offscreen, can leave 'firstcolumn' with a value that doesn't
fit the situation.  So, make sure that it has a valid value.

This complements the previous commit.

This fixes https://savannah.gnu.org/bugs/?65611.
The issue was reported by `correctmost`.

Bug existed since version 2.8.6, commit e375995d.
2024-04-19 16:11:14 +02:00
Benno Schulenberg
7b07e1ee5c softwrap: adjust start-of-screen when the 'edittop' line is hard-wrapped
When one or more chunks of the current line are above the viewport,
and this line gets hard-wrapped, then 'edittop' needs to be advanced,
otherwise the first row could be blank -- representing a chunk that
doesn't exist any more.

This fixes https://savannah.gnu.org/bugs/?65604.
The issue was reported by `correctmost`.

Bug existed since version 2.8.6, commit e375995d.
2024-04-17 17:12:09 +02:00
Benno Schulenberg
c02aec557c syntax: makefile, sh: recognize also a fresh Makefile and fresh .profile
When opening a nonexistent file with nano, it likely consists of only a
name without any path component, and thus without any slash.  So when a
file regex checks for a slash, it should check also for start-of-string.

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

Problem existed for the Makefile since version 2.9.8, commit 22663f8a,
and for .profile since version 3.0, commit 4a268678 (but earlier, nano
did not recognize .profile files at all).
2024-04-14 12:09:36 +02:00
Benno Schulenberg
c695d49a86 editing: adjust the mark before trimming redundant blanks
When an entirely blank line is trimmed (when --autoindent is active and
Enter is pressed while the cursor is at the end of the current indent),
the mark needs be adjusted *before* 'current_x' is zeroed, otherwise the
mark gets moved too much to the right, which causes the region to become
bigger than what the user intended, or leads to accessing unallocated
memory.

This fixes https://savannah.gnu.org/bugs/?65586.
The issue was reported by `correctmost`.

Bug existed since version 2.8.1, commit 005ee8ed.
2024-04-13 16:24:18 +02:00
Benno Schulenberg
3cd3ba0397 gnulib: update to its current upstream state 2024-04-12 10:57:03 +02:00
Benno Schulenberg
829ab5e72d syntax: nanorc: colorize {toprow} and {bottomrow} for string binds 2024-04-07 15:55:38 +02:00
Benno Schulenberg
4ae8082552 files: do not allow M-U to remove text read from standard input
This fixes https://savannah.gnu.org/bugs/?65565.

Problem existed since version 2.1.8, commit 25d459aa,
since reading from standard input was introduced.
2024-04-07 11:33:34 +02:00
Benno Schulenberg
2c8d57fbb2 docs: document the new bindable functions 'toprow' and 'bottomrow' 2024-04-07 10:57:07 +02:00
Benno Schulenberg
e51a28e492 rcfile: add bindable functions for moving the cursor to top or bottom row 2024-04-07 10:47:03 +02:00
Benno Schulenberg
72c83badf6 feedback: lowercase a letter, as the phrase is not a full sentence
It could also have been after a comma (instead of between parentheses).
2024-04-07 10:39:06 +02:00
Benno Schulenberg
fe4f74f631 minibar: mention the file format when it's DOS or Mac
This provides feedback about the file format in a better way than
how it was done until the previous commit.
2024-04-07 10:27:21 +02:00
Benno Schulenberg
2b335060b0 feedback: suppress format-conversion messages for --zero and --mini
A "Read xx lines (converted from...)" message should be suppressed when
--zero or --minibar are active (just like the normal "Read xx lines"),
as otherwise it gets shown at a confusing moment when multiple files
are opened at the same time.  The message should get shown, however,
when inserting a file into the current buffer.

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

Bug existed since version 6.0, commit f147131e.
2024-04-06 17:55:29 +02:00
Benno Schulenberg
c3fc3ec73d tweaks: slightly reword the help text for the Replace-With prompt
To avoid the vague impression that the characters typed at the two
prompts should correspond one to one.
2024-03-31 14:02:29 +02:00
Benno Schulenberg
be14fc593f tweaks: rename two variables, to be clearer and to match others
Also trim a verbose comment.
2024-03-30 12:39:15 +01:00
Benno Schulenberg
f2bfa53b61 tweaks: elide a redundant variable 2024-03-30 12:39:04 +01:00
Benno Schulenberg
25d07b422d tweaks: rename a variable, to better indicate what it represents
And also to get away from the abundance of the word "current".
2024-03-30 11:35:41 +01:00
Benno Schulenberg
8610857015 feedback: drop an unnecessary warning, to not bother the user
The idea of the warning was that `row < 0 || row >= editwinrows` would
never be true: that the check was redundant and could be removed.

As it appears to be too hard to make sure in advance that a chunk will
not fall outside the viewport, just drop the warning and leave the check
in place.

This also addresses https://savannah.gnu.org/bugs/?64168.
Reported-by: Matteo Raso <matteo_luigi_raso@protonmail.com>
2024-03-30 11:15:32 +01:00
Benno Schulenberg
17abce073f display: do not attempt to draw a line that is outside the viewport
When we're on the last row in the viewport, it is unwise to try and draw
the next line.

This fixes https://savannah.gnu.org/bugs/?65539.
The issue was reported by `correctmost`.

Bug existed since commit c2322f85 from three days ago.
2024-03-30 10:49:29 +01:00
Benno Schulenberg
02d50bd4aa help: mention M-Home and M-End in the help text and help lines
Make these new keystrokes discoverable for people who read help texts.
2024-03-29 12:56:15 +01:00
Benno Schulenberg
67d459b262 bindings: let <Alt+Home/End> move the cursor to top/bottom of viewport
For now these are hidden keystrokes -- they are not listed anywhere,
and the functions are not bindable by the user.
2024-03-28 16:04:34 +01:00
Benno Schulenberg
5ecefb8766 moving: preserve horizontal position when jumping to top or bottom row 2024-03-28 16:04:34 +01:00
Benno Schulenberg
52eb0e992d new feature: functions that jump to the top or bottom of the viewport
(The next commit will preserve the horizontal cursor position.)
2024-03-28 16:04:34 +01:00
Benno Schulenberg
19ddc081c1 tweaks: rename a variable, to be more readable 2024-03-28 16:01:48 +01:00
Benno Schulenberg
8e91e26cc5 tweaks: reshuffle three fragments of code, moving related things together
And avoid calling xplustabs() twice in a row.
2024-03-28 15:58:28 +01:00
Benno Schulenberg
c2322f8563 display: draw a new magic line rightaway when there are multiline regexes
Drawing a line will allocate multidata for it (even when the line is
actually empty), so that this multidata will not be missing later on
when the next line gets drawn in the same burst of keystrokes.

(This also removes the triggering of a full refresh when line numbers
are active: only the new magic line needs to be additionally drawn, in
order to get the line number printed.)

This fixes https://savannah.gnu.org/bugs/?65516.
The issue was reported by `correctmost`.

Problem existed since version 6.3, commit 80c2000f.
2024-03-27 11:12:47 +01:00
Benno Schulenberg
4f0683a481 docs: add an example binding for normalizing Unicode to the sample nanorc
This requires `uconv` from the 'icu-devtools' package (on Debian).
2024-03-26 11:37:29 +01:00
Benno Schulenberg
b9449de5cf docs: improve the description of the 'flipexecute' bindable function
It is bindable only in the Insert menu -- in the Execute menu it has
a "blind", unadvertised binding (because I consider toggling between
menus somewhat of a misfeature).
2024-03-26 11:29:56 +01:00
Benno Schulenberg
c3a9578b82 feedback: raise the level of "Macro is empty", to match similar messages
The other three "... is empty" messages use the AHEM error level too.
2024-03-26 11:27:38 +01:00
Benno Schulenberg
6351dab3e6 bindings: let M-" place/remove an anchor, and let M-' jump to one
On my current laptop, typing <Alt+Insert> is awkward because it requires
holding down <Fn> too.  Also, M-" and M-' are in the normal symbols area
of the keyboard, which makes them easier to type and more discoverable.
Furthermore, being next to M-: and M-; (on a US keyboard) reinforces the
meanings: start/place, stop/remove, run/goto.
2024-03-25 11:01:14 +01:00
Benno Schulenberg
3ef6399d56 tweaks: rename a variable, away from an abbreviation
And rename its sister too.
2024-03-24 10:46:46 +01:00
Benno Schulenberg
f4754bfb5a memory: prevent a leak by freeing a possibly already existing color combo
This fixes https://savannah.gnu.org/bugs/?65505.

Buglet existed in this form since version 2.9.3, commit 4b24ce1c.
2024-03-23 11:04:23 +01:00
Benno Schulenberg
3fb8efc8f2 input: prevent 'macro_length' from underflowing when hammering M-:
Normally, when recording a macro, users will make their keystrokes
slowly and carefully, and will most likely wait to see the effect
of the previous keystroke before making the next.  So, the chances
of two `recordmacro` keystrokes coming in in quick succession is
normally nil.  The 'macro_length' variable just needs a guard to
prevent it from underflowing when someone is hammering the keys.

This fixes https://savannah.gnu.org/bugs/?65394 in a better way.
2024-03-22 16:27:34 +01:00
Benno Schulenberg
9ae84071eb input: store key codes in the macro buffer as they come in from ncurses
Otherwise the leading ESC of keystrokes like M-A does not get recorded.

This reverts commit 191cf671 from three weeks ago.

This fixes https://savannah.gnu.org/bugs/?65507.
2024-03-22 16:27:11 +01:00
Benno Schulenberg
c2b4c2ae0e docs: mention that 'light' background colors do not work on Linux console
This addresses https://savannah.gnu.org/bugs/?65501.
Reported-by: Alan Cristhian Ruiz <alancristhian@protonmail.com>
2024-03-22 11:23:05 +01:00
Benno Schulenberg
9f1431be17 justify: keep as much of the marked region onscreen as possible
When the justified region fits in its entirety onscreen, then it should
be shown in its entirety, because the user is probably curious what the
region looks like after justification.  This behavior will mean that
the line above the topline of the screen will still have multidata
(when the syntax has multiline regexes).  When the justified region
does not fit onscreen, then as much as possible should be shown --
meaning that the cursor should be either at the top or the bottom
of the viewport, meaning that it should not be centered.

This fixes https://savannah.gnu.org/bugs/?65482.
The issue was reported by `correctmost`.

Bug existed since version 4.0, since justifying a region was introduced.
2024-03-19 17:18:18 +01:00
Benno Schulenberg
e1c6ae7cf3 justify: keep the cursor at the original end of a marked region
When justifying a region that was marked backwards, the cursor
should stay at the beginning of this region.  The old logic was
faulty because mark_is_before_cursor() does not give the correct
result *after* the justification has been done: for some reason
the mark ends up always before the cursor.

Bug existed since version 5.2, commit 0f8423eb,
which mistakenly removed the auxiliary variable.  :/
2024-03-19 16:45:02 +01:00
Benno Schulenberg
bb7a9fe7d2 tweaks: ungettextize three strings, to make a translator hint right again
The strings are gettextized further down, for the non-tiny version,
so they will get translated anyhow.  The relevant translator hint
is the earlier one about "the next thirteen strings".

Also adjust an indentation, and ungettextize another string for
consistency.
2024-03-19 11:56:33 +01:00
Benno Schulenberg
d77263d8ed bindings: let M-& show the ncurses version+patch, as a small Easter egg 2024-03-18 10:33:40 +01:00
Benno Schulenberg
fdd92af3ac display: add a wnoutrefresh() call for NetBSD, to force a cursor update
With NetBSD curses, when only the cursor is moved (without writing any
text), then a call of wnoutrefresh() is needed to make doupdate() move
the cursor.  Ncurses does not need this.

This addresses https://savannah.gnu.org/patch/?10438.
2024-03-18 10:02:11 +01:00
Benno Schulenberg
dd009e0bc7 tweaks: rename a function and variable, to describe better what they do 2024-03-17 17:18:48 +01:00
Benno Schulenberg
170e7d79e7 tweaks: express an 'if' more concisely, and add two blank lines
The calls of wnoutrefresh() after those new blank lines are not needed
for ncurses to show the cursor in the right place, but are logically
needed because things have been written to the screen in the preceding
code -- although nano seems to work correctly also without those calls.
2024-03-17 16:57:19 +01:00
Benno Schulenberg
a7635ceb5d tweaks: rename a variable, to be a bit more indicative 2024-03-17 16:40:04 +01:00
Benno Schulenberg
64fb0be8b2 tweaks: add another translator hint, to help avoid overlong key tags 2024-03-16 16:28:16 +01:00
Benno Schulenberg
a5a8487132 tweaks: improve three translator hints
The browser listing has a rigid format: longer translations
for "(dir)", "(parent dir)", and "(huge)" will be clipped.
2024-03-15 14:06:14 +01:00
Benno Schulenberg
8cf61af551 indicator: do not oversize the scroller when softwrapping
This fixes https://savannah.gnu.org/bugs/?65445.

Bug existed since version 5.7, commit 49d8b99e.
2024-03-11 11:18:28 +01:00
Benno Schulenberg
778f000a3b docs: use a space after #, like everywhere else in the sample nanorc
Also, use a more mnemonic example shortcut for copy-to-clipboard.
2024-03-10 17:32:09 +01:00
Benno Schulenberg
623ff4e1ed docs: trim stuff that is more than five years old from the changelog
A detailed list of changes is useful for a small number of users only,
and only when the changes are fairly recent.

The NEWS file, that contains a summary of user-visible changes and
will be useful for a larger number of users, is distributed in full.
2024-03-09 17:18:04 +01:00
Benno Schulenberg
260f00c76d screen: recalculate the multidata when detecting the need for it
This fixes https://savannah.gnu.org/bugs/?65435.
The issue was reported by `correctmost`.

Problem existed since version 6.3, commit 80c2000f.
2024-03-09 09:01:31 +01:00
Benno Schulenberg
0c8a3b5c3e tweaks: pull a fragment of code a bit forward, to enable the next commit 2024-03-09 08:32:47 +01:00
Benno Schulenberg
e76068a2de docs: adjust an example help line in the README to the current state 2024-03-08 17:12:28 +01:00
Benno Schulenberg
a12e45c355 help: show ^F/^B as primary shortcuts for search, not as secondary
This looks better in the help viewer (^F/^B matching the pair M-B/M-F),
and showing ^F instead of ^W for search in the main edit window will
prevent novice users from using ^W in situations where they shouldn't.
2024-03-08 11:50:20 +01:00
Benno Schulenberg
74b9dd6881 help: rebalance the help items when --preserve is used
As a backward search is now normally always bound (to ^B, instead of
conditionally to ^Q), ^L should always be shown in the help viewer.

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

Problem existed since commit 8a304bdf, since ^F/^B do a search.
2024-03-08 11:31:02 +01:00
Benno Schulenberg
edd0823d96 docs: mention that --modernbindings overrides --preserve 2024-03-08 11:25:14 +01:00
Benno Schulenberg
4ef4eb4f12 options: make --modernbindings actually override --preserve
When modern bindings are requested, ^S should save and ^Q must exit,
so --preserve and 'set preserve' need to be cancelled.

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

Bug existed since commit 18b37c98, which introduced --modernbindings.
2024-03-08 11:04:48 +01:00
Benno Schulenberg
862574f381 undo: force a screen refresh also for the special case Bsp-at-EOF
Because meanwhile the cursor might be someplace where EOF is offscreen.

This effectively reverts commit 9ccf85ea from two years ago, but also
sets 'focusing' to false so that the last line of the buffer will be at
the bottom of the edit window, where it probably was when Bsp was typed.

This fixes https://savannah.gnu.org/bugs/?65428.
The issue was reported by `correctmost`.

Bug existed since version 6.3, commit 9ccf85ea.
2024-03-07 17:14:18 +01:00
Benno Schulenberg
c67ea1ffc1 undo: recompute the multidata when a piece of text is replaced
When a justification (or even a spell check) is undone or redone,
this might affect the matching of multiline regexes, so... schedule
a recalculation of the multidata in those cases.

This fixes https://savannah.gnu.org/bugs/?65426.
The issue was reported by `correctmost`.

Problem existed since version 6.3, commit 80c2000f.
2024-03-07 16:51:08 +01:00
Benno Schulenberg
5bd5bcd06a docs: mention backreferences (for replacements with regular expressions)
Also mention that nano prompts for each occurrence, and that, when
a region is marked, replacements are made only within that region.
2024-03-05 15:50:15 +01:00
Benno Schulenberg
a13cd6a177 execute: show "Older" and "Newer" in the help lines, to allow rebinding
Since commits c8363a0d and a75bf0a1 from seven years ago, the Execute
menu permits retrieving previously executed commands, but the help text
and help lines never showed the corresponding keystrokes.

Four years ago commit d3954901 made the Execute menu directly accessible,
but I preferred to not mention the ^P/^N keystrokes in the help lines,
to leave as much space as possible for the executable functions (added
in subsequent commits), thinking that no one would want to rebind those
keystrokes anyway, as the Up/Down arrows seem more logical and easier.

The issue was reported by Ivan Vorontsov:
  https://lists.gnu.org/archive/html/help-nano/2024-02/msg00003.html
2024-03-05 11:31:48 +01:00
Benno Schulenberg
f60c6b25ad docs: delete a remark about libvte that is no longer relevant
Libvte 0.55 is more than five years old -- almost all users will
have upgraded by now to 0.55 or newer.
2024-03-05 08:44:04 +01:00
Benno Schulenberg
c6a2664106 tweaks: delete a redundant fragment of code from do_replace_loop()
Since commit 50954a4b from a year and a half ago, a replacing session
will not ever change the final empty line, so a fresh magic line will
never be needed.
2024-03-04 16:30:09 +01:00
Benno Schulenberg
4ab80abb5e justify: recompute the multidata for paragraphs larger than the viewport
A freshly justified paragraph does not yet have any multidata,
and if this new paragraph has more lines than fit in the viewport
(minus one line for the cursor), then the line above the top of the
new viewport will be without multidata.  The coloring code cannot
handle this, so all the multidata then needs to be recalculated.

This fixes https://savannah.gnu.org/bugs/?65396.
The issue was reported by `correctmost`.

Problem existed since version 6.3, commit 80c2000f.
2024-03-04 12:52:18 +01:00
Benno Schulenberg
f37d097c1c rcfile: avoid crashing on an include path that is way too long
The `gnulib` globbing module apparently does not handle an overload
of slashes well, so avoid feeding it more than it can take.

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

Problem probably existed since version 2.3.3,
since globbing was introduced.
2024-03-04 11:44:22 +01:00
Benno Schulenberg
191cf671be input: store keystroke in macro buffer only when about to interpret it
When the keystroke after the keystroke bound to `recordmacro` arrived
so quickly that the two got stored together in nano's keystroke buffer,
the main loop had not yet interpreted the `recordmacro` command and had
thus not yet set 'recording' to true, meaning that that second keystroke
would not get recorded.

Nano should record keystrokes into the macro buffer when fetching them
from its own keystroke buffer, not when fetching them from ncurses.

This fixes https://savannah.gnu.org/bugs/?65394.
The issue was reported by `correctmost`.

Bug existed since version 2.9.0, since macros were introduced.
2024-03-02 17:45:11 +01:00
Benno Schulenberg
3098315e05 replacing: stash the string to be replaced while asking for replacement
During the Replace-With prompt the user could search in its help text,
which would overwite the 'last_search' string.  Make therefore sure that
the latter gets restored to what it was before the Replace-With prompt.

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

Bug existed since version 2.8.2,
since searching in a help text became possible.
2024-02-28 11:44:03 +01:00
Benno Schulenberg
39db2e9d66 tweaks: implement the fix of the previous commit somewhat differently 2024-02-27 17:24:32 +01:00
Benno Schulenberg
ee1a1306e2 search: avoid crashing after searching a help text during a regex replace
Searching in a help text does not support using regular expressions,
so when 'inhelp' is set, do not free a compiled regex -- because if
there is such a regex, it belongs to a replacement session that is
about to begin.

This fixes https://savannah.gnu.org/bugs/?65369.
The issue was reported by `correctmost`.

Bug existed since version 2.8.2,
since searching in a help text became possible.
2024-02-26 13:20:24 +01:00
Benno Schulenberg
db72774458 verbatim: avoid referencing an uninitialized value
Only check input bytes when their count is nonzero.

This fixes https://savannah.gnu.org/bugs/?65365.
The issue was reported by `correctmost`.

The problem existed since version 5.7, commit c75a3839,
but occurred more easily since version 7.0, commit 75e5f885.
2024-02-26 10:48:51 +01:00
Benno Schulenberg
3d727266c3 input: for one bump of the mousewheel scroll two lines, not three
Scrolling three lines at a time goes too fast: it feels erratic.
Whereas scrolling two lines at a time still feels like scrolling.
2024-02-25 16:14:44 +01:00
Andy Koppe
4673e709b2 input: scroll on mousewheel events instead of moving the cursor
Translate mousewheel events into Alt+Up/Down key presses instead of
into plain Up/Down key presses, as the latter only start scrolling
once the cursor reaches the top or bottom.

Scrolling rather than moving the cursor is the standard behavior for
mousewheel events in GUI editors such as Gedit and Kate, as well as
in the mouse mode of terminal editors such as vim, joe, and mcedit.

Signed-off-by: Andy Koppe <andy.koppe@gmail.com>
2024-02-23 16:06:33 +01:00
Benno Schulenberg
f1a04f780a syntax: javascript: recognize also the .mjs extension
The V8 JavaScript-engine developers recommend using this extension:
  https://v8.dev/features/modules#mjs

Also, add the fairly new "JavaScript source" as magic description.

This fulfills https://savannah.gnu.org/bugs/?65334.
Requested-by: Matt Whitlock <gnu@mattwhitlock.name>
2024-02-20 17:00:48 +01:00
Benno Schulenberg
eca5856d99 tweaks: remove two pairs of unneeded braces, and normalize a line 2024-02-18 15:02:51 +01:00
Benno Schulenberg
190221c91c justify: set x = 0 for the undo item, for when using --cutfromcursor
When --cutfromcursor is active, 'current_x' needs to be set to zero when
doing a justification, so that the correct starting position gets stored
in the undo item.  (Without --cutfromcursor, the value of 'current_x'
does not matter.)

This fixes https://savannah.gnu.org/bugs/?65317.
The issue was indirectly reported by `correctmost`.

Bug existed in this form since version 5.0, commit ae5a4ece.

Between versions 4.0 and 5.0, nano would not eat a line but would
instead crash when undoing a justification that was done with the
cursor away from the left edge.
2024-02-16 15:56:22 +01:00
Benno Schulenberg
77d74b5d81 input: flush the keystroke buffer upon any kind of error condition
This stops the execution of a macro or a string bind whenever something
unexpected happens, to prevent the waiting keystrokes from doing things
that were not intended.

Especially this prevents an infinite loop: when during the recording
of a macro the `runmacro` keystroke is typed in some menu (where the
keystroke is not bound), and the macro is later replayed in a way that
results in exiting from that menu before the `runmacro` keystroke gets
replayed...

This fixes https://savannah.gnu.org/bugs/?65301.
The issue was reported by `correctmost`.

Bug existed since version 2.9.0, since the macro feature was introduced.
2024-02-14 09:23:18 +01:00
Benno Schulenberg
0e44752ba1 justify: set the correct starting point also with --cutfromcursor
When --cutfromcursor is active, 'current_x' does need to be zero for
the segment extraction to do the right thing.

This fixes https://savannah.gnu.org/bugs/?65289.
The issue was indirectly reported by `correctmost`.

Bug existed since version 4.0, commit 2500debb.
2024-02-11 16:31:20 +01:00
Benno Schulenberg
20692e0c29 browser: restore typing position at prompt after "^R name ^T ^F ^V ^C"
When going back from the browser to a file prompt, restore the typing
position also after a 'to_first_file' (^Y) and 'to_last_file (^V).

The cursor misplacement existed since version 5.9, commit 508301a2.
2024-02-11 16:05:56 +01:00
Benno Schulenberg
206b4e2a7e search: avoid a crash after a nested search, reported by correctmost
When going back to a previous prompt, restore the typing position
also for 'to_first_line' (^Y) and 'to_last_line (^V).

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

Bug existed since version 5.9, commit 6d5b1656, which allowed exiting
from a Search-in-help prompt with ^Y or ^V.
2024-02-11 14:57:24 +01:00
Benno Schulenberg
8fefee2d41 undo: prevent a use-after-free, reported by correctmost
When the cursor is on the last line, and an undo removes this line,
do not let 'openfile->current' become invalid.

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

Bug existed since version 6.3, commit eea3e1f0.

(It should have been fixed in commit 9410a556, more than a year ago.)
2024-02-10 12:14:52 +01:00
Benno Schulenberg
cdaa43b396 syntax: makefile: ensure that the <Tab> key always produces a tab
Making it independent from the `tabstospaces` setting.

And remove the now-redundant suggestion from the sample nanorc.
2024-02-05 17:17:37 +01:00
Benno Schulenberg
a0eebf20db bindings: in the tiny version, bind M-6 only in main, not at the prompts
This prevents M-6 from unexpectedly exiting from the prompt
and then copying a line in the edit window.
2024-01-31 08:34:02 +01:00
Benno Schulenberg
b84f6fc15f general: include the Copy function (M-6 or ^C) into the tiny version
When using --modernbindings with the tiny version, it was strange that
^X cuts and ^V pastes but ^C complains about being unbound.  Fix that.
2024-01-31 08:21:28 +01:00
Benno Schulenberg
d0a1bc361a help: restore ^H and ^D as the primary shortcuts for Backspace and Delete
Commit 18b37c98 moved the bindings of ^H and ^D further down.  Now move
the bindings of <Bsp> and <Del> to after those, so that ^H and ^D will
be shown again first in the help text (when not using --modernbindings).
2024-01-30 08:13:23 +01:00
Benno Schulenberg
d35650b034 docs: document the new --modernbindings option 2024-01-29 10:40:48 +01:00
Benno Schulenberg
580eaf29d6 bindings: set up modern bindings also when binary's name starts with "e"
This allows activating the "modern" bindings without having to pass an
option, by simply invoking nano through a symlink -- for example: `en`
(short for "editor nano"), or `et` (short for "edit"), or just `e`.
2024-01-29 10:40:48 +01:00
Benno Schulenberg
a27da0d75b bindings: with --modern, do not let ^Q^Q quit nano without saving
With --modernbindings, instead accept ^Q^X for abandoning any changes
-- the inverse of the normal (but undocumented) ^X^Q.

This prevents the unintentional loss of work when the user hits ^Q twice
by accident.
2024-01-29 10:40:48 +01:00
Benno Schulenberg
26c75a6828 bindings: with --modern, use ^H for Help when the terminal allows it
Also, allow using ^H (or ^N) for exiting from Help too.
2024-01-29 10:40:48 +01:00
Benno Schulenberg
c32828bb13 tweaks: normalize the indentation after the previous change 2024-01-29 10:40:48 +01:00
Benno Schulenberg
18b37c980a new feature: option --modernbindings sets up more widespread key bindings
With --modernbindings, ^Q quits, ^F finds, ^B finds backwards, ^G finds
again, ^D finds again backwards, ^X cuts, ^C copies, ^V pastes, ^A sets
the mark, ^R replaces, ^O opens a file, ^W writes out a file, ^S saves,
^Z undoes, ^Y redoes, ^P shows the position, ^T goes to a given line,
and ^E executes.

Note that with --modernbindings ^Q and ^S are always bound, meaning that
--preserve / 'set preserve' is ignored.  This is necessary because ^Q is
an essential keystroke in the modern bindings.

Also note that these "modern bindings" are effective only in the main
edit window, not in the various menus.  In all menus ^C means Cancel,
and I can't think of a good alternative default keystroke for that
(in order for ^C to mean Copy).  And in a few menus ^V has a meaning,
and there is no good alternative for that either.  So... in the menus
the user has to use M-6 for Copy and ^U for Paste (and ^K for Erase --
Cut does not exist in the menus), like with the default bindings.
2024-01-29 10:40:48 +01:00
Benno Schulenberg
64ac4610de tweaks: rewrap a comment, and reshuffle seven declarations
Also, drop three unneeded initializations.
2024-01-28 09:35:40 +01:00
Benno Schulenberg
dea34733a4 tweaks: move two static declarations to the only function that uses them 2024-01-27 11:41:57 +01:00
Benno Schulenberg
0e72c0d372 chars: add a helper function for stripping leading blanks from a string
And apply this function to the formatter and linter command strings,
to complement the bug fixes in the previous two commits.
2024-01-25 16:50:09 +01:00
Benno Schulenberg
88c8da143f linter: do not mess up the input stream when the linter command is empty
Instead simply say that no linter is defined.

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

Bug existed since version 5.5, commit bc368133, but before
that commit nano would crash on an empty linter command.
2024-01-24 16:23:09 +01:00
Benno Schulenberg
367f84b0ec formatter: do not crash when the formatter command is empty
Instead simply say that no formatter is defined.

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

Bug existed since version 4.6, since the formatter was reintroduced.
2024-01-24 16:22:04 +01:00
Benno Schulenberg
1a3ef7e497 docs: fix a ten-year-old typo, reported by correctmost
This fixes https://savannah.gnu.org/bugs/?65193.
2024-01-23 13:18:09 +01:00
Benno Schulenberg
c19012d4cd docs: say "mini bar", not "minibar", when referring to the actual bar
Like is done for the other bars: title bar, status bar, prompt bar.
2024-01-20 11:02:54 +01:00
Benno Schulenberg
b502631d10 docs: mention the changed meanings of ^F/^B and also in the texi manual
Also somewhat reword the note for version 4.0.
2024-01-18 11:06:01 +01:00
Benno Schulenberg
6728e5d791 docs: mention the missing two options that override --bold
And improve one word.
2024-01-16 16:15:22 +01:00
Benno Schulenberg
101b53b541 docs: add ^T^S (spell check) and M-S (softwrap) to the cheatsheet
Also, adjust the alignment of the two header lines,
and slightly reword one of the descriptions.
2024-01-16 10:56:41 +01:00
Benno Schulenberg
11c492fdd0 docs: add M-C and M-Z to the cheatsheet, and reshuffle for balance 2024-01-13 11:27:28 +01:00
Benno Schulenberg
792d4e9a23 docs: adjust the cheatsheet for the changed meanings of ^F, ^B, M-F, M-B 2024-01-13 11:22:14 +01:00
Mike Frysinger
c59e9d228e build: link in $(GETRANDOM_LIB) from gnulib
On Windows builds, gnulib might set GETRANDOM_LIB to -lbcrypt and then
use that API.  But since we don't include $(GETRANDOM_LIB) when linking,
we fail.  On Linux systems, this is empty as getrandom APIs are part of
the main C library already.  This is also what the link requirements say
in gnulib's modules/getrandom spec.
2024-01-12 17:00:34 +01:00
Mike Frysinger
d8848df14f gnulib: import canonicalize-lgpl for realpath
Building for mingw fails due to missing realpath.  Pull in the gnulib
module to get it working again.
2024-01-12 16:59:40 +01:00
Benno Schulenberg
4a2729b780 copyright: update the years for the FSF 2024-01-10 11:24:28 +01:00
Benno Schulenberg
7c174a1a25 syntax: c: require a preceding blank when a line comment contains a quote
This avoids miscolorizing part of a string when it contains a URL.

This fixes https://savannah.gnu.org/bugs/?64340.
Reported-by: Yonut Smith <deanlast3@gmail.com>

Problem has existed for more than twenty years, at least since support
for multine-line regexes was added in commit 6c1e6612 in 2002.
2024-01-09 10:20:50 +01:00
Benno Schulenberg
f0e69b4a51 tweaks: use a pair of parentheses to clarify the order of operations
(Parentheses are used everywhere else with a bitwise &.)
2024-01-08 17:25:03 +01:00
Benno Schulenberg
4a915b1ed5 input: avoid hanging after a 39-character paste on a VSCode terminal
The terminal in VSCode splits pastes into 50-byte chunks and can
thus split an escape sequence somewhere in the middle, resulting
in nano failing to recognize the end-of-bracketed-paste sequence
and thus hanging -- until another, different-sized paste is made.

Avoid this hang by interpreting any invalid escape sequence that
starts with "\e [ 2" as a truncated end-of-bracketed-paste.

(This will leave a spurious tilde after the 39-character paste,
which is not nice but... better than hanging.)

This works around https://savannah.gnu.org/bugs/?64996.
Reported-by: Jacob Lifshay <programmerjake@gmail.com>
2023-12-21 15:40:21 +01:00
Benno Schulenberg
cbf5a5b5d3 docs: in the sample nanorc, set the guidestripe to a soft grey
This gives both an example of the #rgb format and shows that the
guidestripe can be set to an unobtrusive color.
2023-12-18 16:14:10 +01:00
Benno Schulenberg
41b52d70be input: recognize certain escape sequences for F13 to F16 again
Even though in nano the names F13 to F24 exist, these names actually
refer to Shift+F1...Shift+F12.  One cannot blame people for thinking
that F13 in nano is the same as F13 in Xorg, so... recognize the escape
sequence for the latter and map it to what nano calls F13.

This accommodates users that put F13...F16 in a custom keymap for Xorg.

This fixes https://savannah.gnu.org/bugs/?64632.
Reported-by: Danny Milosavljevic <dannym@scratchpost.org>

Problem existed since version 5.0, commit 9a6158cd.
2023-12-17 17:48:04 +01:00
Benno Schulenberg
129696cdbe gnulib: update to current upstream state, to make a fresh checkout work
Also, increase the checkout depth, so that it will work for longer.

Indirectly-reported-by: Jacob Lifshay <programmerjake@gmail.com>
2023-12-10 10:58:01 +01:00
Benno Schulenberg
8cc3ab213d tweaks: rename a variable, to be clearer when seen in context 2023-12-09 16:25:02 +01:00
Benno Schulenberg
9bf966af37 tweaks: add an extra variable, to avoid reusing one for another purpose 2023-12-08 16:12:17 +01:00
Benno Schulenberg
a76a6bf692 softwrap: remember the actual breaking point when wrapping at blanks
When softwrapping at blanks, the wrapping routine should, when called
again, continue searching from where the previous chunk ended, not from
the point it reached during that previous search, because this could be
*just* beyond the space that could be the next breaking point.

This fixes https://savannah.gnu.org/bugs/?64945.
Reported-by: Andreas Schamanek <schamane@fam.tuwien.ac.at>

Bug existed since version 6.4, commit 0e9bef34.
2023-12-06 17:18:41 +01:00
Benno Schulenberg
6a7a0c8f50 display: show the help lines down to the tiniest possible terminal size
That is: compute the minimum needed terminal height more accurately.
2023-11-25 17:07:05 +01:00
Benno Schulenberg
f5bc261944 general: let the constant-show toggle override the zero-interface mode
When the user hits the M-C toggle while option --zero is in effect,
instead of complaining "Not possible", do what the user probably
tries to achieve: cancel `zero` mode and switch on `constantshow`.
2023-11-25 17:07:05 +01:00
Benno Schulenberg
8a304bdf7c bindings: make ^F start a forward search by default
This makes nano more usable for users that are accustomed to the
near universal use of ^F for Find/Search in other programs, and
especially for users that somehow access a terminal through their
browser (where ^W will, destructively, close the terminal tab).

(To keep the bindings consistent, make ^B start a backward search,
and let M-F and M-B search for the next occurrence in the matching
direction.)

Suggested-by: Chris Allegretta <chrisa@asty.org>
Suggested-by: Donnie Ferris <DonnyBahama@gmx.com>
  https://lists.gnu.org/archive/html/nano-devel/2023-01/msg00001.html
2023-11-24 16:24:08 +01:00
Benno Schulenberg
124e86a6d2 undo the prelast commit in order to redo it with a fuller commit message 2023-11-24 14:42:08 +01:00
Benno Schulenberg
96df9e0a20 docs: mention how to get the old behavior of ^F, ^B, M-F, and M-B back 2023-11-22 10:52:34 +01:00
9228180b1e Merge branch 'master' into line-folding 2023-11-01 12:47:08 -07:00
Benno Schulenberg
a04d2a433c bindings: make ^F start a forward search by default
This makes nano more usable for users that are accustomed to the
near universal use of ^F for Find/Search in other programs.

To keep the bindings consistent, make ^B start a backward search,
and let M-F and M-B search for the next occurrence in the matching
direction.
2023-10-30 15:01:53 +01:00
b2f79e3a6e Merge branch 'master' into line-folding 2023-08-25 12:48:22 -07:00
4622210cfb Fix some sh*t 2023-06-03 19:49:44 -07:00
9317206586 Add colorization to folding segments.
I already added this for myself since I've been using this patch for a while
so I figured I'd include it. This simply makes it possible to colorize the
folded segments as the user desires. An option 'foldedcolor' is enabled for
the rcfile.

Signed-off-by: rexy712 <rexy712@protonmail.com>
2023-04-06 11:52:59 -07:00
7027b9b601 Add option '--enable-folding' and add shortcut for folding.
In order to test the functionality, one actually has to be able to build it!
This patch adds an option to the configure script, builds 'folding.c', and
adds a shortcut to make folding possible. The shortcut here is set to 'M-['.

Signed-off-by: rexy712 <rexy712@protonmail.com>
2023-04-06 11:52:38 -07:00
fc3598f116 Handle all the more complicated modifications to existing functionality.
Not everything is as simple as just UNFOLD_SEGMENT. These are the cases where
specific modifications were needed. Most of the actual heavy lifting was done
when modifying the functions 'update_line' and 'do_prev_word'.

Most of the changes here actually came down to 'get_row_from_edittop' or
changing from 'update_line' to 'update_line_at'.

Signed-off-by: rexy712 <rexy712@protonmail.com>
2023-04-06 11:52:13 -07:00
90dac326c1 Modify line number arithmetic to no longer assume linear increments.
When adding folding lines, the lines drawn on screen are no longer
guaranteed to increment one by one. There could be a large skip when
handling folded segments. So instances where the codebase assumed
'openfile->current->lineno - edittop->lineno' would yield the position
on screen of the current line needed to be modified. Similar problems
existed in many places so a function 'get_row_from_edittop' handles
finding the current position of a line in relation to 'edittop'.

Signed-off-by: rexy712 <rexy712@protonmail.com>
2023-04-06 11:51:53 -07:00
a299827554 Modify signatures of functions to be modular for further folding patches.
The bracket search functions 'find_a_bracket' is very useful for searching for
region to fold when no selection is made. To make this possible, the function
needed to be modularized so it could be reused in a way not originally
intended.
The functions 'do_prev_word' and 'do_next_word' were interesting in that
sometimes it is desirable to get the corresponding word within a folded
segment and sometimes it was better to skip folded segments. So a boolean
parameter seemed like a good way to not duplicate functionality while
making the function work for both cases.
The 'update_line' function only worked in relation to edittop from the
given line's lineno. This obviously won't get the correct position if
there are folded lines. So I added a new function 'update_line_at' to
allow specifying where in the window to update when calling the function.
The original 'update_line' still exists to not modify existing code
utilizing it.

Signed-off-by: rexy712 <rexy712@protonmail.com>
2023-04-06 11:50:46 -07:00
a39e61a3e0 Add calls to UNFOLD_SEGMENT in existing functions.
Nano's existing functionality needs to mesh with the ability to
fold lines. The most common of these issues is needing to unfold
when a line is updated or the user accesses a line inside of a folded
segment. This patch handles all the places this can be done simply
with a 1 or 2 line modification.

Signed-off-by: rexy712 <rexy712@protonmail.com>
2023-04-06 11:50:22 -07:00
584571248f Add the basic support structure for the folding.
Adds in some preprocessor directives for easily adding in unfolding
support to existing functions that require it. Also adds in some
helper functions in 'folding.c' for common tasks which will need
performed. And of course add the 'folded' boolean to the linestruct
type so we know which lines are currently folded.

Signed-off-by: rexy712 <rexy712@protonmail.com>
2023-04-06 11:49:38 -07:00
103 changed files with 34744 additions and 34060 deletions

31
AUTHORS
View File

@ -13,16 +13,15 @@ Benno Schulenberg <bensberg@telfort.nl>
Current maintainer.
David Lawrence Ramsey <pooka109@gmail.com>
* Former stable series maintainer. Multiple buffer support,
operating dir (-o) option, bug fixes for display routines,
wrapping code, spelling fixes, constantshow mode, parts of
UTF-8 support, softwrap overhaul, undoable (un)indentations,
undoable justifications, justifiable regions, and numerous
other fixes.
* Multiple-buffer support, operating-dir option (-o), bug fixes
for display routines, wrapping code, spelling fixes, parts of
UTF-8 support, softwrap overhaul, constantshow mode, undoable
indentations, undoable justifications, justifiable regions,
and numerous other fixes. Former stable-series maintainer.
Jordi Mallach <jordi@gnu.org>
* Debian package maintainer, fellow bug squasher.
* Internationalization support head, ca.po maintainer.
* Debian package maintainer, fellow bug squasher, translator
for Catalan. Former head of internationalization support.
Adam Rogoyski <rogoyski@cs.utexas.edu>
* New write_file() function, read_file() optimization, mouse
@ -35,9 +34,9 @@ Robert Siemborski <rjs3@andrew.cmu.edu>
new edit display routines.
Rocco Corsi <rocco.corsi@sympatico.ca>
* Internal spelling code, many optimizations and bug fixes for
findnextstr() and search-related functions, various display
and file handling fixes.
* Internal spelling code, many optimizations and bug fixes
for findnextstr() and search-related functions, various
display and file-handling fixes.
David Benbennick <dbenbenn@math.cornell.edu>
* Wrap and justify bugfixes/enhancements, new color syntax
@ -45,11 +44,11 @@ David Benbennick <dbenbenn@math.cornell.edu>
miscellaneous fixes.
Mike Frysinger <vapier@gentoo.org>
* Gentoo package maintainer. Whitespace display mode,
--enable-utf8/--disable-utf8 configure options for ncurses,
many new color regexes and improvements to existing color
regexes in syntax/*.nanorc, the move from svn to git, the
conversion to gnulib, and miscellaneous bug fixes.
* Whitespace display mode, --enable-utf8/--disable-utf8 configure
options for ncurses, many new color regexes and improvements to
existing ones in syntax/*.nanorc, the move from svn to git, the
conversion to gnulib, and miscellaneous bug fixes. Former
Gentoo package maintainer.
Mark Majeres <mark@engine12.com>
* A functional undo/redo system, and coloring nano's interface.

4447
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,15 @@
Improvements in GNU nano
========================
Since 8.0:
- To accommodate newcomers, ^F now starts a forward search.
- Option --modernbindings makes ^Q quit, ^X cut, ^C copy, ^V paste,
^Z undo, ^Y redo, ^O open a file, and ^G find again, among others.
- M-Home/M-End put the cursor on the first/last row in the viewport.
- With `nano filename:number` the given file will be opened with the
cursor on the given line number (when 'set colonparsing' is used).
- Option --listsyntaxes lists the names of available syntaxes.
Since 7.0:
- String binds may contain bindable function names between braces.
- Word completion looks for candidates in all open buffers.

83
NEWS
View File

@ -1,3 +1,53 @@
2025.04.02 - GNU nano 8.4 "Five Miles Out"
• Bracketed pastes over a slow connection are more reliable.
• Tabs in an external paste at a prompt are not dropped.
• Feedback occurs when the cursor sits on a Byte Order Mark.
• The Execute prompt is more forgiving of a typo.
2024.12.21 - GNU nano 8.3 "like mice in the dream of a tabby cat"
• A build failure with gcc-15 is fixed.
• Several translations were updated.
2024.09.05 - GNU nano 8.2 "Charlotte will climb walls!"
• At a Yes-No prompt, beside Y and the localized initial for "Yes",
also ^Y is accepted. Similarly, ^N for "No", and ^A for "All".
• A text-highlighting bug with Alt+Home/Alt+End is fixed.
2024.07.12 - GNU nano 8.1 "de dag van de bitterkoekjespudding"
• The idiom `nano filename:linenumber` is understood only when the
option --colonparsing (or 'set colonparsing') is used.
• Modern bindings are *not* activated when nano's invocation name
starts with "e", as it jars with Debian's alternatives system.
• New bindable function 'cycle' first centers the current row,
then moves it to the top of the viewport, then to the bottom.
It is bound by default to ^L.
• Option --listsyntaxes/-z lists the names of available syntaxes.
2024.05.01 - GNU nano 8.0 "Grus grus"
• By default ^F is bound to starting a forward search, and ^B to
starting a backward search, while M-F and M-B repeat the search
in the corresponding direction. (See the documentation if you
want the old bindings back.)
• Command-line option --modernbindings (-/) makes ^Q quit, ^X cut,
^C copy, ^V paste, ^Z undo, ^Y redo, ^O open a file, ^W write a
file, ^R replace, ^G find again, ^D find again backwards, ^A set
the mark, ^T jump to a line, ^P show the position, and ^E execute.
• Above modern bindings are activated also when the name of nano's
executable (or a symlink to it) starts with the letter "e".
• To open a file at a certain line number, one can now use also
`nano filename:number`, besides `nano +number filename`.
• <Alt+Home> and <Alt+End> put the cursor on the first and last
row in the viewport, while retaining the horizontal position.
• When the three digits in an #RGB color code are all the same,
the code is mapped to the xterm grey scale, giving access to
fourteen levels of grey instead of just four.
• For easier access, M-" is bound to placing/removing an anchor,
and M-' to jumping to the next anchor.
• Whenever an error occurs, the keystroke buffer is cleared, thus
stopping the execution of a macro or a string bind.
• The mousewheel scrolls the viewport instead of moving the cursor.
2023.01.18 - GNU nano 7.2 "Boer doe mij 't hekke lös!"
• <Shift+Insert> is prevented from pasting in view mode.
@ -887,26 +937,23 @@
fixes for that version are still forthcoming.
2010.02.11 - GNU nano 2.2.3 "fumbling toward stability" is released.
This release contains a fix for only one bug, but a
rather irritating one: when paging up/down with smooth
scrolling, the cursor position was not being preserved
due to a bug in 2.2.2. With such a targeted fix
like this what could POSSIBLY go WRONG? Hahaha.
Enjoy and if you find new bugs, as always please
use Savannah's bug tracker.
This release contains a fix for only one bug, but a rather
irritating one: when paging up/down with smooth scrolling,
the cursor position was not being preserved due to a bug
in 2.2.2. With such a targeted fix like this what could
POSSIBLY go WRONG? Hahaha. Enjoy, and if you find new
bugs, as always please use Savannah's bug tracker:
https://savannah.gnu.org/bugs/?func=additem&group=nano
2010.01.17 - GNU nano 2.2.2 is released for you, you, you. This
release includes fixes for: crashes when writing
backup files in certain conditions, improper
screen centering when moving up/down in various
combination of smooth scrolling and soft wrapping modes,
a search crash on the armel arch, and issues with
lots of keybinding customizations causing crashing
particularly on FreeBSD. Also included are better
help menu entries for forward/back in the file browser,
some man page tweaks and one assert fix. As always,
share and enjoy!
2010.01.17 - GNU nano 2.2.2 is released for you, you, you. This release
includes fixes for: crashes when writing backup files in
certain conditions, improper screen centering when moving
up/down in various combinations of smooth scrolling and soft
wrapping modes, a search crash on the armel arch, and issues
with lots of keybinding customizations causing crashing
particularly on FreeBSD. Also included are better help menu
entries for forward/back in the file browser, some man page
tweaks and one assert fix. As always, share and enjoy!
2009.12.12 - GNU nano 2.2.1 "DLR strikes back" is open for business.
This release fixes many bugs, including: missing

4
README
View File

@ -15,7 +15,7 @@ Appearance
In rough ASCII graphics, this is what nano's screen looks like:
____________________________________________________________________
| GNU nano 7.2 filename Modified |
| GNU nano 8.4 filename Modified |
--------------------------------------------------------------------
| This is the text window, displaying the contents of a 'buffer', |
| the contents of the file you are editing. |
@ -29,7 +29,7 @@ Appearance
| |
--------------------------------------------------------------------
| [ Some status message ] |
|^G Help ^O Write Out ^W Where Is ^K Cut ^T Execute |
|^G Help ^O Write Out ^F Where Is ^K Cut ^T Execute |
|^X Exit ^R Read File ^\ Replace ^U Paste ^J Justify |
--------------------------------------------------------------------

View File

@ -12,9 +12,9 @@ To successfully compile GNU nano from git, you'll need the following:
autoconf (version >= 2.69)
automake (version >= 1.14)
autopoint (version >= 0.18.3)
autopoint (version >= 0.20)
gcc (version >= 5.0)
gettext (version >= 0.18.3)
gettext (version >= 0.20)
git (version >= 2.7.4)
groff (version >= 1.12)
make (any version)

View File

@ -2,9 +2,10 @@
# Generate configure & friends for GIT users.
gnulib_url="git://git.sv.gnu.org/gnulib.git"
gnulib_hash="2cf7f442f52f70b3df6eb396eb93ea08e54883c5"
gnulib_hash="f1daedcb4c6c653dfc2936847dfe55f5a076d94b"
modules="
canonicalize-lgpl
futimens
getdelim
getline
@ -31,7 +32,7 @@ modules="
# Make sure the local gnulib git repo is up-to-date.
if [ ! -d "gnulib" ]; then
git clone --depth=1111 ${gnulib_url}
git clone --depth=2222 ${gnulib_url}
fi
cd gnulib >/dev/null || exit 1
curr_hash=$(git log -1 --format=%H)
@ -42,20 +43,11 @@ if [ "${gnulib_hash}" != "${curr_hash}" ]; then
fi
cd .. >/dev/null || exit 1
echo "Autopoint..."
autopoint --force
rm -rf lib
echo "Gnulib-tool..."
./gnulib/gnulib-tool --import ${modules}
echo
echo "Aclocal..."
aclocal -I m4
echo "Autoconf..."
autoconf
echo "Autoheader..."
autoheader
echo "Automake..."
automake --add-missing
echo "Autoreconf..."
autoreconf --install --symlink --force
echo "Done."

View File

@ -1,6 +1,6 @@
# Configuration for GNU nano - a small and user-friendly text editor
#
# Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc.
# Copyright (C) 1999-2011, 2013-2025 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], [7.2], [nano-devel@gnu.org], [nano])
AC_INIT([GNU nano], [8.4], [nano-devel@gnu.org], [nano])
AC_CONFIG_SRCDIR([src/nano.c])
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([1.14])
@ -48,7 +48,7 @@ PKG_PROG_PKG_CONFIG
dnl Internationalization macros.
AM_GNU_GETTEXT_VERSION([0.18.3])
AM_GNU_GETTEXT_VERSION([0.20])
AM_GNU_GETTEXT([external], [need-ngettext])
AM_CONDITIONAL(USE_NLS, test x$USE_NLS = xyes)
@ -128,6 +128,20 @@ if test "x$enable_color" != xno; then
color_support=yes
fi
AC_ARG_ENABLE(folding,
AS_HELP_STRING([--disable-folding], [Disable line folding support]))
if test "x$enable_tiny" = xyes; then
if test "x$enable_folding" = xyes; then
AC_MSG_ERROR([
*** --enable-folding cannot work with --enable-tiny])
else
enable_folding=no
fi
fi
if test "x$enable_folding" != xno; then
AC_DEFINE(ENABLE_FOLDING, 1, [Define this to have line folding support.])
fi
AC_ARG_ENABLE(comment,
AS_HELP_STRING([--disable-comment], [Disable the comment/uncomment function]))
if test "x$enable_tiny" = xyes; then

View File

@ -12,8 +12,8 @@
<body>
<br>
<h1 align="center">Overview of nano's shortcuts &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</h1>
<h3 align="center">The editor's keystrokes and their functions &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</h3>
<h1 align="center">Overview of nano's shortcuts &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</h1>
<h3 align="center">The editor's keystrokes and their functions &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</h3>
<br>
<table align="center"><tbody>
@ -33,7 +33,6 @@
<tr><td>Ctrl+K &nbsp;&nbsp;</td><td>Cut current line into cutbuffer</td></tr>
<tr><td>Alt+6</td><td>Copy current line into cutbuffer</td></tr>
<tr><td>Ctrl+U</td><td>Paste contents of cutbuffer</td></tr>
<tr><td>Alt+T</td><td>Cut until end of buffer</td></tr>
<tr><td>Ctrl+]</td><td>Complete current word</td></tr>
<tr><td>Alt+3</td><td>Comment/uncomment line/region</td></tr>
<tr><td>Alt+U</td><td>Undo last action</td></tr>
@ -43,10 +42,10 @@
<b>Search and replace</b>
<table><tbody>
<tr><td>Ctrl+Q &nbsp;&nbsp;</td><td>Start backward search</td></tr>
<tr><td>Ctrl+W</td><td>Start forward search</td></tr>
<tr><td>Alt+Q</td><td>Find next occurrence backward</td></tr>
<tr><td>Alt+W</td><td>Find next occurrence forward</td></tr>
<tr><td>Ctrl+B &nbsp;&nbsp;&nbsp;</td><td>Start backward search</td></tr>
<tr><td>Ctrl+F</td><td>Start forward search</td></tr>
<tr><td>Alt+B</td><td>Find next occurrence backward</td></tr>
<tr><td>Alt+F</td><td>Find next occurrence forward</td></tr>
<tr><td>Alt+R</td><td>Start a replacing session</td></tr>
</tbody></table>
<br>
@ -64,11 +63,15 @@
<b>Operations</b>
<table><tbody>
<tr><td>Ctrl+T &nbsp;&nbsp;</td><td>Execute some command</td></tr>
<tr><td>Ctrl+T Ctrl+S</td><td>Run a spell check</td></tr>
<tr><td>Ctrl+T Ctrl+Y</td><td>Run a syntax check</td></tr>
<tr><td>Ctrl+T Ctrl+O &nbsp;</td><td>Run a formatter</td></tr>
<tr><td>Tab</td><td>Indent marked region</td></tr>
<tr><td>Shift+Tab &nbsp;&nbsp;</td><td>Unindent marked region</td></tr>
<tr><td>Ctrl+J</td><td>Justify paragraph or region</td></tr>
<tr><td>Alt+J</td><td>Justify entire buffer</td></tr>
<tr><td>Alt+B</td><td>Run a syntax check</td></tr>
<tr><td>Alt+F</td><td>Run a formatter/fixer/arranger</td></tr>
<tr><td>Alt+:</td><td>Start/stop recording of macro</td></tr>
<tr><td>Alt+T</td><td>Cut until end of buffer</td></tr>
<tr><td>Alt+:</td><td>Start/stop recording of macro &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td></tr>
<tr><td>Alt+;</td><td>Replay macro</td></tr>
</tbody></table>
<br>
@ -77,8 +80,8 @@
<b>Moving around</b>
<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><b>&larr;</b></td><td>One character backward</td></tr>
<tr><td><b>&rarr;</b></td><td>One character 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>
@ -87,6 +90,8 @@
<tr><td>Ctrl+N</td><td>One line down</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>Alt+Home &nbsp;</td><td>To first row in viewport</td></tr>
<tr><td>Alt+End</td><td>To last row in viewport</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>
@ -96,7 +101,7 @@
<b>Special movement</b>
<table><tbody>
<tr><td>Alt+G &nbsp;&nbsp;&nbsp;</td><td>Go to specified line</td></tr>
<tr><td>Alt+G &nbsp;&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>&uarr;</b></td><td>Scroll viewport up</td></tr>
<tr><td>Alt+<b>&darr;</b></td><td>Scroll viewport down</td></tr>
@ -108,20 +113,21 @@
<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 line/word/character count</td></tr>
<tr><td>Alt+D</td><td>Report line/word/character counts</td></tr>
<tr><td>Ctrl+G</td><td>Display help text</td></tr>
</tbody></table>
<br>
<b>Various</b>
<table><tbody>
<tr><td>Alt+A</td><td>Turn the mark on/off</td></tr>
<tr><td>Tab</td><td>Indent marked region</td></tr>
<tr><td>Shift+Tab &nbsp;&nbsp;</td><td>Unindent marked region</td></tr>
<tr><td>Alt+A &nbsp;&nbsp;&nbsp;&nbsp;</td><td>Set or unset the mark</td></tr>
<tr><td>Alt+V</td><td>Enter next keystroke verbatim</td></tr>
<tr><td>Alt+C</td><td>Turn constant position info on/off</td></tr>
<tr><td>Alt+N</td><td>Turn line numbers on/off</td></tr>
<tr><td>Alt+P</td><td>Turn visible whitespace on/off</td></tr>
<tr><td>Alt+X</td><td>Hide or unhide the help lines</td></tr>
<tr><td>Alt+S</td><td>Turn softwrapping on/off</td></tr>
<tr><td>Alt+X</td><td>Hide/unhide the help lines</td></tr>
<tr><td>Alt+Z</td><td>Hide/unhide the info bars</td></tr>
<tr><td>Ctrl+L</td><td>Refresh the screen</td></tr>
</tbody></table>
<br>

View File

@ -45,13 +45,13 @@
<blockquote><p>
<a href="#4.1">4.1. Alt+Up does nothing on a Linux console. How can I make it scroll?</a><br>
<a href="#4.2">4.2. How can I make Ctrl+Shift+Left/Right select words on urxvt?</a><br>
<a href="#4.3">4.3. Ack! My numeric keypad's keys don't work properly when NumLock is off! What can I do?</a><br>
<a href="#4.3">4.3. How do I remove an unwanted Byte Order Mark?</a><br>
<a href="#4.4">4.4. With what keystroke can I paste text from the clipboard into nano?</a><br>
<a href="#4.5">4.5. How do I select text for or paste text from the clipboard when nano's mouse support is turned on?</a><br>
<a href="#4.6">4.6. When I paste text into a document, each line gets indented further than the last. Why? And how can I stop this?</a><br>
<a href="#4.7">4.7. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</a><br>
<a href="#4.8">4.8. I've compiled nano with color support, but I don't see any color when I run it!</a><br>
<a href="#4.9">4.9. How do I make nano my default editor (in Pine, mutt, etc.)?</a><br>
<a href="#4.9">4.9. How do I make nano my default editor (in Pine, mutt, git, ...)?</a><br>
</p></blockquote>
<h3><a href="#5">5. Internationalization</a></h3>
<blockquote><p>
@ -76,10 +76,10 @@
</p></blockquote>
<hr width="100%">
<h1><a name="1"></a>1. General</h1>
<h3><a name="1.1"></a>1.1. What is GNU nano?</h3>
<h1 id="1">1. General</h1>
<h3 id="1.1">1.1. What is GNU nano?</h3>
<blockquote><p>GNU nano was designed to be a free replacement for the Pico text editor, part of the Pine email suite from <a href="http://www.washington.edu/pine/">The University of Washington</a>. It aimed to &quot;emulate Pico as closely as is reasonable and then include extra functionality&quot;.</p></blockquote>
<h3><a name="1.2"></a>1.2. What is the history behind nano?</h3>
<h3 id="1.2">1.2. What is the history behind nano?</h3>
<blockquote><p>Funny you should ask!</p>
<p><b>In the beginning...</b></p>
<p>For years Pine was THE program used to read email on a Unix system. The Pico text editor is the portion of the program one would use to compose his or her mail messages. Many beginners to Unix flocked to Pico and Pine because of their well organized, easy to use interfaces. With the proliferation of GNU/Linux in the mid to late 90's, many University students became intimately familiar with the strengths (and weaknesses) of Pine and Pico.</p>
@ -89,30 +89,30 @@
<p>It was in late 1999 when Chris Allegretta (our hero) was yet again complaining to himself about the less-than-perfect license Pico was distributed under, the 1000 makefiles that came with it and how just a few small improvements could make it the Best Editor in the World (TM). Having been a convert from Slackware to Debian, he missed having a simple binary package that included Pine and Pico, and had grown tired of downloading them himself.</p>
<p>Finally something snapped inside and Chris coded and hacked like a madman for many hours straight one weekend to make a (barely usable) Pico clone, at the time called TIP (Tip Isn't Pico). The program could not be invoked without a filename, could not save files, had no help text display, spell checker, and so forth. But over time it improved, and with the help of a few great coders it matured to the (hopefully) stable state it is in today.</p>
<p>In February 2001, nano was declared an official GNU program by Richard Stallman. nano also reached its first production release on March 22, 2001.</p></blockquote>
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
<h3 id="1.3">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>7.2</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
<h3><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h3>
<h3 id="1.4">1.4. What is the current version of nano?</h3>
<blockquote><p>The current version of nano <i>should</i> be <b>8.4</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
<h3 id="1.5">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%">
<h1><a name="2"></a>2. Where to get GNU nano.</h1>
<h3><a name="2.1"></a>2.1. Web sites that carry nano.</h3>
<h1 id="2">2. Where to get GNU nano.</h1>
<h3 id="2.1">2.1. Web sites that carry nano.</h3>
<blockquote><p>The nano source tarballs can be downloaded from the following web sites:</p>
<ul>
<li><a href="https://nano-editor.org/dist/latest/">https://nano-editor.org/dist/latest/</a></li>
<li><a href="https://ftpmirror.gnu.org/gnu/nano/">https://ftpmirror.gnu.org/gnu/nano/</a></li>
</ul>
</blockquote>
<h3><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h3>
<h3 id="2.2">2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h3>
<blockquote>
<ul>
<li><a href="https://kojipkgs.fedoraproject.org//packages/nano/">https://kojipkgs.fedoraproject.org//packages/nano/</a></li>
<li><a href="https://software.opensuse.org/package/nano">https://software.opensuse.org/package/nano</a></li>
</ul>
</blockquote>
<h3><a name="2.3"></a>2.3. Deb packages (Debian and derivatives):</h3>
<h3 id="2.3">2.3. Deb packages (Debian and derivatives):</h3>
<blockquote><p>Debian users can check out the current nano packages for:</p>
<ul>
<li><a href="https://packages.debian.org/stable/editors/nano">stable</a></li>
@ -121,14 +121,14 @@
</ul>
<p>You can also have a look at the <a href="http://ftp.debian.org/debian/pool/main/n/nano/">Package Pool</a> to see all the available binary and source packages.</p>
</blockquote>
<h3><a name="2.4"></a>2.4. By git (for the brave).</h3>
<h3 id="2.4">2.4. By git (for the brave).</h3>
<blockquote><p>For the "bleeding edge" current version of nano, you can use <b>git</b> to download the current source code. <i>Note:</i> believe it or not, by downloading code that has not yet stabilized into an official release, there could quite possibly be bugs, in fact the code may not even compile! Anyway, see <a href="http://git.savannah.gnu.org/cgit/nano.git/tree/README.hacking">the hacking document</a> for info on getting and building nano from git.</p></blockquote>
<hr width="100%">
<h1><a name="3"></a>3. Installation and Configuration</h1>
<h3><a name="3.1"></a>3.1. How do I install the RPM or DEB package?</h3>
<h1 id="3">3. Installation and Configuration</h1>
<h3 id="3.1">3.1. How do I install the RPM or DEB package?</h3>
<blockquote><p>It's simple really! As root, type <b>rpm -Uvh nano-x.y-1*.rpm</b> if you have a RedHat-ish system or <b>dpkg -i nano_x.y-1*.deb</b> if you have a Debian-ish system, where <b>x.y</b> is the version number of nano. There are other programs to install packages, and if you wish to use those, knock yourself out.</p></blockquote>
<h3><a name="3.2"></a>3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h3>
<h3 id="3.2">3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h3>
<blockquote><p>Okay, take a deep breath, this really isn't hard. Unpack the nano source with a command like:</p>
<p class="indented"><b>tar -xvf nano-x.y.tar.gz</b></p>
<p>Then you need to run <b>configure</b> with any options you might want (if any).</p>
@ -137,13 +137,13 @@
<b>./configure</b><br>
<b>make</b><br>
<b>make install</b>&nbsp;&nbsp; #(as root, of course)</p></blockquote>
<h3><a name="3.3"></a>3.3. Why does everything go into /usr/local?</h3>
<h3 id="3.3">3.3. Why does everything go into /usr/local?</h3>
<blockquote><p>Well, that's what the <b>configure</b> script defaults to. If you wish to change this, simply do this:</p>
<p class="indented"><b>./configure --prefix=/usr</b></p>
<p>This will put nano into /usr/bin when you run <b>make install</b>.</p></blockquote>
<h3><a name="3.4"></a>3.4. nano should automatically run strip on the binary when installing it!</h3>
<h3 id="3.4">3.4. nano should automatically run strip on the binary when installing it!</h3>
<blockquote><p>It does when you use <b>make install-strip</b>. The default <b>make install</b> does not, and will not, run strip automatically.</p></blockquote>
<h3><a name="3.5"></a>3.5. How can I make the executable smaller? This is too bloated!</h3>
<h3 id="3.5">3.5. How can I make the executable smaller? This is too bloated!</h3>
<blockquote><p>Actually, there are several parts of the editor that can be disabled. You can pass arguments to the <b>configure</b> script that disable certain features. Here's a brief list:</p>
<pre>
<b>--disable-browser</b> Disable the built-in file browser
@ -167,20 +167,20 @@
<b>--disable-wrapping</b> Disable all hard-wrapping of text</pre>
<p>There's also the <b>--enable-tiny</b> option which disables everything above, as well as some larger chunks of the program (like the undo/redo code and the code for selecting text). Also, if you know you don't need other languages, you can use <b>--disable-nls</b> to disable internationalization and save a few kilobytes. And finally, there's always good old <b>strip</b> to remove all unneeded symbols.</p>
</blockquote>
<h3><a name="3.6"></a>3.6. Tell me more about this multibuffer stuff!</h3>
<h3 id="3.6">3.6. Tell me more about this multibuffer stuff!</h3>
<blockquote><p>To use multiple file buffers, you must not have configured nano with <b>--disable-multibuffer</b> nor with <b>--enable-tiny</b> (use <b>nano -V</b> to check the compilation options). Then when you want to insert a file into its own buffer instead of into the current file, just hit <b>Meta-F</b> after typing <b>^R</b>. If you always want files to be loaded into their own buffers, use the <b>-F</b> or <b>--multibuffer</b> flag when you invoke nano, or add <b>set multibuffer</b> to your .nanorc file.</p>
<p>You can move between the buffers you have open with the <b>Meta-&lt;</b> and <b>Meta-&gt;</b> keys, or more easily without holding Shift: <b>Meta-,</b> and <b>Meta-.</b> (clear as mud, right? =-). When you have more than one buffer open, the ^X shortcut will say &quot;Close&quot;, instead of &quot;Exit&quot;.</p></blockquote>
<h3><a name="3.7"></a>3.7. Tell me more about this verbatim input stuff!</h3>
<h3 id="3.7">3.7. Tell me more about this verbatim input stuff!</h3>
<blockquote><p>When you want to insert a literal character into the file you're editing, such as a control character that nano usually treats as a command, first press <b>Meta-V</b> (if you're not at a prompt, you'll get the message &quot;Verbatim Input&quot; on the status bar), then press the key(s) that generate the character you want.</p>
<p>Alternatively, if Unicode support is enabled (see section <a href="#5.3">5.3</a>), you can press <b>Meta-V</b> and then type a six-digit hexadecimal code (from 000000 to 10FFFF, case-insensitive), and the character with the corresponding value will be inserted. The status bar will change to &quot;Unicode Input: ......&quot; when you do this.</p></blockquote>
<h3><a name="3.8"></a>3.8. How do I make a .nanorc file that will be read when I start nano?</h3>
<h3 id="3.8">3.8. How do I make a .nanorc file that will be read when I start nano?</h3>
<blockquote><p>It's not hard at all! Simply copy the <b>sample.nanorc</b> from the doc/ directory in the nano source package (or from /usr/doc/nano on your system) to <b>.nanorc</b> in your home directory, and then edit it. If you didn't get a sample nanorc, the syntax of the file is simple: features are turned on and off by using the words <b>set</b> and <b>unset</b> followed by the long option name of the feature (see <b>man nanorc</b> for the full list of options). For example, &quot;set quickblank&quot; or &quot;set smarthome&quot;. Of course, for this to work, your nano must <b>not</b> have been compiled with <b>--disable-nanorc</b>.</p></blockquote>
<h3><a name="3.9"></a>3.9. Why does my self-compiled nano not read /etc/nanorc?</h3>
<blockquote><p>By default (see <a href="#3.3">3.3</a>), nano gets installed into /usr/local. This also means that, at startup, nano will read <b>/usr/local/etc/nanorc</b> instead of <b>/etc/nanorc</b>. You can make a symlink from the former to the latter if you want your self-compiled nano to read the same nanorc as the system-installed nano. Or you can configure your nano to overwrite the system nano (again, see <a href="#3.3">3.3</a>).</p></blockquote>
<h3 id="3.9">3.9. Why does my self-compiled nano not read /etc/nanorc?</h3>
<blockquote><p>By default (see <a href="#3.3">3.3</a>), nano gets installed into /usr/local. This also means that, at startup, nano reads <b>/usr/local/etc/nanorc</b> instead of <b>/etc/nanorc</b>. You can make a symlink from the former to the latter if you want your self-compiled nano to read the same nanorc as the system-installed nano. Or you can configure your nano to overwrite the system nano (again, see <a href="#3.3">3.3</a>).</p></blockquote>
<hr width="100%">
<h1><a name="4"></a>4. Running</h1>
<h3><a name="4.1"></a>4.1. Alt+Up does nothing on a Linux console. How can I make it scroll?</h3>
<h1 id="4">4. Running</h1>
<h3 id="4.1">4.1. Alt+Up does nothing on a Linux console. How can I make it scroll?</h3>
<blockquote><p>On Debian and its derivatives, the <b>Alt+Up</b> keystroke on a Linux console
produces by default a 'KeyboardSignal', which normally does absolutely nothing and is useless
for the average user. To get the keystroke to do what it ought to do (scroll the viewport
@ -193,7 +193,7 @@
&nbsp;&nbsp;&nbsp;&nbsp;sed -i 's/KeyboardSignal/Up/' ${file%.gz};<br>
&nbsp;&nbsp;&nbsp;&nbsp;gzip ${file%.gz};<br>
done</b></p></blockquote>
<h3><a name="4.2"></a>4.2. How can I make Ctrl+Shift+Left/Right select words on urxvt?</h3>
<h3 id="4.2">4.2. How can I make Ctrl+Shift+Left/Right select words on urxvt?</h3>
<blockquote><p>The urxvt terminal emulator produces non-standard escape sequences for the modified cursor keys. These deviant sequences are not listed in the terminfo database, which means that ncurses does not recognize them. The easiest way around this is to tell urxvt to produce xterm-compatible escape sequences for the relevant keystrokes. To achieve this, add the following lines to your ~/.Xresources file:</p>
<pre>
URxvt.iso14755_52: False
@ -208,31 +208,35 @@
URxvt.keysym.M-Right: \033[1;3C
URxvt.keysym.M-Left: \033[1;3D
URxvt.keysym.M-Home: \033[1;3H
URxvt.keysym.M-End: \033[1;3F
URxvt.keysym.M-Insert: \033[2;3~
URxvt.keysym.M-Delete: \033[3;3~
URxvt.keysym.M-Page_Up: \033[5;3~
URxvt.keysym.M-Page_Down: \033[6;3~</pre>
URxvt.keysym.M-Page_Down: \033[6;3~
URxvt.keysym.S-Page_Up: \033[5;2~
URxvt.keysym.S-Page_Down: \033[6;2~</pre>
<p>Then run <b>xrdb ~/.Xresources</b> and restart your urxvt terminal. Now <b>Ctrl+Shift+Left</b> and <b>Ctrl+Shift+Right</b> will select words, <b>Alt+Up</b> and <b>Alt+Down</b> will scroll the text without moving the cursor, and several such things more.</p></blockquote>
<h3><a name="4.3"></a>4.3. Ack! My numeric keypad's keys don't work properly when NumLock is off! What can I do?</h3>
<blockquote><p>You can use the <b>-K</b> or <b>--rawsequences</b> option on the command line, or add the line <b>set rawsequences</b> to your .nanorc. However, nano's mouse support will be disabled if you do any of these things.</p></blockquote>
<h3><a name="4.4"></a>4.4. With what keystroke can I paste text from the clipboard into nano?</h3>
<blockquote><p>In most desktop environments <b>Shift+Insert</b> will paste the contents of the clipboard.</p></blockquote>
<h3><a name="4.5"></a>4.5. How do I select text for or paste text from the clipboard when nano's mouse support is turned on?</h3>
<h3 id="4.3">4.3. How do I remove an unwanted Byte Order Mark?</h3>
<blockquote><p>To check whether a file contains a Byte Order Mark (BOM), open the file and type <b>Ctrl+Home</b>. If there is a BOM, the status bar will tell you so. Now type <b>Delete</b> to remove the BOM, and <b>^S</b> to save the file.</p>
<p>If you've accidentally deleted a Byte Order Mark from a file that needs it, and you want to restore it, then type: <b>Ctrl+Home Alt+V feff Enter</b>. Verify that the BOM is back with <b>Ctrl+Home</b>, and save the file with <b>^S</b>. (Note that on Unix, files should not contain a BOM.)</p></blockquote>
<h3 id="4.4">4.4. With what keystroke can I paste text from the clipboard into nano?</h3>
<blockquote><p>In most desktop environments <b>Shift+Insert</b> pastes the contents of the clipboard.</p></blockquote>
<h3 id="4.5">4.5. How do I select text for or paste text from the clipboard when nano's mouse support is turned on?</h3>
<blockquote><p>Try holding down the Shift key and selecting or pasting the text as you normally would.</p></blockquote>
<h3><a name="4.6"></a>4.6. When I paste text into a document, each line gets indented further than the last. Why? And how can I stop this?</h3>
<h3 id="4.6">4.6. When I paste text into a document, each line gets indented further than the last. Why? And how can I stop this?</h3>
<blockquote><p>You have the <i>autoindent</i> feature turned on. Hit <b>Meta-I</b> to turn it off, paste your text, and then hit <b>Meta-I</b> again to turn it back on.</p>
<p><i>Update:</i> Since version 4.8, nano will suppress auto-indentation during a paste (when your terminal understands <a href="https://en.wikipedia.org/wiki/Bracketed-paste">bracketed pastes</a>), so you no longer need to toggle it off and on manually.</p></blockquote>
<h3><a name="4.7"></a>4.7. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</h3>
<p><i>Update:</i> Since version 4.8, nano suppresses auto-indentation during a paste (when your terminal understands <a href="https://en.wikipedia.org/wiki/Bracketed-paste">bracketed pastes</a>), so you no longer need to toggle it off and on manually.</p></blockquote>
<h3 id="4.7">4.7. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</h3>
<blockquote><p>When pasting from Windows, in some situations linefeeds are sent instead of carriage returns (Enters). And linefeeds are <b>^J</b>s, which make nano justify (rewrap) the current paragraph. To prevent these linefeeds from causing these unwanted justifications, add this line to your .nanorc on the remote Linux box: <b>unbind ^J main</b> or <b>bind ^J enter main</b>, depending on whether the paste contains CR + LF or only LF.</p>
<p><i>Update:</i> Since version 4.8, nano will ignore linefeed characters in a paste (when your terminal understands <a href="https://en.wikipedia.org/wiki/Bracketed-paste">bracketed pastes</a>), so you no longer need the above workaround.</p></blockquote>
<h3><a name="4.8"></a>4.8. I've compiled nano with color support, but I don't see any color when I run it!</h3>
<p><i>Update:</i> Since version 4.8, nano ignores linefeed characters in a paste (when your terminal understands <a href="https://en.wikipedia.org/wiki/Bracketed-paste">bracketed pastes</a>), so you no longer need the above workaround.</p></blockquote>
<h3 id="4.8">4.8. I've compiled nano with color support, but I don't see any color when I run it!</h3>
<blockquote><p>If you want nano to actually use color, you have to specify the color configurations you want it to use in your .nanorc. Several example configurations are in the <b>syntax/</b> subdirectory of the nano source, which are normally installed to <b>/usr/local/share/nano/</b>. To enable all of them, uncomment the line <b># include "/usr/local/share/nano/*.nanorc"</b> in your nanorc. See also section <a href="#3.9">3.9</a>.</p></blockquote>
<h3><a name="4.9"></a>4.9. How do I make nano my default editor (in Pine, mutt, etc.)?</h3>
<h3 id="4.9">4.9. How do I make nano my default editor (in Pine, mutt, git, ...)?</h3>
<blockquote><p>You need to make nano your $EDITOR. If you want this to be saved, you should put a line like this in your <b>.bashrc</b> if you use bash (or <b>.zshrc</b> if you believe in zsh):</p>
<p class="indented"><b>export EDITOR=/usr/local/bin/nano</b></p>
<p>or, if you use tcsh, put this in your <b>.cshrc</b> file:</p>
<p class="indented"><b>setenv EDITOR /usr/local/bin/nano</b></p>
<p>Change /usr/local/bin/nano to wherever nano is installed on your system. Type &quot;which nano&quot; to find out. This will not take effect until the next time you log in. So log out and back in again.</p>
<p>Then, on top of that, if you use Pine, you must go into setup (type <b>S</b> at the main menu), and then configure (type <b>C</b>). Hit Enter on the lines that say:</p>
<p class="indented"><b>[ ] enable-alternate-editor-cmd</b><br>
@ -240,47 +244,50 @@
<p>Then exit (<b>E</b>) and select Yes (<b>Y</b>).</p>
<p>If you're a mutt user, you should see an effect immediately the next time you log in. No further configuration is needed. However, if you want to let people know you use nano to compose your email messages, you can put a line like this in your <b>.muttrc</b>:</p>
<p class="indented"><b>my_hdr X-Composer: nano-x.y</b></p>
<p>Again, replace x.y with the version of nano you use.</p></blockquote>
<p>Again, replace x.y with the version of nano you use.</p>
<p>To use nano to edit your git commit messages, you can run:</p>
<p class="indented"><b>git config --global core.editor "nano --guide=74 --nohelp +1"</b></p>
<p>Note the <b>+1</b> at the end — it makes nano start always at the top of the edit window. The guidestripe helps you keep the text within a reasonable width.</blockquote>
<hr width="100%">
<h1><a name="5"></a>5. Internationalization</h1>
<h3><a name="5.1"></a>5.1. There's no translation for my language!</h3>
<h1 id="5">5. Internationalization</h1>
<h3 id="5.1">5.1. There's no translation for my language!</h3>
<blockquote><p>In June 2001, GNU nano entered the <a href="https://translationproject.org/html/welcome.html">Translation Project</a> and since then, translations should be managed from there.</p>
<p>If there isn't a translation for your language, you could ask <a href="https://translationproject.org/team/">your language team</a> to translate nano, or better still, join that team and do it yourself. Joining a team is easy. You just need to ask the team leader to add you, and then send a <a href="https://translationproject.org/disclaim.txt">translation disclaimer to the FSF</a> (this is necessary as nano is an official GNU package, but it does <b>not</b> mean that you transfer the rights of your work to the FSF, it's just so the FSF can legally manage them).</p>
<p>In any case, translating nano is easy. Just grab the latest <b>nano.pot</b> file listed on <a href="https://translationproject.org/domain/nano.html">nano's page</a> at the TP, and translate each <b>msgid</b> line into your native language on the <b>msgstr</b> line. When you're done, you should send it to the TP's central PO-file repository.</p></blockquote>
<h3><a name="5.2"></a>5.2. I don't like the translation for &lt;x&gt; in my language. How can I fix it?</h3>
<h3 id="5.2">5.2. I don't like the translation for &lt;x&gt; in my language. How can I fix it?</h3>
<blockquote><p>The best way is to send an e-mail with your suggested corrections to the team's mailing list. The address is mentioned in the <code>Language-Team:</code> field in the relevant PO file. The team leader or the assigned translator can then make the changes reach the nano-devel list.</p></blockquote>
<h3><a name="5.3"></a>5.3. What is the status of Unicode support?</h3>
<h3 id="5.3">5.3. What is the status of Unicode support?</h3>
<blockquote><p>Unicode should be fully usable nowadays. When the encoding of your terminal is set to UTF-8, and your locale (mainly the LANG environment variable) is UTF-8 too, then you should be able to read, enter and save Unicode text.</p></blockquote>
<hr width="100%">
<h1><a name="6"></a>6. Advocacy and Licensing</h1>
<h3><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h3>
<h1 id="6">6. Advocacy and Licensing</h1>
<h3 id="6.1">6.1. Why should I use nano instead of Pico?</h3>
<blockquote><p>If you want features like undo/redo, syntax highlighting, line numbers, soft-wrapping, opening multiple files at once, an interface localized to your language, or search and replace with support for regular expressions, then you want nano.</p></blockquote>
<h3><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h3>
<h3 id="6.2">6.2. Why should I use Pico instead of nano?</h3>
<blockquote><p>If you use your editor only to write emails or other texts and have no need for the above-mentioned features, then Pico will do fine for you.</p></blockquote>
<h3><a name="6.3"></a>6.3. What is so bad about the older Pine license?</h3>
<h3 id="6.3">6.3. What is so bad about the older Pine license?</h3>
<blockquote><p>The U of W license for older versions of Pine and Pico is not considered truly Free Software according to both the Free Software Foundation and the <a href="https://www.debian.org/social_contract#guidelines">Debian Free Software Guidelines</a>. The main problem regards the limitations on distributing derived works: according to UW, you can distribute their software, and you can modify it, but you can not do both, i.e. distribute modified binaries.</p></blockquote>
<h3><a name="6.4"></a>6.4. Okay, well, what mail program should I use then?</h3>
<h3 id="6.4">6.4. Okay, well, what mail program should I use then?</h3>
<blockquote><p>If you are looking to use a Free Software program similar to Pine, and Emacs is not your thing, you should definitely take a look at <a href="http://www.mutt.org/">mutt</a>. It is a full-screen, console based mail program that actually has a lot more flexibility than Pine, but has a keymap included in the distribution that allows you to use the same keystrokes as Pine would to send and receive mail. It's also under the GNU General Public License, version 2.0.</p>
<p>Of course, due to the license change you can now use the <a href="http://www.washington.edu/alpine/">Alpine distribution</a> of PINE as it is now considered Free Software, but you would be sacrificing many of nano's features to do so.</p></blockquote>
<hr width="100%">
<h1><a name="7"></a>7. Miscellaneous</h1>
<h3><a name="7.1"></a>7.1. Where can I ask questions or send suggestions?</h3>
<h1 id="7">7. Miscellaneous</h1>
<h3 id="7.1">7.1. Where can I ask questions or send suggestions?</h3>
<blockquote><p>There are three mailing lists for nano hosted at <a href="https://savannah.gnu.org/">Savannah</a>: info-nano, help-nano and nano-devel. info-nano is a very low traffic list where new versions of nano are announced (surprise!). help-nano is for getting help with the editor without needing to hear all of the development issues surrounding it. nano-devel is a normally low, sometimes high traffic list for discussing the present and future development of nano. Here are links to where you can sign up for a given list:</p>
<p>info-nano - <a href="https://lists.gnu.org/mailman/listinfo/info-nano/">https://lists.gnu.org/mailman/listinfo/info-nano/</a><br>
help-nano - <a href="https://lists.gnu.org/mailman/listinfo/help-nano/">https://lists.gnu.org/mailman/listinfo/help-nano/</a><br>
nano-devel - <a href="https://lists.gnu.org/mailman/listinfo/nano-devel/">https://lists.gnu.org/mailman/listinfo/nano-devel/</a></p></blockquote>
<h3><a name="7.2"></a>7.3. How do I submit a bug report or patch?</h3>
<h3 id="7.2">7.3. How do I submit a bug report or patch?</h3>
<blockquote>
<p>The best way to submit bugs is through the <a href="https://savannah.gnu.org/bugs/?group=nano">Savannah bug tracker</a>, as you can check whether the bug you are reporting has already been submitted, and it makes it easier for the maintainers to keep track of them.
<p>You can submit patches for nano via <a href="https://savannah.gnu.org/patch/?group=nano">Savannah's patch manager</a>.</p></blockquote>
<h3><a name="7.3"></a>7.3. I want to send the development team a big load of cash (or just a thank you).</h3>
<h3 id="7.3">7.3. I want to send the development team a big load of cash (or just a thank you).</h3>
<blockquote><p>That's fine. Send it <a href="mailto:nano-devel@gnu.org">our way</a>! Better yet, fix a <a href="https://savannah.gnu.org/bugs/?group=nano">bug</a> in the program or implement a <a href="https://nano-editor.org/dist/latest/TODO">cool feature</a> and send us that instead (though cash is fine too).</p></blockquote>
<h3><a name="7.4"></a>7.4. How do I join the development team?</h3>
<h3 id="7.4">7.4. How do I join the development team?</h3>
<blockquote><p>The easiest way is to consistently send in good patches that add some needed functionality, fix a bug or two, and/or make the program more optimized/efficient. Then ask nicely and you will probably be added to the Savannah development list and be given write access after a while. There is a lot of responsibility that goes along with being a team member, so don't think it's just something to add to your resume.</p></blockquote>
<h3><a name="7.5"></a>7.5. Can I have write access to the git tree?</h3>
<h3 id="7.5">7.5. Can I have write access to the git tree?</h3>
<blockquote><p>Re-read section <a href="#7.4">7.4</a> and you should know the answer.</p></blockquote>
<hr width="100%">

View File

@ -1,4 +1,4 @@
.\" Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc.
.\" Copyright (C) 1999-2011, 2013-2025 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 7.2" "January 2023"
.TH NANO 1 "version 8.4" "April 2025"
.SH NAME
nano \- Nano's ANOther text editor, inspired by Pico
@ -25,13 +25,28 @@ nano \- Nano's ANOther text editor, inspired by Pico
.B nano
.RI [ options "] [[\fB+" line [\fB, column "]] " file ]...
.sp
.B nano
.RI [ options "] [" file [\fB: line [\fB: column "]]]..."
.sp
.BR nano " [" \fIoptions "] [[" + [ crCR ]{ / | ? } \fIstring "] " \fIfile ]...
.SH NOTICE
Since version 8.0, to be newcomer friendly, \fB^F\fR starts a forward search,
\fB^B\fR starts a backward search, \fBM\-F\fR searches the next occurrence
forward, and \fBM\-B\fR searches the next occurrence backward. If you want
those keystrokes to do what they did before version 8.0, add the following
lines at the end of your \fInanorc\fR file:
.sp
.RS 4
.B bind ^F forward main
.br
.B bind ^B back main
.br
.B bind M\-F formatter main
.br
.B bind M\-B linter main
.RE
.sp
.SH DESCRIPTION
\fBnano\fP is a small and friendly text editor. It copies the look and feel
\fBnano\fR is a small and friendly text editor. It copies the look and feel
of Pico, but is free software, and implements several features that Pico
lacks, such as: opening multiple files, scrolling per line, undo/redo,
syntax coloring, line numbering, and soft-wrapping overlong lines.
@ -40,9 +55,6 @@ When giving a filename on the command line, the cursor can be put on a
specific line by adding the line number with a plus sign (\fB+\fR) before
the filename, and even in a specific column by adding it with a comma.
Negative numbers count from the end of the file or line.
The line and column numbers may also be specified by gluing them with colons
after the filename. (When a filename contains a colon followed by digits,
escape the colon by preceding it with a triple backslash.)
.sp
The cursor can be put on the first or last occurrence of a specific string
by specifying that string after \fB+/\fR or \fB+?\fR before the filename.
@ -65,21 +77,21 @@ Entering text and moving around in a file is straightforward: typing the
letters and using the normal cursor movement keys. Commands are entered
by using the Control (^) and the Alt or Meta (M\-) keys.
Typing \fB^K\fR deletes the current line and puts it in the cutbuffer.
Consecutive \fB^K\fRs will put all deleted lines together in the cutbuffer.
Any cursor movement or executing any other command will cause the next
\fB^K\fR to overwrite the cutbuffer. A \fB^U\fR will paste the current
Consecutive \fB^K\fRs put all deleted lines together in the cutbuffer.
Any cursor movement or executing any other command causes the next
\fB^K\fR to overwrite the cutbuffer. A \fB^U\fR pastes the current
contents of the cutbuffer at the current cursor position.
.sp
When a more precise piece of text needs to be cut or copied, you can mark
its start with \fB^6\fR, move the cursor to its end (the marked text will be
highlighted), and then use \fB^K\fR to cut it, or \fBM\-6\fR to copy it to the
cutbuffer. You can also save the marked text to a file with \fB^O\fR, or
spell check it with \fB^T^T\fR.
its start with \fB^6\fR, move the cursor to its end (the marked text is
highlighted), and then use \fB^K\fR to cut it, or \fBM\-6\fR to copy it to
the cutbuffer. You can also save the marked text to a file with \fB^O\fR,
or spell check it with \fB^T^T\fR.
.sp
On some terminals, text can be selected also by holding down Shift while
using the arrow keys. Holding down the Ctrl or Alt key too will increase
using the arrow keys. Holding down the Ctrl or Alt key too increases
the stride.
Any cursor movement without Shift being held will cancel such a selection.
Any cursor movement without Shift being held cancels such a selection.
.sp
Any valid Unicode code point can be inserted into the buffer by typing
\fBM\-V\fR followed by the hexadecimal digits of the code point (concluded
@ -89,35 +101,38 @@ A literal control code (except \fB^J\fR) can be inserted by typing
.sp
The two lines at the bottom of the screen show some important commands;
the built-in help (\fB^G\fR) lists all the available ones.
The default key bindings can be changed via a \fInanorc\fR file -- see
The default key bindings can be changed via a \fInanorc\fR file \(em see
.BR nanorc (5).
.\" Never hyphenate these:
.hw ncurses terminfo
.SH OPTIONS
.TP
.BR \-A ", " \-\-smarthome
Make the Home key smarter. When Home is pressed anywhere but at the
very beginning of non-whitespace characters on a line, the cursor will
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.
very beginning of non-whitespace characters on a line, the cursor jumps
to that beginning (either forwards or backwards). If the cursor is
already at that position, it jumps to the true beginning of the line.
.TP
.BR \-B ", " \-\-backup
When saving a file, back up the previous version of it, using the current
filename suffixed with a tilde (\fB~\fP).
filename suffixed with a tilde (\fB~\fR).
.TP
.BR \-C\ \fIdirectory ", " \-\-backupdir= \fIdirectory
Make and keep not just one backup file, but make and keep a uniquely
numbered one every time a file is saved -- when backups are enabled (\fB\-B\fR).
.BI \-C " directory\fR, " \-\-backupdir= directory
Make and keep not just one backup file, but make and keep a uniquely numbered
one every time a file is saved \(em when backups are enabled (\fB\-B\fR).
The uniquely numbered files are stored in the specified \fIdirectory\fR.
.TP
.BR \-D ", " \-\-boldtext
For the interface, use bold instead of reverse video. This will be overridden
by setting the options \fBtitlecolor\fP, \fBstatuscolor\fP, \fBkeycolor\fP,
\fBfunctioncolor\fP, \fBnumbercolor\fP, and/or \fBselectedcolor\fP in your
nanorc file. See \fBnanorc\fR(5).
For the interface, use bold instead of reverse video.
This can be overridden for specific elements by setting the options
\fB\%titlecolor\fR, \fB\%statuscolor\fR, \fB\%promptcolor\fR,
\fB\%minicolor\fR, \fB\%keycolor\fR, \fB\%numbercolor\fR, and/or
\fB\%selectedcolor\fR in your nanorc file. See \fBnanorc\fR(5).
.TP
.BR \-E ", " \-\-tabstospaces
Convert each typed tab to spaces -- to the number of spaces
Convert each typed tab to spaces \(em to the number of spaces
that a tab at that position would take up.
(Note: pasted tabs are not converted.)
.TP
@ -134,17 +149,17 @@ executed commands, so they can be easily reused in later sessions.
.BR \-I ", " \-\-ignorercfiles
Don't look at the system's \fInanorc\fR nor at the user's \fInanorc\fR.
.TP
.BR \-J\ \fInumber ", " \-\-guidestripe= \fInumber
.BI \-J " number\fR, " \-\-guidestripe= number
Draw a vertical stripe at the given column, to help judge the width of the
text. (The color of the stripe can be changed with \fBset stripecolor\fR
text. (The color of the stripe can be changed with \fBset \%stripecolor\fR
in your \fInanorc\fR file.)
.TP
.BR \-K ", " \-\-rawsequences
Interpret escape sequences directly, instead of asking \fBncurses\fR
to translate them. (If you need this option to get some keys to work
properly, it means that the terminfo terminal description that is used
does not fully match the actual behavior of your terminal. This can
happen when you ssh into a BSD machine, for example.)
properly, it means that the \fBterminfo\fR terminal description that
is used does not fully match the actual behavior of your terminal.
This can happen when you ssh into a BSD machine, for example.)
Using this option disables \fBnano\fR's mouse support.
.TP
.BR \-L ", " \-\-nonewlines
@ -166,10 +181,10 @@ beginning of a paragraph (unless auto-indenting is on).
For the 200 most recent files, log the last position of the cursor,
and place it at that position again upon reopening such a file.
.TP
.BR "\-Q ""\fIregex\fB""" ", " "\-\-quotestr=""" \fIregex """
.BI "\-Q """ regex\fB"\fR, " \-\-quotestr=""" regex """"
Set the regular expression for matching the quoting part of a line.
The default value is "\fB^([\ \\t]*([!#%:;>|}]|//))+\fR".
(Note that \fB\\t\fP stands for an actual Tab.)
(Note that \fB\\t\fR stands for an actual Tab.)
This makes it possible to rejustify blocks of quoted text when composing
email, and to rewrap blocks of line comments when writing source code.
.TP
@ -179,17 +194,16 @@ command line. This means: don't read or write history files;
don't allow suspending; don't allow spell checking;
don't allow a file to be appended to, prepended to, or saved under a
different name if it already has one; and don't make backup files.
Restricted mode can also be activated by invoking \fBnano\fP
with any name beginning with 'r' (e.g. "rnano").
Restricted mode can also be activated by invoking \fBnano\fR
with any name beginning with 'r' (e.g.\& "rnano").
.TP
.BR \-S ", " \-\-softwrap
Display over multiple screen rows lines that exceed the screen's width.
(You can make this soft-wrapping occur at whitespace instead of rudely at
the screen's edge, by using also \fB\-\-atblanks\fR.)
(The old short option, \fB\-$\fR, is deprecated.)
.TP
.BR \-T\ \fInumber ", " \-\-tabsize= \fInumber
Set the size (width) of a tab to \fInumber\fP columns. The value of
.BI \-T " number\fR, " \-\-tabsize= number
Set the size (width) of a tab to \fInumber\fR columns. The value of
\fInumber\fR must be greater than 0. The default value is \fB8\fR.
.TP
.BR \-U ", " \-\-quickblank
@ -207,14 +221,14 @@ Show the current version number and exit.
Detect word boundaries differently by treating punctuation
characters as part of a word.
.TP
.BR "\-X ""\fIcharacters\fB""" ", " "\-\-wordchars=""" \fIcharacters """
.BI "\-X """ characters\fB"\fR, " \-\-wordchars=""" characters """"
Specify which other characters (besides the normal alphanumeric ones)
should be considered as part of a word. When using this option, you
probably want to omit \fB\-W\fR (\fB\-\-wordbounds\fR).
.TP
.BR \-Y\ \fIname ", " \-\-syntax= \fIname
.BI \-Y " name\fR, " \-\-syntax= name
Specify the name of the syntax highlighting to use from among the ones
defined in the \fInanorc\fP files.
defined in the \fInanorc\fR files.
.TP
.BR \-Z ", " \-\-zap
Let an unmodified Backspace or Delete erase the marked region
@ -230,7 +244,7 @@ Automatically hard-wrap the current line when it becomes overlong.
the last one given takes effect.)
.TP
.BR \-c ", " \-\-constantshow
Constantly show the cursor position on the status bar.
Constantly report the cursor position on the status bar.
Note that this overrides option \fB\-U\fR (\fB\-\-quickblank\fR).
.TP
.BR \-d ", " \-\-rebinddelete
@ -241,7 +255,7 @@ system either Backspace acts like Delete or Delete acts like Backspace.
.BR \-e ", " \-\-emptyline
Do not use the line below the title bar, leaving it entirely blank.
.TP
.BR \-f\ \fIfile ", " \-\-rcfile= \fIfile
.BI \-f " file\fR, " \-\-rcfile= file
Read only this \fIfile\fR for setting nano's options, instead of reading
both the system-wide and the user's nanorc files.
.TP
@ -272,33 +286,34 @@ Display line numbers to the left of the text area.
.BR \-m ", " \-\-mouse
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 Window
click), and execute shortcuts. The mouse works in the X Window
System, and on the console when gpm is running. Text can still be
selected through dragging by holding down the Shift key.
.TP
.BR \-n ", " \-\-noread
Treat any name given on the command line as a new file. This allows
\fBnano\fR to write to named pipes: it will start with a blank buffer,
and will write to the pipe when the user saves the "file". This way
\fBnano\fR to write to named pipes: it starts with a blank buffer,
and writes to the pipe when the user saves the "file". This way
\fBnano\fR can be used as an editor in combination with for instance
\fBgpg\fR without having to write sensitive data to disk first.
.TP
.BR \-o\ \fIdirectory ", " \-\-operatingdir= \fIdirectory
Set the operating directory. This makes \fBnano\fP set up something
.BI \-o " directory\fR, " \-\-operatingdir= directory
Set the operating directory. This makes \fBnano\fR set up something
similar to a chroot.
.TP
.BR \-p ", " \-\-preserve
Preserve the XON and XOFF sequences (\fB^Q\fR and \fB^S\fR) so they
will be caught by the terminal.
Preserve the XOFF and XON sequences (\fB^S\fR and \fB^Q\fR) so that
they are caught by the terminal (stopping and resuming the output).
Note that option \fB\-/\fR (\fB\-\-modernbindings\fR) overrides this.
.TP
.BR \-q ", " \-\-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.
.TP
.BR \-r\ \fInumber ", " \-\-fill= \fInumber
.BI \-r " number\fR, " \-\-fill= number
Set the target width for justifying and automatic hard-wrapping at this
\fInumber\fR of columns. If the value is 0 or less, wrapping will occur
\fInumber\fR of columns. If the value is 0 or less, wrapping occurs
at the width of the screen minus \fInumber\fR columns, allowing the wrap
point to vary along with the width of the screen if the screen is resized.
The default value is \fB\-8\fR.
@ -323,7 +338,7 @@ unless \fB\-\-restricted\fR is given too.
.BR \-w ", " \-\-nowrap
Do not automatically hard-wrap the current line when it becomes overlong.
This is the default. (This option is the opposite of \fB\-b\fR
(\fB\-\-breaklonglines\fR) -- the last one given takes effect.)
(\fB\-\-breaklonglines\fR) \(em the last one given takes effect.)
.TP
.BR \-x ", " \-\-nohelp
Don't show the two help lines at the bottom of the screen.
@ -331,10 +346,23 @@ Don't show the two help lines at the bottom of the screen.
.BR \-y ", " \-\-afterends
Make Ctrl+Right and Ctrl+Delete stop at word ends instead of beginnings.
.TP
.BR \-z ", " \-\-listsyntaxes
List the names of the available syntaxes and exit.
.TP
.BR \-! ", " \-\-magic
When neither the file's name nor its first line give a clue,
try using libmagic to determine the applicable syntax.
.TP
.BR \-@ ", " \-\-colonparsing
When a filename given on the command line ends in a colon plus digits
and this filename does not exist, then snip the colon plus digits and
understand the digits as a line number. If the trimmed filename does
not exist either, then repeat the process and understand the obtained
two numbers as line and column number. But if the doubly trimmed
filename does not exist either, then forget the trimming and accept
the original filename as is. To disable this colon parsing for some
file, use \fB+1\fR or similar before the relevant filename.
.TP
.BR \-% ", " \-\-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
@ -346,7 +374,7 @@ filename in the center of the title bar.
.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 filename is shown
for the status bar. In this "mini bar" the filename 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),
@ -367,6 +395,19 @@ The status bar appears only when there is a significant message,
and disappears after 1.5 seconds or upon the next keystroke.
With \fBM\-Z\fR the title bar plus status bar can be toggled.
With \fBM\-X\fR the help lines.
.TP
.BR \-/ ", " \-\-modernbindings
Use key bindings similar to the ones that most modern programs use:
\fB^X\fR cuts, \fB^C\fR copies, \fB^V\fR pastes,
\fB^Z\fR undoes, \fB^Y\fR redoes,
\fB^F\fR searches forward, \fB^G\fR searches next,
\fB^S\fR saves, \fB^O\fR opens a file, \fB^Q\fR quits,
and (when the terminal permits) \fB^H\fR shows help.
Furthermore, \fB^A\fR sets the mark,
\fB^R\fR makes replacements, \fB^D\fR searches previous,
\fB^P\fR shows the position, \fB^T\fR goes to a line,
\fB^W\fR writes out a file, and \fB^E\fR executes a command.
Note that this overrides option \fB\-p\fR (\fB\-\-preserve\fR).
.SH TOGGLES
Several of the above options can be switched on and off also while
@ -381,9 +422,9 @@ the help viewer and the linter. All other toggles work in
the main menu only.
.SH FILES
When \fB\-\-rcfile\fR is given, \fBnano\fR will read just the specified file
for setting its options and syntaxes and key bindings. Without that option,
\fBnano\fR will read two configuration files: first the system's
When \fB\-\-rcfile\fR is given, \fBnano\fR reads just the specified file
for setting its options and syntaxes and key bindings. Without that
option, \fBnano\fR reads two configuration files: first the system's
\fInanorc\fR (if it exists), and then the user's \fInanorc\fR (if it
exists), either \fI~/.nanorc\fR or \fI$XDG_CONFIG_HOME/nano/nanorc\fR
or \fI~/.config/nano/nanorc\fR, whichever is encountered first. See
@ -394,30 +435,31 @@ See \fI/usr/share/nano/\fR and \fI/usr/share/nano/extra/\fR
for available syntax-coloring definitions.
.SH NOTES
Option \fB\-z\fR (\fB\-\-suspendable\fR) has been removed.
Suspension is enabled by default, reachable via \fB^T^Z\fR.
(If you want a plain \fB^Z\fR to suspend nano, add
\fBbind ^Z suspend main\fR to your nanorc.)
.sp
At a Yes-No prompt, \fB^Y\fR can be used for "Yes", \fB^N\fR for "No",
and \fB^A\fR for "All". These unlisted bindings work in any locale.
.sp
When you want to copy marked text from \fBnano\fR to the system's clipboard,
see one of the examples in the \fBnanorc\fR(5) man page.
.sp
If no alternative spell checker command is specified on the command
line nor in one of the \fInanorc\fP files, \fBnano\fP will check the
\fBSPELL\fP environment variable for one.
line nor in one of the \fInanorc\fR files, \fBnano\fR checks the
\fBSPELL\fR environment variable for one.
.sp
In some cases \fBnano\fP will try to dump the buffer into an emergency
file. This will happen mainly if \fBnano\fP receives a SIGHUP or
SIGTERM or runs out of memory. It will write the buffer into a file
named \fInano.save\fP if the buffer didn't have a name already, or will
add a ".save" suffix to the current filename. If an emergency file with
that name already exists in the current directory, it will add ".save"
plus a number (e.g.\& ".save.1") to the current filename in order to make
it unique. In multibuffer mode, \fBnano\fP will write all the open
buffers to their respective emergency files.
In some cases \fBnano\fR tries to dump the buffer into an emergency file.
This happens mainly if \fBnano\fR receives a SIGHUP or SIGTERM or runs out
of memory. It writes the buffer into a file named \fInano.save\fR if the
buffer didn't have a name already, or adds a ".save" suffix to the current
filename. If an emergency file with that name already exists in the
current directory, it adds ".save" plus a number (e.g.\& ".save.1") to
the current filename in order to make it unique. In multibuffer mode,
\fBnano\fR writes all open buffers to their respective emergency files.
.sp
If you have any question about how to use \fBnano\fR in some specific
situation, you can ask on \fIhelp-nano@gnu.org\fR.
situation, you can ask on \fIhelp\-nano@gnu.org\fR.
.SH BUGS
The recording and playback of keyboard macros works correctly only on a
@ -428,7 +470,7 @@ Please report any other bugs that you encounter via:
.br
.IR https://savannah.gnu.org/bugs/?group=nano .
.sp
When nano crashes, it will save any modified buffers to emergency .save files.
When nano crashes, it saves any modified buffers to emergency .save files.
If you are able to reproduce the crash and you want to get a backtrace, define
the environment variable \fBNANO_NOCATCH\fR.
@ -438,4 +480,4 @@ the environment variable \fBNANO_NOCATCH\fR.
.SH SEE ALSO
.BR nanorc (5)
.sp
\fI/usr/share/doc/nano/\fP (or equivalent on your system)
\fI/usr/share/doc/nano/\fR (or equivalent on your system)

View File

@ -12,9 +12,9 @@ The complete manual for the GNU nano text editor.
@end documentdescription
@smallbook
@set EDITION 0.7
@set VERSION 7.2
@set UPDATED January 2023
@set EDITION 0.8
@set VERSION 8.4
@set UPDATED April 2025
@dircategory Editors
@direntry
@ -29,7 +29,7 @@ The complete manual for the GNU nano text editor.
@title GNU @command{nano}
@subtitle a small and friendly text editor
@subtitle version 7.2
@subtitle version 8.4
@author Chris Allegretta
@ -40,7 +40,7 @@ This manual documents the GNU @command{nano} text editor.
The contents of this manual are part of the GNU @command{nano} distribution.
@sp 5
Copyright @copyright{} 1999-2009, 2014-2023 Free Software Foundation, Inc.
Copyright @copyright{} 1999-2009, 2014-2025 Free Software Foundation, Inc.
@sp 1
This document is dual-licensed. You may distribute and/or modify it
under the terms of either of the following licenses:
@ -79,7 +79,7 @@ For suggesting improvements: @email{nano-devel@@gnu.org}
@node Top
@top
This manual documents GNU @command{nano}, version 7.2.
This manual documents GNU @command{nano}, version 8.4.
@menu
* Introduction::
@ -112,14 +112,22 @@ as is reasonable while offering a superset of Pico's functionality.
@xref{Pico Compatibility} for more details on how @command{nano} and
Pico differ.
Starting with version 4.0, @command{nano} no longer hard-wraps an overlong
line by default. It further uses linewise scrolling by default, and by
default includes the line below the title bar into the editing area.
If you want the old, Pico behavior back, you can use the
@blankline
Since version 4.0, @command{nano} no longer hard-wraps overlong
lines by default. It also by default uses linewise scrolling, and by
default includes the line below the title bar in the editing area.
In case you want the old, Pico behavior back, you can use the
following options: @option{--breaklonglines},
@option{--jumpyscrolling}, and @option{--emptyline}
(or @option{-bje}).
@blankline
Since version 8.0, @kbd{^F} starts a forward search, @kbd{^B} starts
a backward search, @kbd{M-F} searches the next occurrence forward,
and @kbd{M-B} searches the next occurrence backward. If you want
those keystrokes to do what they did before version 8.0, see the
rebindings in the sample nanorc file.
@blankline
Please report bugs via @url{https://savannah.gnu.org/bugs/?group=nano}.
@ -148,9 +156,6 @@ The cursor can be put on a specific line of a file by adding
the line number with a plus sign before the filename, and even
in a specific column by adding it with a comma.
Negative numbers count from the end of the file or line.
The line and column numbers may also be specified by gluing them with colons
after the filename. (When a filename contains a colon followed by digits,
escape the colon by preceding it with a triple backslash.)
The cursor can be put on the first or last occurrence of a specific string
by specifying that string after @code{+/} or @code{+?} before the filename.
@ -208,9 +213,9 @@ file has been modified since it was last saved or opened.
The status bar is the third line from the bottom of the screen. It
shows important and informational messages. Any error messages that
occur from using the editor will appear on the status bar. Any questions
that are asked of the user will be asked on the status bar, and any user
input (search strings, filenames, etc.) will be input on the status bar.
occur from using the editor appear on the status bar. Any questions
that are asked of the user are asked on the status bar, and any user
input (search strings, filenames, etc.) is input on the status bar.
The two help lines at the bottom of the screen show some of the most
essential functions of the editor.
@ -228,21 +233,21 @@ Characters not present on the keyboard can be entered in two ways:
@item
For characters with a single-byte code,
pressing the Esc key twice and then typing a three-digit decimal number
(from @kbd{000} to @kbd{255}) will make @command{nano} behave as if you
(from @kbd{000} to @kbd{255}) makes @command{nano} behave as if you
typed the key with that value.
@item
For any possible character, pressing @kbd{M-V} (Alt+V) and then typing a
series of hexadecimal digits (at most six, or concluded with @kbd{Enter} or
@kbd{Space}) will enter the corresponding Unicode character into the buffer.
@kbd{Space}) enters the corresponding Unicode character into the buffer.
@end itemize
For example, typing @kbd{Esc Esc 2 3 4} will enter the character "ê" ---
For example, typing @kbd{Esc Esc 2 3 4} enters the character "ê" ---
useful when writing about a French party. Typing @kbd{M-V 0 0 2 2 c 4}
will enter the symbol "⋄", a little diamond.
enters the symbol "⋄", a little diamond.
Typing @kbd{M-V} followed by anything other than a hexadecimal digit
will enter this keystroke verbatim into the buffer, allowing the user
enters this keystroke verbatim into the buffer, allowing the user
to insert literal control codes (except @code{^J}) or escape sequences.
@node Commands
@ -272,8 +277,8 @@ and then pressing the desired key.
Text can be cut from a file a whole line at a time with @kbd{^K}.
The cut line is stored in the cutbuffer. Consecutive strokes of @kbd{^K}
will add each cut line to this buffer, but a @kbd{^K}
after any other keystroke will overwrite the entire cutbuffer.
add each cut line to this buffer, but a @kbd{^K}
after any other keystroke overwrites the entire cutbuffer.
The contents of the cutbuffer can be pasted at the current cursor position
with @kbd{^U}.
@ -286,14 +291,14 @@ with @kbd{M-6}.
Text can be selected by first 'setting the Mark' with @kbd{^6}
or @kbd{M-A} and then moving the cursor to the other end of the portion
to be selected. The selected portion of text will be highlighted.
to be selected. The selected portion of text is highlighted.
This selection can now be cut or copied in its entirety with a single
@kbd{^K} or @kbd{M-6}. Or the selection can be used to limit the scope of
a search-and-replace (@kbd{^\}) or spell-checking session (@kbd{^T^T}).
On some terminals, text can be selected also by holding down @kbd{Shift}
while using the cursor keys. Holding down the @kbd{Ctrl} or @kbd{Alt}
key too will increase the stride. Such a selection is cancelled
key too increases the stride. Such a selection is cancelled
upon any cursor movement where @kbd{Shift} isn't held.
Cutting or copying selected text toggles off the mark automatically.
@ -302,15 +307,32 @@ If needed, it can be toggled off manually with another @kbd{^6} or @kbd{M-A}.
@node Search and Replace
@section Search and Replace
One can search the current buffer for the occurrence of any string
with the Search command (default key binding: @kbd{^W}). The default search
With the Search command (@kbd{^F} or @kbd{^W}) one can search the
current buffer for the occurrence of any string. The default search
mode is forward, case-insensitive, and for literal strings. But one
can search backwards by pressing @kbd{M-B}, search case sensitively with @kbd{M-C},
and interpret regular expressions in the search string with @kbd{M-R}.
can search backwards by toggling @kbd{M-B}, search case sensitively
with @kbd{M-C}, and interpret regular expressions in the search string
with @kbd{M-R}.
A regular expression in a search string always covers just one line;
it cannot span multiple lines. And when replacing (with @kbd{^\} or @kbd{M-R})
the replacement string cannot contain a newline (LF).
With the Replacement command (@kbd{M-R} or @kbd{^\}) one can replace
a given string (or regular expression) with another string.
When a regular expression contains fragments between parentheses,
the replacement string can refer back to these fragments via
@code{\1} to @code{\9}.
For each occurrence of the search string you are asked whether to
replace it. You can choose Yes (replace it), or No (skip this one),
or All (replace all remaining occurrences without asking any more),
or Cancel (stop with replacing, but replacements that have already
been made will not be undone).
If before a replacing session starts a region is marked, then
only occurrences of the search string within the marked region
will be replaced.
A regular expression always covers just one line --- it cannot span
multiple lines. And neither a search string nor a replacement string
can contain a newline (LF).
@node Using the Mouse
@section Using the Mouse
@ -322,7 +344,7 @@ executes the selected shortcut. To be able to select text with the
left button, or paste text with the middle button, hold down the
Shift key during those actions.
The mouse will work in the X Window System, and on the console when gpm
The mouse works in the X Window System, and on the console when gpm
is running.
@node Anchors
@ -362,7 +384,7 @@ and @kbd{^V} (Page Down) keys. @kbd{^X} exits from the help viewer.
@chapter The File Browser
When in the Read-File (@kbd{^R}) or Write-Out menu (@kbd{^O}),
pressing @kbd{^T} will invoke the file browser.
pressing @kbd{^T} invokes the file browser.
Here, one can navigate directories in a graphical manner in order to
find the desired file.
@ -371,8 +393,8 @@ other cursor-movement keys. More targeted movement is accomplished by
searching, via @kbd{^W} or @kbd{w}, or by changing directory, via
@kbd{^_} or @kbd{g}. The behavior of the @kbd{Enter} key (or @kbd{s})
varies by what is currently selected.
If the currently selected object is a directory, the file browser will
enter and display the contents of the directory. If the object is a
If the currently selected object is a directory, the file browser
enters and displays the contents of the directory. If the object is a
file, this filename and path are copied to the status bar, and the file
browser exits.
@ -380,17 +402,16 @@ browser exits.
@node Command-line Options
@chapter Command-line Options
@command{nano} takes the following options from the command line:
@command{nano} accepts the following options from the command line:
@table @option
@item -A
@itemx --smarthome
Make the Home key smarter. When Home is pressed anywhere but at the
very beginning of non-whitespace characters on a line, the cursor will
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.
very beginning of non-whitespace characters on a line, the cursor jumps
to that beginning (either forwards or backwards). If the cursor is
already at that position, it jumps to the true beginning of the line.
@item -B
@itemx --backup
@ -405,9 +426,11 @@ The uniquely numbered files are stored in the specified directory.
@item -D
@itemx --boldtext
For the interface, use bold instead of reverse video. This will be overridden
by setting the options @code{titlecolor}, @code{statuscolor}, @code{keycolor},
@code{functioncolor}, @code{numbercolor}, and/or @code{selectedcolor} in your
For the interface, use bold instead of reverse video.
This can be overridden for specific elements
by setting the options @code{titlecolor}, @code{statuscolor},
@code{promptcolor}, @code{minicolor}, @code{keycolor},
@code{numbercolor}, and/or @code{selectedcolor} in your
nanorc file. @xref{@code{set keycolor}} for details.
@item -E
@ -495,7 +518,6 @@ any name beginning with @code{r} (e.g.@: @command{rnano}).
Display over multiple screen rows lines that exceed the screen's width.
(You can make this soft-wrapping occur at whitespace instead of rudely at
the screen's edge, by using also @code{--atblanks}.)
(The old short option, @code{-$}, is deprecated.)
@item -T @var{number}
@itemx --tabsize=@var{number}
@ -548,7 +570,7 @@ the last one given takes effect.)
@item -c
@itemx --constantshow
Constantly display the cursor position (line number, column number,
Constantly report the cursor position (line number, column number,
and character number) on the status bar.
Note that this overrides option @option{-U} (@option{--quickblank}).
@ -600,16 +622,16 @@ Display line numbers to the left of the text area.
@item -m
@itemx --mouse
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 Window
System, and on the console when gpm is running. Text can still be
selected through dragging by holding down the Shift key.
clicks can be used to place the cursor, set the mark (with two clicks),
and execute shortcuts. The mouse works in the X Window System, and on
the console when gpm is running. Text can still be selected through
dragging by holding down the Shift key.
@item -n
@itemx --noread
Treat any name given on the command line as a new file. This allows
@command{nano} to write to named pipes: it will start with a blank buffer,
and will write to the pipe when the user saves the "file". This way
@command{nano} to write to named pipes: it starts with a blank buffer,
and writes to the pipe when the user saves the "file". This way
@command{nano} can be used as an editor in combination with for instance
@command{gpg} without having to write sensitive data to disk first.
@ -620,8 +642,9 @@ similar to a chroot.
@item -p
@itemx --preserve
Preserve the @kbd{^Q} (XON) and @kbd{^S} (XOFF) sequences so data being
sent to the editor can be stopped and started.
Preserve the @kbd{^S} (XOFF) and @kbd{^Q} (XON) sequences so that
data being sent to the terminal can be stopped and resumed.
Note that option @option{-/} (@option{--modernbindings}) overrides this.
@item -q
@itemx --indicator
@ -632,7 +655,7 @@ and how much of the buffer is covered by the viewport.
@item -r @var{number}
@itemx --fill=@var{number}
Set the target width for justifying and automatic hard-wrapping at this
@var{number} of columns. If the value is 0 or less, wrapping will occur
@var{number} of columns. If the value is 0 or less, wrapping occurs
at the width of the screen minus @var{number} columns, allowing the wrap
point to vary along with the width of the screen if the screen is resized.
The default value is @t{-8}.
@ -688,11 +711,26 @@ disabled to display the help-system navigation keys.
Make @kbd{Ctrl+Right} and @kbd{Ctrl+Delete} stop at word ends
instead of beginnings.
@item -z
@itemx --listsyntaxes
List the names of the available syntaxes and exit.
@item -!
@itemx --magic
When neither the file's name nor its first line give a clue,
try using libmagic to determine the applicable syntax.
@item -@@
@itemx --colonparsing
When a filename given on the command line ends in a colon plus digits
and this filename does not exist, then snip the colon plus digits and
understand the digits as a line number. If the trimmed filename does
not exist either, then repeat the process and understand the obtained
two numbers as line and column number. But if the doubly trimmed
filename does not exist either, then forget the trimming and accept
the original filename as is. To disable this colon parsing for some
file, use @code{+1} or similar before the relevant filename.
@item -%
@itemx --stateflags
Use the top-right corner of the screen for showing some state flags:
@ -706,7 +744,7 @@ filename in the center of the title bar.
@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 filename is shown
for the status bar. In this "mini bar" the filename 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),
@ -729,10 +767,23 @@ and disappears after 1.5 seconds or upon the next keystroke.
With @kbd{M-Z} the title bar plus status bar can be toggled.
With @kbd{M-X} the help lines.
@item -/
@itemx --modernbindings
Use key bindings similar to the ones that most modern programs use:
@kbd{^X} cuts, @kbd{^C} copies, @kbd{^V} pastes,
@kbd{^Z} undoes, @kbd{^Y} redoes,
@kbd{^F} searches forward, @kbd{^G} searches next,
@kbd{^S} saves, @kbd{^O} opens a file, @kbd{^Q} quits,
and (when the terminal permits) @kbd{^H} shows help.
Furthermore, @kbd{^A} sets the mark,
@kbd{^R} makes replacements, @kbd{^D} searches previous,
@kbd{^P} shows the position, @kbd{^T} goes to a line,
@kbd{^W} writes out a file, and @kbd{^E} executes a command.
Note that this overrides option @option{-p} (@option{--preserve}).
@end table
@sp 1
Option @code{-z} (@code{--suspendable}) has been removed.
Suspension is enabled by default, reachable via @kbd{^T^Z}.
(If you want a plain @kbd{^Z} to suspend nano, add
@code{bind ^Z suspend main} to your nanorc.)
@ -790,7 +841,7 @@ for more details). The following global toggles are available:
@item Hidden Interface
@kbd{M-Z} toggles the @option{-0} (@option{--zero}) command-line option,
but without the @option{-x} (@option{--nohelp}) part. That is: it toggles
just the title bar plus status bar (or the combined minibar plus status bar),
just the title bar plus status bar (or the combined mini bar plus status bar),
not the help lines. The latter are toggled with @kbd{M-X}.
@end table
@ -800,13 +851,13 @@ not the help lines. The latter are toggled with @kbd{M-X}.
@chapter Nanorc Files
Nanorc files can be used to configure @command{nano} to your liking
without using command-line options. During startup @command{nano} will
normally read two files: first the system-wide file, @file{/etc/nanorc}
without using command-line options. During startup @command{nano}
normally reads two files: first the system-wide file, @file{/etc/nanorc}
(the exact path may be different on your system), and then the user-specific
file, either @file{~/.nanorc} or @file{$XDG_CONFIG_HOME/nano/nanorc} or
@file{.config/nano/nanorc}, whichever exists first.
However, if @option{--rcfile} is given, @command{nano} will skip the
above files and will read just the specified settings file.
However, if @option{--rcfile} is given, @command{nano} skips the
above files and reads just the specified settings file.
A nanorc file can contain @command{set} and @command{unset} commands for
various options (@pxref{Settings}). It can also contain commands that
@ -866,10 +917,11 @@ with @code{set backup} or @option{--backup} or @option{-B}.
The uniquely numbered files are stored in the specified directory.
@item set boldtext
Use bold instead of reverse video for the title bar, status bar, key combos,
function tags, line numbers, and selected text. This is overridden by
setting the options @code{titlecolor}, @code{statuscolor}, @code{keycolor},
@code{functioncolor}, @code{numbercolor}, and/or @code{selectedcolor}.
Use bold instead of reverse video for the title bar, status bar,
prompt bar, mini bar, key combos, line numbers, and selected text.
This can be overridden by setting the options @code{titlecolor},
@code{statuscolor}, @code{promptcolor}, @code{minicolor},
@code{keycolor}, @code{numbercolor}, and/or @code{selectedcolor}.
@item set bookstyle
When justifying, treat any line that starts with whitespace as the
@ -888,8 +940,18 @@ Automatically hard-wrap the current line when it becomes overlong.
@item set casesensitive
Do case-sensitive searches by default.
@item set colonparsing
When a filename given on the command line ends in a colon plus digits
and this filename does not exist, then snip the colon plus digits and
understand the digits as a line number. If the trimmed filename does
not exist either, then repeat the process and understand the obtained
two numbers as line and column number. But if the doubly trimmed
filename does not exist either, then forget the trimming and accept
the original filename as is. To disable this colon parsing for some
file, use @code{+1} or similar before the relevant filename.
@item set constantshow
Constantly display the cursor position on the status bar.
Constantly report the cursor position on the status bar.
Note that this overrides @option{quickblank}.
@item set cutfromcursor
@ -905,7 +967,7 @@ The default value is @t{bold,white,red}.
@item set fill @var{number}
Set the target width for justifying and automatic hard-wrapping at this
@var{number} of columns. If the value is 0 or less, wrapping will occur
@var{number} of columns. If the value is 0 or less, wrapping occurs
at the width of the screen minus @var{number} columns, allowing the wrap
point to vary along with the width of the screen if the screen is resized.
The default value is @t{-8}.
@ -943,6 +1005,8 @@ 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 a Linux console, @code{light} does not have
any effect for a background color.
On terminal emulators that can do at least 256 colors,
other valid (but unprefixable) color names are:
@ -987,7 +1051,7 @@ The default value is "@t{(<[@{)>]@}}".
@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 filename is shown
for the status bar. In this "mini bar" the filename 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),
@ -1002,13 +1066,13 @@ The line plus column numbers and the character code are displayed only when
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.
Use this color combination for the mini bar.
(When this option is not specified, the colors of the title bar are used.)
@xref{@code{set keycolor}} for valid color names.
@item set mouse
Enable mouse support, so that mouse clicks can be used to place the
cursor, set the mark (with a double click), or execute shortcuts.
cursor, set the mark (with two clicks), or execute shortcuts.
@item set multibuffer
When reading in a file with @kbd{^R}, insert it into a new buffer by default.
@ -1032,7 +1096,7 @@ Use this color combination for line numbers.
@xref{@code{set keycolor}} for valid color names.
@item set operatingdir "@var{directory}"
@command{nano} will only read and write files inside "directory" and its
@command{nano} only reads and writes files inside "directory" and its
subdirectories. Also, the current directory is changed to here, so
files are inserted from this directory. By default, the operating
directory feature is turned off.
@ -1042,7 +1106,8 @@ Save the cursor position of files between editing sessions.
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}).
Preserve the XOFF and XON sequences (@kbd{^S} and @kbd{^Q}) so that
they are caught by the terminal (stopping and resuming the output).
@item set promptcolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
Use this color combination for the prompt bar.
@ -1092,8 +1157,6 @@ Save a changed buffer automatically on exit (@kbd{^X}); don't prompt.
@item set scrollercolor @var{fgcolor},@var{bgcolor}
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.)
@xref{@code{set keycolor}} for valid color names.
@item set selectedcolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
@ -1107,10 +1170,9 @@ poor vision.
@item set smarthome
Make the Home key smarter. When Home is pressed anywhere but at the
very beginning of non-whitespace characters on a line, the cursor will
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.
very beginning of non-whitespace characters on a line, the cursor jumps
to that beginning (either forwards or backwards). If the cursor is
already at that position, it jumps to the true beginning of the line.
@item set softwrap
Display lines that exceed the screen's width over multiple screen lines.
@ -1236,10 +1298,10 @@ via the following commands in a nanorc file:
@item syntax @var{name} ["@var{fileregex}" @dots{}]
Start the definition of a syntax with this @var{name}.
All subsequent @code{color} and other such commands
will be added to this syntax, until a new @code{syntax}
are added to this syntax, until a new @code{syntax}
command is encountered.
When @command{nano} is run, this syntax will be automatically
When @command{nano} is run, this syntax is automatically
activated (for the relevant buffer) if the absolute filename
matches the extended regular expression @var{fileregex}.
Or the syntax can be explicitly activated (for all buffers)
@ -1261,8 +1323,8 @@ If no @var{fileregex} matched and no @code{header} regex matched
either, then compare this @var{regex} (or regexes) against the
result of querying the @code{magic} database about the current
file, to determine whether this syntax should be used for it.
(This functionality only works when @code{libmagic} is installed
on the system and will be silently ignored otherwise.)
(This querying is done only when @code{libmagic} is actually installed
on the system and @option{--magic} or @code{set magic} was given.)
@item formatter @var{program} [@var{argument} @dots{}]
Run the given @var{program} on the full contents of the current buffer.
@ -1297,6 +1359,8 @@ 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 a Linux console, @code{light} does not have
any effect for a background color.
On terminal emulators that can do at least 256 colors,
other valid (but unprefixable) color names are:
@ -1328,7 +1392,7 @@ Paint all pieces of text whose start matches extended regular expression
"fromrx" and whose end matches extended regular expression "torx" with
the given foreground and background colors, at least one of
which must be specified. This means that, after an initial instance of
"fromrx", all text until the first instance of "torx" will be colored.
"fromrx", all text until the first instance of "torx" is colored.
This allows syntax highlighting to span multiple lines.
@item icolor [bold,][italic,]@var{fgcolor},@var{bgcolor} start="@var{fromrx}" end="@var{torx}"
@ -1365,7 +1429,7 @@ Rebinds @code{key} to @code{function} in the context of @code{menu}
Makes @code{key} produce @code{string} in the context of @code{menu}
(or in all menus where the key exists when @code{all} is used).
Besides literal text and/or control codes, the @code{string} may contain
function names between braces. These functions will be invoked when the
function names between braces. These functions are invoked when the
key is typed. To include a literal opening brace, use @code{@{@{@}}.
@item unbind key menu
@ -1376,13 +1440,14 @@ Unbinds @code{key} from @code{menu}
Note that @code{bind key "@{function@}" menu} is equivalent to
@code{bind key function menu}, except that for the latter form
@command{nano} will check the availability of the @code{function}
in the given @code{menu} at startup time (and report an error if
@command{nano} checks the availability of the @code{function}
in the given @code{menu} at startup time (and reports an error if
it does not exist there), whereas for the first form @command{nano}
will check at execution time that the @code{function} exists but not
checks at execution time that the @code{function} exists but not
whether it makes any sense in the current menu. The user has to take
care that a function name between braces (or any sequence of them)
is appropriate. Strange behavior can result when it is not.
is appropriate. Strange behavior or even a crash can result when
the braced name is unfitting.
@sp 1
The format of @code{key} should be one of:
@ -1524,7 +1589,7 @@ the contents of the buffer.)
@item linter
Invokes a syntax-checking program (if the active syntax defines one).
If this program produces lines of the form "filename:linenum:charnum:
some message", then the cursor will be put at the indicated position
some message", then the cursor is put at the indicated position
in the mentioned file while showing "some message" on the status bar.
You can move from message to message with @kbd{PgUp} and @kbd{PgDn},
and leave linting mode with @kbd{^C} or @kbd{Enter}.
@ -1578,7 +1643,11 @@ while keeping the cursor in the same text position, if possible.
(This function is bound by default to @kbd{Alt+Down}.)
@item center
Scrolls the line with the cursor to the middle of the screen.
Scrolls the line with the cursor to the middle of the viewport.
@item cycle
Scrolls the line with the cursor first to the middle of the viewport,
then to the top, then to the bottom.
@item prevword
Moves the cursor to the beginning of the previous word.
@ -1605,6 +1674,12 @@ Moves the cursor to the beginning of the current or preceding block of text.
@item nextblock
Moves the cursor to the beginning of the next block of text.
@item toprow
Moves the cursor to the first row in the viewport.
@item bottomrow
Moves the cursor to the last row in the viewport.
@item pageup
Goes up one screenful.
@ -1700,7 +1775,7 @@ Toggles between searching for something and replacing something.
Toggles between searching for text and targeting a line number.
@item flipexecute
Toggles between inserting a file and executing a command.
Switches from inserting a file to executing a command.
@item flippipe
When executing a command, toggles whether the current buffer (or marked
@ -1757,7 +1832,8 @@ and the linter. All further toggles are available in the main menu only.)
Toggles the presence of title bar and status bar.
@item constantshow
Toggles the constant display of the current line, column, and character positions.
Toggles the constant reporting (on the status bar)
of the current line, column, and character positions.
@item softwrap
Toggles the displaying of overlong lines on multiple screen lines.
@ -1780,15 +1856,14 @@ whitespace as the preceding line --- or as the next line if the preceding line
is the beginning of a paragraph.
@item cutfromcursor
Toggles whether cutting text will cut the whole line or just from the current cursor
Toggles whether cutting text cuts the whole line or just from the current cursor
position to the end of the line.
@item breaklonglines
Toggles whether long lines will be hard-wrapped to the next line.
(The old name of this function, 'nowrap', is deprecated.)
Toggles whether the overlong part of a line is hard-wrapped to the next line.
@item tabstospaces
Toggles whether typed tabs will be converted to spaces.
Toggles whether typed tabs are converted to spaces.
@item mouse
Toggles mouse support.
@ -1873,7 +1948,7 @@ whereas Pico does it at screen width minus six columns. You can make
@command{nano} do as Pico by using @option{--fill=-6}.
@item Scrolling
By default, @command{nano} will scroll just one line (instead of half
By default, @command{nano} scrolls just one line (instead of half
a screen) when the cursor is moved to a line that is just out of view.
And when paging up or down, @command{nano} keeps the cursor in the same
screen position as much as possible, instead of always placing it on the
@ -1889,8 +1964,8 @@ get it back with the @option{--emptyline} option.
@item Interactive Replace
Instead of allowing you to replace either just one occurrence of a search
string or all of them, @command{nano}'s replace function is interactive: it
will pause at each found search string and query whether to replace this
string or all of them, @command{nano}'s replace function is interactive:
it pauses at each found search string and asks whether to replace this
instance. You can then choose Yes, or No (skip this one), or All (don't
ask any more), or Cancel (stop with replacing).
@ -1915,8 +1990,8 @@ but also (between the two) the current column position.
@item Spell Checking
In the internal spell checker misspelled words are sorted alphabetically
and trimmed for uniqueness, such that the words 'apple' and 'Apple' will
be prompted for correction separately.
and trimmed for uniqueness, such that the strings 'Aplpe' and 'aplpe'
will be offered for correction separately.
@item Writing Selected Text to Files
When using the Write-Out key (@kbd{^O}), text that has been selected using the
@ -1928,8 +2003,8 @@ When using the Read-File key (@kbd{^R}), @command{nano} can not just read a file
it can also read the output of a command to be run (@kbd{^X}).
@item Reading from Working Directory
By default, Pico will read files from the user's home directory (when
using @kbd{^R}), but it will write files to the current working directory
By default, Pico reads files from the user's home directory (when
using @kbd{^R}), but it writes files to the current working directory
(when using @kbd{^O}). @command{nano} makes this symmetrical: always reading
from and writing to the current working directory --- the directory
that @command{nano} was started in.
@ -2064,7 +2139,7 @@ Include some code for runtime debugging output. This can get messy, so
chances are you only want this feature when you're working on the nano source.
@item --disable-nls
Exclude Native Language support. This will disable the use of any
Exclude Native Language support. This disables the use of any
available GNU @command{nano} translations.
@item --enable-utf8

View File

@ -1,4 +1,4 @@
.\" Copyright (C) 2003-2011, 2013-2023 Free Software Foundation, Inc.
.\" Copyright (C) 2003-2011, 2013-2025 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,32 +16,52 @@
.\" Documentation License along with this program. If not, see
.\" <https://www.gnu.org/licenses/>.
.\"
.TH NANORC 5 "version 7.2" "January 2023"
.TH NANORC 5 "version 8.4" "April 2025"
.SH NAME
nanorc \- GNU nano's configuration file
.SH DESCRIPTION
The \fInanorc\fP files contain the default settings for \fBnano\fP,
The \fInanorc\fR files contain the default settings for \fBnano\fR,
a small and friendly text editor. During startup, if \fB\-\-rcfile\fR
is not given, \fBnano\fR will read two files: first the
system-wide settings, from \fI/etc/nanorc\fP (the exact path might be
different on your system), and then the user-specific settings, either
from \fI~/.nanorc\fR or from \fI$XDG_CONFIG_HOME/nano/nanorc\fR
or from \fI~/.config/nano/nanorc\fR, whichever is encountered first.
If \fB\-\-rcfile\fR is given, \fBnano\fR will read just the specified
settings file.
is not given, \fBnano\fR reads two files: first the system-wide settings,
from \fI/etc/nanorc\fR (the exact path might be different on your system),
and then the user-specific settings, either from \fI~/.nanorc\fR or from
\fI$XDG_CONFIG_HOME/nano/nanorc\fR or from \fI~/.config/nano/nanorc\fR,
whichever is encountered first. If \fB\-\-rcfile\fR is given,
\fBnano\fR reads just the specified settings file.
.SH NOTICE
Since version 8.0, to be newcomer friendly, \fB^F\fR starts a forward search,
\fB^B\fR starts a backward search, \fBM\-F\fR searches the next occurrence
forward, and \fBM\-B\fR searches the next occurrence backward. If you want
those keystrokes to do what they did before version 8.0, add the following
lines at the end of your \fInanorc\fR file:
.sp
.RS 4
.B bind ^F forward main
.br
.B bind ^B back main
.br
.B bind M\-F formatter main
.br
.B bind M\-B linter main
.RE
.sp
.\" Never hyphenate these:
.hw ncurses terminfo
.SH OPTIONS
The configuration file accepts a series of \fBset\fP and \fBunset\fP
The configuration file accepts a series of \fBset\fR and \fBunset\fR
commands, which can be used to configure nano on startup without using
command-line options. Additionally, there are some commands to define
syntax highlighting and to rebind keys -- see the two separate sections
on those. \fBnano\fP reads one command per line.
syntax highlighting and to rebind keys \(em see the two separate sections
on those. \fBnano\fR reads one command per line.
All commands and keywords should be written in lowercase.
.sp
Options in \fInanorc\fP files take precedence over nano's defaults, and
command-line options override \fInanorc\fP settings. Also, options that
Options in \fInanorc\fR files take precedence over nano's defaults, and
command-line options override \fInanorc\fR settings. Also, options that
do not take an argument are unset by default. So using the \fBunset\fR
command is only needed when wanting to override a setting of the system's
\fInanorc\fR file in your own \fInanorc\fR. Options that take an
@ -70,29 +90,30 @@ and/or spaces as the previous line (or as the next line if the previous
line is the beginning of a paragraph).
.TP
.B set backup
When saving a file, create a backup file by adding a tilde (\fB~\fP) to
When saving a file, create a backup file by adding a tilde (\fB~\fR) to
the file's name.
.TP
.B set backupdir "\fIdirectory\fP"
.B set backupdir \fIdirectory\fR
Make and keep not just one backup file, but make and keep a uniquely
numbered one every time a file is saved -- when backups are enabled
numbered one every time a file is saved \(em when backups are enabled
with \fBset backup\fR or \fB\-\-backup\fR or \fB\-B\fR.
The uniquely numbered files are stored in the specified \fIdirectory\fR.
.TP
.B set boldtext
Use bold instead of reverse video for the title bar, status bar, key combos,
function tags, line numbers, and selected text. This can be overridden by
setting the options \fBtitlecolor\fP, \fBstatuscolor\fP, \fBkeycolor\fP,
\fBfunctioncolor\fP, \fBnumbercolor\fP, and \fBselectedcolor\fP.
Use bold instead of reverse video for the title bar, status bar,
prompt bar, mini bar, key combos, line numbers, and selected text.
This can be overridden by setting the options \fB\%titlecolor\fR,
\fB\%statuscolor\fR, \fB\%promptcolor\fR, \fB\%minicolor\fR,
\fB\%keycolor\fR, \fB\%numbercolor\fR, and/or \fB\%selectedcolor\fR.
.TP
.B set bookstyle
When justifying, treat any line that starts with whitespace as the
beginning of a paragraph (unless auto-indenting is on).
.TP
.BI "set brackets """ characters """
.BI "set brackets """ characters """"
Set the characters treated as closing brackets when justifying
paragraphs. This may not include blank characters. Only closing
punctuation (see \fBset punct\fP), optionally followed by the specified
punctuation (see \fBset punct\fR), optionally followed by the specified
closing brackets, can end sentences. The default value is "\fB\(dq')>]}\fR".
.TP
.B set breaklonglines
@ -101,8 +122,18 @@ Automatically hard-wrap the current line when it becomes overlong.
.B set casesensitive
Do case-sensitive searches by default.
.TP
.B set colonparsing
When a filename given on the command line ends in a colon plus digits
and this filename does not exist, then snip the colon plus digits and
understand the digits as a line number. If the trimmed filename does
not exist either, then repeat the process and understand the obtained
two numbers as line and column number. But if the doubly trimmed
filename does not exist either, then forget the trimming and accept
the original filename as is. To disable this colon parsing for some
file, use \fB+1\fR or similar before the relevant filename.
.TP
.B set constantshow
Constantly display the cursor position in the status bar.
Constantly report the cursor position on the status bar.
This overrides the option \fBquickblank\fR.
.TP
.B set cutfromcursor
@ -114,11 +145,11 @@ Do not use the line below the title bar, leaving it entirely blank.
.B set errorcolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Use this color combination for the status bar when an error message is displayed.
The default value is \fBbold,white,red\fR.
See \fBset titlecolor\fR for valid color names.
See \fBset \%titlecolor\fR for valid color names.
.TP
.B set fill \fInumber\fR
Set the target width for justifying and automatic hard-wrapping at this
\fInumber\fR of columns. If the value is 0 or less, wrapping will occur
\fInumber\fR of columns. If the value is 0 or less, wrapping occurs
at the width of the screen minus \fInumber\fR columns, allowing the wrap
point to vary along with the width of the screen if the screen is resized.
The default value is \fB\-8\fR.
@ -126,7 +157,7 @@ The default value is \fB\-8\fR.
.B set functioncolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
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.
See \fBset \%titlecolor\fR for more details.
.TP
.B set guidestripe \fInumber
Draw a vertical stripe at the given column, to help judge the width of the
@ -147,7 +178,7 @@ Scroll the buffer contents per half-screen instead of per line.
.B set keycolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
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.
See \fBset \%titlecolor\fR for more details.
.TP
.B set linenumbers
Display line numbers to the left of the text area.
@ -162,16 +193,16 @@ try using libmagic to determine the applicable syntax.
(Calling libmagic can be relatively time consuming.
It is therefore not done by default.)
.TP
.BI "set matchbrackets """ characters """
.BI "set matchbrackets """ characters """"
Specify the opening and closing brackets that can be found by bracket
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".
The default value is "\fB(<[{)>]}\fR".
.TP
.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 filename is shown
for the status bar. In this "mini bar" the filename 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),
@ -186,14 +217,14 @@ The line plus column numbers and the character code are displayed only when
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.
Use this color combination for the mini bar.
(When this option is not specified, the colors of the title bar are used.)
See \fBset titlecolor\fR for more details.
See \fBset \%titlecolor\fR for more details.
.TP
.B set mouse
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 Window
Enable mouse support, if available for your system. When enabled,
mouse clicks can be used to place the cursor, set the mark (with two
clicks), and execute shortcuts. The mouse works in the X Window
System, and on the console when gpm is running. Text can still be
selected through dragging by holding down the Shift key.
.TP
@ -216,10 +247,10 @@ When needed, use \fBunset breaklonglines\fR instead.
.TP
.B set numbercolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Use this color combination for line numbers.
See \fBset titlecolor\fR for more details.
See \fBset \%titlecolor\fR for more details.
.TP
.B set operatingdir "\fIdirectory\fP"
\fBnano\fP will only read and write files inside \fIdirectory\fP and its
.B set operatingdir \fIdirectory\fR
\fBnano\fR only reads and writes files inside \fIdirectory\fR and its
subdirectories. Also, the current directory is changed to here, so
files are inserted from this directory. By default, the operating
directory feature is turned off.
@ -229,18 +260,19 @@ Save the cursor position of files between editing sessions.
The cursor position is remembered for the 200 most-recently edited files.
.TP
.B set preserve
Preserve the XON and XOFF keys (\fB^Q\fR and \fB^S\fR).
Preserve the XOFF and XON sequences (\fB^S\fR and \fB^Q\fR) so that
they are caught by the terminal (stopping and resuming the output).
.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.
See \fBset \%titlecolor\fR for more details.
.TP
.BI "set punct """ characters """
.BI "set punct """ characters """"
Set the characters treated as closing punctuation when justifying
paragraphs. This may not include blank characters. Only the
specfified closing punctuation, optionally followed by closing brackets
(see \fBbrackets\fP), can end sentences. The default value is "\fB!.?\fP".
specified closing punctuation, optionally followed by closing brackets
(see \fBset brackets\fR), can end sentences. The default value is "\fB!.?\fR".
.TP
.B set quickblank
Make status-bar messages disappear after 1 keystroke instead of after 20.
@ -249,17 +281,17 @@ When option \fBminibar\fR or \fBzero\fR is in effect,
\fBquickblank\fR makes a message disappear after
0.8 seconds instead of after the default 1.5 seconds.
.TP
.BI "set quotestr """ regex """
.BI "set quotestr """ regex """"
Set the regular expression for matching the quoting part of a line.
The default value is "\fB^([\ \\t]*([!#%:;>|}]|//))+\fP".
(Note that \fB\\t\fR stands for an actual Tab character.)
The default value is "\fB^([\ \et]*([!#%:;>|}]|//))+\fR".
(Note that \fB\et\fR stands for an actual Tab character.)
This makes it possible to rejustify blocks of quoted text when composing
email, and to rewrap blocks of line comments when writing source code.
.TP
.B set rawsequences
Interpret escape sequences directly, instead of asking \fBncurses\fR
to translate them. (If you need this option to get some keys to work
properly, it means that the terminfo terminal description that is used
properly, it means that the \fBterminfo\fR terminal description that is used
does not fully match the actual behavior of your terminal. This can
happen when you ssh into a BSD machine, for example.)
Using this option disables \fBnano\fR's mouse support.
@ -278,13 +310,11 @@ Save a changed buffer automatically on exit (\fB^X\fR); don't prompt.
.TP
.B set scrollercolor \fIfgcolor\fB,\fIbgcolor\fR
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.
See \fBset \%titlecolor\fR for more details.
.TP
.B set selectedcolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Use this color combination for selected text.
See \fBset titlecolor\fR for more details.
See \fBset \%titlecolor\fR for more details.
.TP
.B set showcursor
Put the cursor on the highlighted item in the file browser, and show
@ -293,10 +323,9 @@ poor vision.
.TP
.B set smarthome
Make the Home key smarter. When Home is pressed anywhere but at the
very beginning of non-whitespace characters on a line, the cursor will
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.
very beginning of non-whitespace characters on a line, the cursor jumps
to that beginning (either forwards or backwards). If the cursor is
already at that position, it jumps to the true beginning of the line.
.TP
.B set softwrap
Display lines that exceed the screen's width over multiple screen lines.
@ -309,8 +338,8 @@ 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.
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:
@ -322,45 +351,46 @@ filename in the center of the title bar.
.TP
.B set statuscolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Use this color combination for the status bar.
See \fBset titlecolor\fR for more details.
See \fBset \%titlecolor\fR for more details.
.TP
.B set stripecolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
Use this color combination for the vertical guiding stripe.
See \fBset titlecolor\fR for more details.
See \fBset \%titlecolor\fR for more details.
.TP
.B set tabsize \fInumber\fR
Use a tab size of \fInumber\fR columns. The value of \fInumber\fP must be
Use a tab size of \fInumber\fR columns. The value of \fInumber\fR must be
greater than 0. The default value is \fB8\fR.
.TP
.B set tabstospaces
Convert each typed tab to spaces -- to the number of spaces
Convert each typed tab to spaces \(em to the number of spaces
that a tab at that position would take up.
(Note: pasted tabs are not converted.)
.TP
.B set titlecolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
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 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.
as a synonym for \fB\%lightblack\fR.
On a Linux console, \fBlight\fR does not have
any effect for a background color.
On terminal emulators that can do at least 256 colors,
other valid (but unprefixable) color names are:
.BR pink ", " purple ", " mauve ", " lagoon ", " mint ", "
.BR lime ", " peach ", " orange ", " latte ", "
.BR rosy ", " beet ", " plum ", " sea ", " sky ", " slate ", "
.BR teal ", " sage ", " brown ", " ocher ", " sand ", " tawny ", "
.BR brick ", " crimson ", and " normal
-- where \fBnormal\fR means the default foreground or background color.
.BR pink ", " \%purple ", " mauve ", " \%lagoon ", " mint ", " lime ", " peach ,
.BR \%orange ", " \%latte ", " \%rosy ", " beet ", " plum ", " sea ", " sky ,
.BR slate ", " teal ", " sage ", " brown ", " \%ocher ", " sand ", " \%tawny ,
.BR brick ", " \%crimson ", and " \%normal
\(em where \fB\%normal\fR means the default foreground or background color.
On such emulators, the color may also be specified as a three-digit hexadecimal
number prefixed with \fB#\fR, with the digits representing the amounts of red,
green, and blue, respectively. This tells \fBnano\fR to select from the
available palette the color that approximates the given values.
Either "\fIfgcolor\fR" or "\fB,\fIbgcolor\fR" may be left out,
and the pair may be preceded by \fBbold\fR and/or \fBitalic\fR
and the pair may be preceded by \fBbold\fR and/or \fB\%italic\fR
(separated by commas) to get a bold and/or slanting typeface,
if your terminal can do those.
.TP
@ -373,7 +403,7 @@ 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
.BI "set whitespace """ characters """
.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
for a UTF-8 locale is "\fB\[Fc]\[md]\fR", and for other locales "\fB>.\fR".
@ -382,7 +412,7 @@ for a UTF-8 locale is "\fB\[Fc]\[md]\fR", and for other locales "\fB>.\fR".
Detect word boundaries differently by treating punctuation
characters as parts of words.
.TP
.BI "set wordchars """ characters """
.BI "set wordchars """ characters """"
Specify which other characters (besides the normal alphanumeric ones)
should be considered as parts of words. When using this option, you
probably want to unset \fBwordbounds\fR.
@ -415,8 +445,8 @@ The period \fB.\fR matches any single character,
\fB*\fR means the preceding item may be matched zero or more times,
\fB+\fR means the preceding item must be matched one or more times,
\fB^\fR matches the beginning of a line, and \fB$\fR the end,
\fB\\<\fR matches the start of a word, and \fB\\>\fR the end,
and \fB\\s\fR matches a blank.
\fB\e<\fR matches the start of a word, and \fB\e>\fR the end,
and \fB\es\fR matches a blank.
It also means that lookahead and lookbehind are not possible.
A complete explanation can be found in the manual page of GNU grep:
\fBman grep\fR.
@ -435,33 +465,33 @@ via the following commands:
.BI syntax " name \fR[" """" fileregex """ " \fR...]
Start the definition of a syntax with this \fIname\fR.
All subsequent \fBcolor\fR and other such commands
will be added to this syntax, until a new \fBsyntax\fR
are added to this syntax, until a new \fBsyntax\fR
command is encountered.
.sp
When \fBnano\fR is run, this syntax will be automatically
When \fBnano\fR is run, this syntax is automatically
activated (for the relevant buffer) if the absolute filename
matches the extended regular expression \fIfileregex\fR.
Or the syntax can be explicitly activated (for all buffers)
by using the \fB\-Y\fR or \fB\-\-syntax\fR
command-line option followed by the \fIname\fR.
.sp
The syntax \fBdefault\fP is special: it takes no \fIfileregex\fR,
The syntax \fBdefault\fR is special: it takes no \fIfileregex\fR,
and applies to files that don't match any syntax's regexes.
The syntax \fBnone\fP is reserved; specifying it on the command line
The syntax \fBnone\fR is reserved; specifying it on the command line
is the same as not having a syntax at all.
.TP
.BI "header """ regex """ \fR...
.BI "header """ regex """ " \fR...
If from all defined syntaxes no \fIfileregex\fR matched, then compare
this \fIregex\fR (or regexes) against the first line of the current file,
to determine whether this syntax should be used for it.
.TP
.BI "magic """ regex """ \fR...
.BI "magic """ regex """ " \fR...
If no \fIfileregex\fR matched and no \fBheader\fR regex matched
either, then compare this \fIregex\fR (or regexes) against the
result of querying the \fBmagic\fP database about the current
result of querying the \fBmagic\fR database about the current
file, to determine whether this syntax should be used for it.
(This functionality only works when \fBlibmagic\fP is installed on the
system and will be silently ignored otherwise.)
(This querying is done only when \fBlibmagic\fR is actually installed
on the system and \fB\-\-magic\fR or \fBset magic\fR was given.)
.TP
.BI formatter " program " \fR[ "argument " \fR...]
Run the given \fIprogram\fR on the full contents of the current buffer.
@ -469,7 +499,7 @@ Run the given \fIprogram\fR on the full contents of the current buffer.
.BI linter " program " \fR[ "argument " \fR...]
Use the given \fIprogram\fR to run a syntax check on the current buffer.
.TP
.BI "comment """ string """
.BI "comment """ string """"
Use the given \fIstring\fR for commenting and uncommenting lines.
If the string contains a vertical bar or pipe character (\fB|\fR),
this designates bracket-style comments; for example, "\fB/*|*/\fR" for
@ -478,37 +508,38 @@ characters after the pipe are appended at the end of the line. If no pipe
character is present, the full string is prepended; for example, "\fB#\fR"
for Python files. If empty double quotes are specified, the comment/uncomment
function is disabled; for example, "" for JSON.
The default value is "\fB#\fP".
The default value is "\fB#\fR".
.TP
.BI "tabgives """ string """
.BI "tabgives """ string """"
Make the <Tab> key produce the given \fIstring\fR. Useful for languages like
Python that want to see only spaces for indentation.
This overrides the setting of the \fBtabstospaces\fR option.
.TP
.BI "color \fR[\fBbold,\fR][\fBitalic,\fR]" fgcolor , bgcolor " """ regex """ " \fR...
Paint all pieces of text that match the extended regular expression
\fIregex\fP with the given foreground and background colors, at least
\fIregex\fR with the given foreground and background colors, at least
one of which must be specified. Valid color names are:
.BR red ", " green ", " blue ", " magenta ", " yellow ", " cyan ", "
.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.
as a synonym for \fB\%lightblack\fR.
On a Linux console, \fBlight\fR does not have
any effect for a background color.
On terminal emulators that can do at least 256 colors,
other valid (but unprefixable) color names are:
.BR pink ", " purple ", " mauve ", " lagoon ", " mint ", "
.BR lime ", " peach ", " orange ", " latte ", "
.BR rosy ", " beet ", " plum ", " sea ", " sky ", " slate ", "
.BR teal ", " sage ", " brown ", " ocher ", " sand ", " tawny ", "
.BR brick ", " crimson ", and " normal
-- where \fBnormal\fR means the default foreground or background color.
.BR pink ", " \%purple ", " mauve ", " \%lagoon ", " mint ", " lime ", " peach ,
.BR \%orange ", " \%latte ", " \%rosy ", " beet ", " plum ", " sea ", " sky ,
.BR slate ", " teal ", " sage ", " brown ", " \%ocher ", " sand ", " \%tawny ,
.BR brick ", " \%crimson ", and " \%normal
\(em where \fB\%normal\fR means the default foreground or background color.
On such emulators, the color may also be specified as a three-digit hexadecimal
number prefixed with \fB#\fR, with the digits representing the amounts of red,
green, and blue, respectively. This tells \fBnano\fR to select from the
available palette the color that approximates the given values.
The color pair may be preceded by \fBbold\fR and/or \fBitalic\fR
The color pair may be preceded by \fBbold\fR and/or \fB\%italic\fR
(separated by commas) to get a bold and/or slanting typeface,
if your terminal can do those.
.sp
@ -518,29 +549,29 @@ which means that later commands can recolor stuff that was colored earlier.
.BI "icolor \fR[\fBbold,\fR][\fBitalic,\fR]" fgcolor , bgcolor " """ regex """ " \fR...
Same as above, except that the matching is case insensitive.
.TP
.BI "color \fR[\fBbold,\fR][\fBitalic,\fR]" fgcolor , bgcolor " start=""" fromrx """ end=""" torx """
.BI "color \fR[\fBbold,\fR][\fBitalic,\fR]" fgcolor , bgcolor " start=""" fromrx """ end=""" torx """"
Paint all pieces of text whose start matches extended regular expression
\fIfromrx\fP and whose end matches extended regular expression \fItorx\fP
\fIfromrx\fR and whose end matches extended regular expression \fItorx\fR
with the given foreground and background colors,
at least one of which must be specified. This means that, after an
initial instance of \fIfromrx\fP, all text until the first instance of
\fItorx\fP will be colored. This allows syntax highlighting to span
initial instance of \fIfromrx\fR, all text until the first instance of
\fItorx\fR is colored. This allows syntax highlighting to span
multiple lines.
.TP
.BI "icolor \fR[\fBbold,\fR][\fBitalic,\fR]" fgcolor , bgcolor " start=""" fromrx """ end=""" torx """
.BI "icolor \fR[\fBbold,\fR][\fBitalic,\fR]" fgcolor , bgcolor " start=""" fromrx """ end=""" torx """"
Same as above, except that the matching is case insensitive.
.TP
.BI "include """ syntaxfile """
Read in self-contained color syntaxes from \fIsyntaxfile\fP. Note that
\fIsyntaxfile\fP may contain only the above commands, from \fBsyntax\fP
to \fBicolor\fP.
.BI "include """ syntaxfile """"
Read in self-contained color syntaxes from \fIsyntaxfile\fR. Note that
\fIsyntaxfile\fR may contain only the above commands, from \fBsyntax\fR
to \fBicolor\fR.
.TP
.BI extendsyntax " name command argument " \fR...
Extend the syntax previously defined as \fIname\fR with another
\fIcommand\fR. This allows adding a new \fBcolor\fP, \fBicolor\fP,
\fBheader\fR, \fBmagic\fR, \fBformatter\fR, \fBlinter\fR, \fBcomment\fR,
or \fBtabgives\fR
command to an already defined syntax -- useful when you want to
\fI\%command\fR. This allows adding a new \fB\%color\fR, \fB\%icolor\fR,
\fB\%header\fR, \fB\%magic\fR, \fB\%formatter\fR, \fB\%linter\fR,
\fB\%comment\fR, or \fB\%tabgives\fR
command to an already defined syntax \(em useful when you want to
slightly improve a syntax defined in one of the system-installed
files (which normally are not writable).
@ -549,37 +580,37 @@ Key bindings can be changed via the following three commands:
.RS 3
.TP
.BI bind " key function menu"
Rebinds the given \fIkey\fP to the given \fIfunction\fP in the given \fImenu\fP
(or in all menus where the function exists when \fBall\fP is used).
Rebinds the given \fIkey\fR to the given \fIfunction\fR in the given \fImenu\fR
(or in all menus where the function exists when \fBall\fR is used).
.TP
.BI bind " key " """" string """" " menu"
Makes the given \fIkey\fR produce the given \fIstring\fR in the given
\fImenu\fR (or in all menus where the key exists when \fBall\fR is used).
Besides literal text and/or control codes, the \fIstring\fR may contain
function names between braces. These functions will be invoked when
function names between braces. These functions are invoked when
the key is typed. To include a literal opening brace, use \fB{{}\fR.
.TP
.BI unbind " key menu"
Unbinds the given \fIkey\fP from the given \fImenu\fP (or from all
menus where the key exists when \fBall\fP is used).
Unbinds the given \fIkey\fR from the given \fImenu\fR (or from all
menus where the key exists when \fBall\fR is used).
.RE
.sp
Note that \fBbind \fIkey\fR \fB"{\fIfunction\fB}"\fR \fImenu\fR is equivalent
to \fBbind \fIkey\fR \fIfunction\fR \fImenu\fR, except that for the latter form
\fBnano\fR will check the availability of the \fIfunction\fR in the given \fImenu\fR
at startup time (and report an error if it does not exist there), whereas for the
first form \fBnano\fR will check at execution time that the \fIfunction\fR exists
\fBnano\fR checks the availability of the \fIfunction\fR in the given \fImenu\fR
at startup time (and reports an error if it does not exist there), whereas for the
first form \fBnano\fR checks at execution time that the \fIfunction\fR exists
but not whether it makes any sense in the current menu. The user has to take care
that a function name between braces (or any sequence of them) is appropriate.
Strange behavior can result when it is not.
Strange behavior or even a crash can result when the braced name is unfitting.
.TP
The format of \fIkey\fP should be one of:
The format of \fIkey\fR should be one of:
.RS 3
.TP 7
.BI ^ X
where \fIX\fR is a Latin letter, or one of several ASCII characters
(@, ], \\, ^, _), or the word "Space".
(@, ], \e, ^, _), or the word "Space".
Example: ^C.
.TP
.BI M\- X
@ -604,13 +635,13 @@ Example: F10.
Rebinding \fB^M\fR (Enter) or \fB^I\fR (Tab) is probably not a good idea.
Rebinding \fB^[\fR (Esc) is not possible, because its keycode
is the starter byte of Meta keystrokes and escape sequences.
Rebinding any of the dedicated cursor-moving keys (the arrows, Home, End,
PageUp and PageDown) is not possible.
Rebinding any of the dedicated cursor-moving keys (the arrows,
Home, End, PageUp and PageDown) is not possible.
On some terminals it's not possible to rebind \fB^H\fR (unless \fB\-\-raw\fR
is used) because its keycode is identical to that of the Backspace key.
.TP
Valid \fIfunction\fP names to be bound are:
Valid \fIfunction\fR names to be bound are:
.RS 3
.TP 2
.B help
@ -633,11 +664,11 @@ Inserts a file into the current buffer (at the current cursor position),
or into a new buffer when option \fBmultibuffer\fR is set.
.TP
.B whereis
Starts a forward search for text in the current buffer -- or for filenames
Starts a forward search for text in the current buffer \(em or for filenames
matching a string in the current list in the file browser.
.TP
.B wherewas
Starts a backward search for text in the current buffer -- or for filenames
Starts a backward search for text in the current buffer \(em or for filenames
matching a string in the current list in the file browser.
.TP
.B findprevious
@ -689,7 +720,7 @@ Counts and reports on the status bar the number of lines, words,
and characters in the current buffer (or in the marked region).
.TP
.B execute
Prompts for a program to execute. The program's output will be inserted
Prompts for a program to execute. The program's output is inserted
into the current buffer (or into a new buffer when \fBM\-F\fR is toggled).
.TP
.B speller
@ -705,7 +736,7 @@ the contents of the buffer.)
.B linter
Invokes a syntax-checking program (if the active syntax defines one).
If this program produces lines of the form "filename:linenum:charnum:
some message", then the cursor will be put at the indicated position
some message", then the cursor is put at the indicated position
in the mentioned file while showing "some message" on the status bar.
You can move from message to message with <PgUp> and <PgDn>,
and leave linting mode with \fB^C\fR or <Enter>.
@ -760,7 +791,11 @@ while keeping the cursor in the same text position, if possible.
(This function is bound by default to <Alt+Down>.)
.TP
.B center
Scrolls the line with the cursor to the middle of the screen.
Scrolls the line with the cursor to the middle of the viewport.
.TP
.B cycle
Scrolls the line with the cursor first to the middle of the viewport,
then to the top, then to the bottom.
.TP
.B prevword
Moves the cursor to the beginning of the previous word.
@ -787,6 +822,12 @@ Moves the cursor to the beginning of the current or preceding block of text.
.B nextblock
Moves the cursor to the beginning of the next block of text.
.TP
.B toprow
Moves the cursor to the first row in the viewport.
.TP
.B bottomrow
Moves the cursor to the last row in the viewport.
.TP
.B pageup
Goes up one screenful.
.TP
@ -804,7 +845,7 @@ Goes to a specific line (and column if specified). Negative numbers count
from the end of the file (and end of the line).
.TP
.B findbracket
Moves the cursor to the bracket (or brace or parenthesis, etc.) that matches
Moves the cursor to the bracket (or brace or parenthesis, etc.\&) that matches
(pairs) with the one under the cursor. See \fBset matchbrackets\fR.
.TP
.B anchor
@ -840,7 +881,7 @@ Deletes the character under the cursor.
Deletes the character before the cursor.
.TP
.B recordmacro
Starts the recording of keystrokes -- the keystrokes are stored
Starts the recording of keystrokes \(em the keystrokes are stored
as a macro. When already recording, the recording is stopped.
.TP
.B runmacro
@ -882,7 +923,7 @@ Toggles between searching for something and replacing something.
Toggles between searching for text and targeting a line number.
.TP
.B flipexecute
Toggles between inserting a file and executing a command.
Switches from inserting a file to executing a command.
.TP
.B flippipe
When executing a command, toggles whether the current buffer (or marked
@ -906,7 +947,7 @@ When writing a file, switches to writing a Mac format.
When writing a file, appends to the end instead of overwriting.
.TP
.B prepend
When writing a file, 'prepends' (writes at the beginning) instead of overwriting.
When writing a file, "prepends" (writes at the beginning) instead of overwriting.
.TP
.B backup
When writing a file, creates a backup of the current file.
@ -939,7 +980,8 @@ and the linter. All further toggles are available in the main menu only.)
Toggles the presence of title bar and status bar.
.TP
.B constantshow
Toggles the constant display of the current line, column, and character positions.
Toggles the constant reporting (on the status bar)
of the current line, column, and character positions.
.TP
.B softwrap
Toggles the displaying of overlong lines on multiple screen lines.
@ -958,26 +1000,25 @@ Toggles the smartness of the Home key.
.TP
.B autoindent
Toggles whether a newly created line will contain the same amount of leading
whitespace as the preceding line -- or as the next line if the preceding line
whitespace as the preceding line \(em or as the next line if the preceding line
is the beginning of a paragraph.
.TP
.B cutfromcursor
Toggles whether cutting text will cut the whole line or just from the current cursor
Toggles whether cutting text cuts the whole line or just from the current cursor
position to the end of the line.
.TP
.B breaklonglines
Toggles whether long lines will be hard-wrapped to the next line.
(The old name of this function, 'nowrap', is deprecated.)
Toggles whether the overlong part of a line is hard-wrapped to the next line.
.TP
.B tabstospaces
Toggles whether typed tabs will be converted to spaces.
Toggles whether typed tabs are converted to spaces.
.TP
.B mouse
Toggles mouse support.
.RE
.TP
Valid \fImenu\fP sections are:
Valid \fImenu\fR sections are:
.RS 3
.TP 2
.B main
@ -990,32 +1031,32 @@ The help-viewer menu.
The search menu (AKA whereis).
.TP
.B replace
The 'search to replace' menu.
The \&'search to replace' menu.
.TP
.B replacewith
The 'replace with' menu, which comes up after 'search to replace'.
The \&'replace with' menu, which comes up after \&'search to replace'.
.TP
.B yesno
The 'yesno' menu, where the Yes/No/All/Cancel question is asked.
The \&'yesno' menu, where the Yes/No/All/Cancel question is asked.
.TP
.B gotoline
The 'goto line (and column)' menu.
The \&'goto line (and column)' menu.
.TP
.B writeout
The 'write file' menu.
The \&'write file' menu.
.TP
.B insert
The 'insert file' menu.
The \&'insert file' menu.
.TP
.B browser
The 'file browser' menu, for selecting a file to be opened or
The \&'file browser' menu, for selecting a file to be opened or
inserted or written to.
.TP
.B whereisfile
The 'search for a file' menu in the file browser.
The \&'search for a file' menu in the file browser.
.TP
.B gotodir
The 'go to directory' menu in the file browser.
The \&'go to directory' menu in the file browser.
.TP
.B execute
The menu for inserting the output from an external command,
@ -1044,7 +1085,7 @@ To make \fBCtrl+Z\fR suspend nano:
To make \fBShift+Alt+C\fR copy the marked region to the system's clipboard:
.sp
.RS
.B bind Sh-M-C """{execute}| xsel -ib {enter}{undo}""" main
.B bind Sh\-M\-C """{execute}| xsel \-ib {enter}{undo}""" main
.RE
.sp
@ -1063,5 +1104,5 @@ Syntax definitions for the syntax coloring of common file types
.SH SEE ALSO
.BR nano (1)
.TP
.I https://nano-editor.org/cheatsheet.html
.I https://nano\-editor.org/cheatsheet.html
An overview of the default key bindings.

View File

@ -1,4 +1,4 @@
.\" Copyright (C) 2002-2007, 2014-2023 Free Software Foundation, Inc.
.\" Copyright (C) 2002-2007, 2014-2025 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 7.2" "January 2023"
.TH RNANO 1 "version 8.4" "April 2025"
.SH NAME
rnano \- a restricted nano

View File

@ -8,6 +8,12 @@
## Inside string parameters, quotes should not be escaped -- the last
## double quote on the line will be seen as the closing quote.
## If you want ^F, ^B, M-F and M-B to do what they did before version 8.0:
# bind ^F forward main
# bind ^B back main
# bind M-F formatter main
# bind M-B linter main
## Make 'nextword' (Ctrl+Right) and 'chopwordright' (Ctrl+Delete)
## stop at word ends instead of at beginnings.
# set afterends
@ -44,7 +50,11 @@
## Do case-sensitive searches by default.
# set casesensitive
## Constantly display the cursor position in the status bar or minibar.
## Interpret digits given on the command line after a colon after a filename
## as the line number to go to in that file.
# set colonparsing
## Constantly report the cursor position, in the status bar or minibar.
# set constantshow
## Use cut-from-cursor-to-end-of-line by default.
@ -92,8 +102,8 @@
# 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
## mouse clicks can be used to place the cursor, set the mark (with
## two clicks), and execute shortcuts. The mouse will work in the
## X Window System, and on the console when gpm is running.
# set mouse
@ -123,7 +133,7 @@
# set preserve
## The characters treated as closing punctuation when justifying paragraphs.
## This may not contain blank characters. Only these closing punctuations,
## This may not contain blank characters. Only these terminating characters,
## optionally followed by closing brackets, can end sentences.
# set punct "!.?"
@ -214,9 +224,9 @@
# set statuscolor bold,white,green
# set errorcolor bold,white,red
# set spotlightcolor black,lightyellow
# set selectedcolor lightwhite,magenta
# set stripecolor ,yellow
# set scrollercolor cyan
# set selectedcolor lightwhite,#804
# set stripecolor ,#444
# set scrollercolor slate,#222
# set numbercolor cyan
# set keycolor cyan
# set functioncolor green
@ -239,12 +249,12 @@
## For all details, see 'man nanorc', section SYNTAX HIGHLIGHTING.
## To include most of the existing syntax definitions, you can do:
# include "@PKGDATADIR@/*.nanorc"
# include @PKGDATADIR@/*.nanorc
## Or you can select just the ones you need. For example:
# include "@PKGDATADIR@/html.nanorc"
# include "@PKGDATADIR@/python.nanorc"
# include "@PKGDATADIR@/sh.nanorc"
# include @PKGDATADIR@/html.nanorc
# include @PKGDATADIR@/python.nanorc
# include @PKGDATADIR@/sh.nanorc
## In @PKGDATADIR@/extra/ you can find some syntaxes that are
## specific for certain distros or for some less common languages.
@ -254,9 +264,6 @@
## independent of the settings of 'tabsize' and 'tabstospaces':
# extendsyntax python tabgives " "
## If <Tab> should always produce an actual TAB when editing a Makefile:
# extendsyntax makefile tabgives " "
## === Key bindings ===
## For all details, see 'man nanorc', section REBINDING KEYS.
@ -284,13 +291,16 @@
# unbind M-T main
## (Those functions are still accessible through ^T^J and ^T^V.)
## For quickly uppercasing or lowercasing the word under or after the cursor.
## For quickly uppercasing or lowercasing the word that the cursor is on.
## (These effectively select a word and pipe it through a sed command.)
#bind Sh-M-U "{nextword}{mark}{prevword}{execute}|sed 's/.*/\U&/'{enter}" main
#bind Sh-M-L "{nextword}{mark}{prevword}{execute}|sed 's/.*/\L&/'{enter}" main
# bind Sh-M-U "{nextword}{mark}{prevword}{execute}| sed 's/.*/\U&/' {enter}" main
# bind Sh-M-L "{nextword}{mark}{prevword}{execute}| sed 's/.*/\L&/' {enter}" main
## For copying a marked region to the system clipboard:
# bind Sh-M-T "{execute}|xsel -ib{enter}{undo}" main
# bind Sh-M-C "{execute}| xsel -ib {enter}{undo}" main
## For normalizing Unicode to precomposed characters:
# bind Sh-M-N "{execute}| uconv -x nfc {enter}" main
## For snipping trailing blanks when you save a file:
# bind ^S "{execute}| sed 's/\s\+$//' {enter}{savefile}" main
@ -298,34 +308,34 @@
## If you would like nano to have keybindings that are more "usual",
## such as ^O for Open, ^F for Find, ^H for Help, and ^Q for Quit,
## then uncomment these:
#bind ^X cut main
#bind ^C copy main
#bind ^V paste all
#bind ^Q exit all
#bind ^S savefile main
#bind ^W writeout main
#bind ^O insert main
#set multibuffer
#bind ^H help all
#bind ^H exit help
#bind ^F whereis all
#bind ^G findnext all
#bind ^B wherewas all
#bind ^D findprevious all
#bind ^R replace main
#unbind ^U all
#unbind ^N main
#unbind ^Y all
#unbind M-J main
#unbind M-T main
#bind ^A mark main
#bind ^P location main
#bind ^T gotoline main
#bind ^T gotodir browser
#bind ^T cutrestoffile execute
#bind ^L linter execute
#bind ^E execute main
#bind ^K "{mark}{end}{zap}" main
#bind ^U "{mark}{home}{zap}" main
#bind ^Z undo main
#bind ^Y redo main
# bind ^X cut main
# bind ^C copy main
# bind ^V paste all
# bind ^Q exit all
# bind ^S savefile main
# bind ^W writeout main
# bind ^O insert main
# set multibuffer
# bind ^H help all
# bind ^H exit help
# bind ^F whereis all
# bind ^G findnext all
# bind ^B wherewas all
# bind ^D findprevious all
# bind ^R replace main
# unbind ^U all
# unbind ^N main
# unbind ^Y all
# unbind M-J main
# unbind M-T main
# bind ^A mark main
# bind ^P location main
# bind ^T gotoline main
# bind ^T gotodir browser
# bind ^T cutrestoffile execute
# bind ^L linter execute
# bind ^E execute main
# bind ^K "{mark}{end}{zap}" main
# bind ^U "{mark}{home}{zap}" main
# bind ^Z undo main
# bind ^Y redo main

View File

@ -31,6 +31,5 @@ EXTRA_DIST = \
threadlib.m4 \
uintmax_t.m4 \
visibility.m4 \
wchar_t.m4 \
wint_t.m4 \
xsize.m4

1597
po/bg.po

File diff suppressed because it is too large Load Diff

1441
po/ca.po

File diff suppressed because it is too large Load Diff

1609
po/cs.po

File diff suppressed because it is too large Load Diff

1443
po/da.po

File diff suppressed because it is too large Load Diff

1447
po/de.po

File diff suppressed because it is too large Load Diff

1520
po/eo.po

File diff suppressed because it is too large Load Diff

1518
po/es.po

File diff suppressed because it is too large Load Diff

1603
po/eu.po

File diff suppressed because it is too large Load Diff

1589
po/fi.po

File diff suppressed because it is too large Load Diff

1504
po/fr.po

File diff suppressed because it is too large Load Diff

1591
po/ga.po

File diff suppressed because it is too large Load Diff

1529
po/gl.po

File diff suppressed because it is too large Load Diff

1966
po/hr.po

File diff suppressed because it is too large Load Diff

1595
po/hu.po

File diff suppressed because it is too large Load Diff

1503
po/id.po

File diff suppressed because it is too large Load Diff

1650
po/is.po

File diff suppressed because it is too large Load Diff

1792
po/it.po

File diff suppressed because it is too large Load Diff

1465
po/ja.po

File diff suppressed because it is too large Load Diff

1633
po/ka.po

File diff suppressed because it is too large Load Diff

1523
po/ko.po

File diff suppressed because it is too large Load Diff

1714
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1504
po/nb.po

File diff suppressed because it is too large Load Diff

1514
po/nl.po

File diff suppressed because it is too large Load Diff

1505
po/pl.po

File diff suppressed because it is too large Load Diff

1606
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1435
po/ro.po

File diff suppressed because it is too large Load Diff

1504
po/ru.po

File diff suppressed because it is too large Load Diff

1602
po/sk.po

File diff suppressed because it is too large Load Diff

1607
po/sl.po

File diff suppressed because it is too large Load Diff

1500
po/sq.po

File diff suppressed because it is too large Load Diff

1541
po/sr.po

File diff suppressed because it is too large Load Diff

1424
po/sv.po

File diff suppressed because it is too large Load Diff

1477
po/tr.po

File diff suppressed because it is too large Load Diff

1518
po/uk.po

File diff suppressed because it is too large Load Diff

1446
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="7.2"
VERSION="8.4"
./configure -C --enable-tiny && make && ./configure -C &&

View File

@ -30,6 +30,7 @@ nano_SOURCES = \
color.c \
cut.c \
files.c \
folding.c \
global.c \
help.c \
history.c \
@ -43,7 +44,7 @@ nano_SOURCES = \
winio.c
nano_LDADD = @LIBINTL@ $(top_builddir)/lib/libgnu.a \
$(LIB_CLOCK_GETTIME) $(LIBTHREAD)
$(GETRANDOM_LIB) $(CLOCK_TIME_LIB) $(LIBTHREAD)
install-exec-hook:
cd $(DESTDIR)$(bindir) && rm -f rnano && $(LN_S) nano rnano

View File

@ -1,7 +1,7 @@
/**************************************************************************
* browser.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 2001-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2015-2016, 2020, 2022 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -182,11 +182,11 @@ void browser_refresh(void)
if (stat(filelist[index], &state) == -1 || !S_ISDIR(state.st_mode))
info = copy_of("--");
else
/* TRANSLATORS: Try to keep this at most 7 characters. */
/* TRANSLATORS: Anything more than 7 cells gets clipped. */
info = copy_of(_("(dir)"));
} else if (S_ISDIR(state.st_mode)) {
if (strcmp(thename, "..") == 0) {
/* TRANSLATORS: Try to keep this at most 12 characters. */
/* TRANSLATORS: Anything more than 12 cells gets clipped. */
info = copy_of(_("(parent dir)"));
infomaxlen = 12;
} else
@ -215,7 +215,7 @@ void browser_refresh(void)
if (result < (1 << 10))
sprintf(info, "%4ju %cB", (intmax_t)result, modifier);
else
/* TRANSLATORS: Try to keep this at most 7 characters.
/* TRANSLATORS: Anything more than 7 cells gets clipped.
* If necessary, you can leave out the parentheses. */
info = mallocstrcpy(info, _("(huge)"));
}
@ -483,26 +483,19 @@ char *browse(char *path)
continue;
}
#endif /* ENABLE_MOUSE */
#ifndef NANO_TINY
while (bracketed_paste)
kbinput = get_kbinput(midwin, BLIND);
if (kbinput == BRACKETED_PASTE_MARKER) {
beep();
continue;
}
#endif
function = interpret(kbinput);
if (function == full_refresh || function == do_help) {
if (function == do_help || function == full_refresh) {
function();
#ifndef NANO_TINY
/* Simulate a terminal resize to force a directory reread,
* or because the terminal dimensions might have changed. */
kbinput = KEY_WINCH;
kbinput = THE_WINDOW_RESIZED;
} else if (function == do_toggle && get_shortcut(kbinput)->toggle == NO_HELP) {
TOGGLE(NO_HELP);
window_init();
kbinput = KEY_WINCH;
kbinput = THE_WINDOW_RESIZED;
#endif
} else if (function == do_search_backward) {
search_filename(BACKWARD);
@ -572,8 +565,7 @@ char *browse(char *path)
/* If the given path is relative, join it with the current path. */
if (*path != '/') {
path = nrealloc(path, strlen(present_path) +
strlen(answer) + 1);
path = nrealloc(path, strlen(present_path) + strlen(answer) + 1);
sprintf(path, "%s%s", present_path, answer);
}
@ -642,7 +634,11 @@ char *browse(char *path)
implant(first_sc_for(MBROWSER, function)->expansion);
#endif
#ifndef NANO_TINY
} else if (kbinput == KEY_WINCH) {
} else if (kbinput == START_OF_PASTE) {
while (get_kbinput(midwin, BLIND) != END_OF_PASTE)
;
statusline(AHEM, _("Paste is ignored"));
} else if (kbinput == THE_WINDOW_RESIZED) {
; /* Gets handled below. */
#endif
} else if (function == do_exit) {
@ -652,7 +648,7 @@ char *browse(char *path)
#ifndef NANO_TINY
/* If the terminal resized (or might have), refresh the file list. */
if (kbinput == KEY_WINCH) {
if (kbinput == THE_WINDOW_RESIZED) {
/* Remember the selected file, to be able to reselect it. */
present_name = copy_of(filelist[selected]);
goto read_directory_contents;

View File

@ -1,7 +1,7 @@
/**************************************************************************
* chars.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 2001-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2016-2021 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -98,10 +98,10 @@ bool is_blank_char(const char *c)
bool is_cntrl_char(const char *c)
{
#ifdef ENABLE_UTF8
if (use_utf8) {
if (use_utf8)
return ((c[0] & 0xE0) == 0 || c[0] == DEL_CODE ||
((signed char)c[0] == -62 && (signed char)c[1] < -96));
} else
else
#endif
return ((*c & 0x60) == 0 || *c == DEL_CODE);
}
@ -181,8 +181,8 @@ char control_mbrep(const char *c, bool isdata)
int mbtowide(wchar_t *wc, const char *c)
{
if ((signed char)*c < 0 && use_utf8) {
unsigned char v1 = (unsigned char)c[0];
unsigned char v2 = (unsigned char)c[1] ^ 0x80;
unsigned char v1 = c[0];
unsigned char v2 = c[1] ^ 0x80;
if (v2 > 0x3F || v1 < 0xC2)
return -1;
@ -192,7 +192,7 @@ int mbtowide(wchar_t *wc, const char *c)
return 2;
}
unsigned char v3 = (unsigned char)c[2] ^ 0x80;
unsigned char v3 = c[2] ^ 0x80;
if (v3 > 0x3F)
return -1;
@ -206,7 +206,7 @@ int mbtowide(wchar_t *wc, const char *c)
return -1;
}
unsigned char v4 = (unsigned char)c[3] ^ 0x80;
unsigned char v4 = c[3] ^ 0x80;
if (v4 > 0x3F || v1 > 0xF4)
return -1;
@ -265,8 +265,8 @@ int char_length(const char *pointer)
{
#ifdef ENABLE_UTF8
if ((unsigned char)*pointer > 0xC1 && use_utf8) {
unsigned char c1 = (unsigned char)pointer[0];
unsigned char c2 = (unsigned char)pointer[1];
unsigned char c1 = pointer[0];
unsigned char c2 = pointer[1];
if ((c2 ^ 0x80) > 0x3F)
return 1;
@ -654,3 +654,12 @@ bool white_string(const char *string)
return !*string;
}
#if defined(ENABLE_SPELLER) || defined(ENABLE_COLOR)
/* Remove leading whitespace from the given string. */
void strip_leading_blanks_from(char *string)
{
while (string && (*string == ' ' || *string == '\t'))
memmove(string, string + 1, strlen(string));
}
#endif

View File

@ -1,7 +1,7 @@
/**************************************************************************
* color.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 2001-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2014-2017, 2020, 2021 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -67,8 +67,15 @@ void set_interface_colorpairs(void)
else if (index == ERROR_MESSAGE) {
init_pair(index + 1, COLOR_WHITE, COLOR_RED);
interface_color_pair[index] = COLOR_PAIR(index + 1) | A_BOLD;
} else
} else if (index == FOLDED_LINE) {
if (COLORS > 15)
init_pair(index + 1, COLOR_BLACK + 8, COLOR_BLACK);
else
init_pair(index + 1, COLOR_WHITE, COLOR_BLACK);
interface_color_pair[index] = COLOR_PAIR(index + 1);
} else {
interface_color_pair[index] = hilite_attribute;
}
}
free(color_combo[index]);
@ -240,7 +247,7 @@ void check_the_multis(linestruct *line)
char *afterstart;
/* If there is no syntax or no multiline regex, there is nothing to do. */
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0)
if (!openfile->syntax || openfile->syntax->multiscore == 0)
return;
if (line->multidata == NULL) {
@ -293,7 +300,7 @@ void precalc_multicolorinfo(void)
regmatch_t startmatch, endmatch;
linestruct *line, *tailline;
if (!openfile->syntax || openfile->syntax->nmultis == 0 || ISSET(NO_SYNTAX))
if (!openfile->syntax || openfile->syntax->multiscore == 0 || ISSET(NO_SYNTAX))
return;
//#define TIMEPRECALC 123
@ -305,7 +312,7 @@ void precalc_multicolorinfo(void)
/* For each line, allocate cache space for the multiline-regex info. */
for (line = openfile->filetop; line != NULL; line = line->next)
if (!line->multidata)
line->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
line->multidata = nmalloc(openfile->syntax->multiscore * sizeof(short));
for (ink = openfile->syntax->color; ink != NULL; ink = ink->next) {
/* If this is not a multi-line regex, skip it. */

View File

@ -1,7 +1,7 @@
/**************************************************************************
* cut.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2014 Mark Majeres *
* Copyright (C) 2016, 2018-2020 Benno Schulenberg *
* *
@ -24,8 +24,9 @@
#include <string.h>
/* Delete the character under the cursor. */
void do_deletion(undo_type action)
/* Delete the character at the current position, and
* add or update an undo item for the given action. */
void expunge(undo_type action)
{
openfile->placewewant = xplustabs();
@ -48,6 +49,7 @@ void do_deletion(undo_type action)
memmove(&openfile->current->data[openfile->current_x],
&openfile->current->data[openfile->current_x + charlen],
line_len - charlen + 1);
UNFOLD_SEGMENT(openfile->current);
#ifndef NANO_TINY
/* When softwrapping, a changed number of chunks requires a refresh. */
if (ISSET(SOFTWRAP) && extra_chunks_in(openfile->current) != old_amount)
@ -62,6 +64,9 @@ void do_deletion(undo_type action)
} else if (openfile->current != openfile->filebot) {
linestruct *joining = openfile->current->next;
UNFOLD_SEGMENT(openfile->current);
UNFOLD_SEGMENT(joining);
/* If there is a magic line, and we're before it: don't eat it. */
if (joining == openfile->filebot && openfile->current_x != 0 &&
!ISSET(NO_NEWLINES)) {
@ -112,7 +117,8 @@ void do_deletion(undo_type action)
set_modified();
}
/* Delete the character under the cursor. */
/* Delete the character under the cursor plus any succeeding zero-widths,
* or, when the mark is on and --zap is active, delete the marked region. */
void do_delete(void)
{
#ifndef NANO_TINY
@ -121,17 +127,18 @@ void do_delete(void)
else
#endif
{
do_deletion(DEL);
expunge(DEL);
#ifdef ENABLE_UTF8
while (openfile->current->data[openfile->current_x] != '\0' &&
is_zerowidth(openfile->current->data + openfile->current_x))
do_deletion(DEL);
expunge(DEL);
#endif
}
}
/* Backspace over one character. That is, move the cursor left one
* character, and then delete the character under the cursor. */
* character, and then delete the character under the cursor. Or,
* when mark is on and --zap is active, delete the marked region. */
void do_backspace(void)
{
#ifndef NANO_TINY
@ -141,10 +148,16 @@ void do_backspace(void)
#endif
if (openfile->current_x > 0) {
openfile->current_x = step_left(openfile->current->data, openfile->current_x);
do_deletion(BACK);
expunge(BACK);
} else if (openfile->current != openfile->filetop) {
do_left();
do_deletion(BACK);
#ifdef ENABLE_FOLDING
if (openfile->current->prev->folded) {
openfile->current = openfile->current->prev;
openfile->current_x = strlen(openfile->current->data);
} else
#endif
do_left();
expunge(BACK);
}
}
@ -192,7 +205,7 @@ void chop_word(bool forward)
* on the edge of the original line, then put the cursor on that
* edge instead, so that lines will not be joined unexpectedly. */
if (!forward) {
do_prev_word();
do_prev_word(ALLOW_FOLDED);
if (openfile->current != is_current) {
if (is_current_x > 0) {
openfile->current = is_current;
@ -201,13 +214,14 @@ void chop_word(bool forward)
openfile->current_x = strlen(openfile->current->data);
}
} else {
do_next_word(ISSET(AFTER_ENDS));
do_next_word(ISSET(AFTER_ENDS), ALLOW_FOLDED);
if (openfile->current != is_current &&
is_current->data[is_current_x] != '\0') {
openfile->current = is_current;
openfile->current_x = strlen(is_current->data);
}
}
UNFOLD_SEGMENT(openfile->current);
/* Set the mark at the start of that word. */
openfile->mark = openfile->current;
@ -262,9 +276,13 @@ void extract_segment(linestruct *top, size_t top_x, linestruct *bot, size_t bot_
if (top == bot && top_x == bot_x)
return;
if (top != bot)
for (linestruct *line = top->next; line != bot->next; line = line->next)
if (top != bot) {
UNFOLD_SEGMENT(top);
for (linestruct *line = top->next; line != bot->next; line = line->next) {
UNFOLD_SEGMENT(line);
had_anchor |= line->has_anchor;
}
}
#endif
if (top == bot) {
@ -378,6 +396,8 @@ void ingraft_buffer(linestruct *topline)
#endif
linestruct *botline = topline;
UNFOLD_SEGMENT(line);
while (botline->next != NULL)
botline = botline->next;
@ -634,6 +654,7 @@ void copy_marked_region(void)
botline->data[bot_x] = saved_byte;
botline->next = afterline;
}
#endif /* !NANO_TINY */
/* Copy text from the current buffer into the cutbuffer. The text is either
* the marked region, the whole line, the text from cursor to end-of-line,
@ -646,17 +667,24 @@ void copy_text(void)
linestruct *was_current = openfile->current;
linestruct *addition;
if (openfile->mark || openfile->last_action != COPY || !keep_cutbuffer) {
#ifndef NANO_TINY
if (openfile->mark || openfile->last_action != COPY)
keep_cutbuffer = FALSE;
#endif
if (!keep_cutbuffer) {
free_lines(cutbuffer);
cutbuffer = NULL;
}
wipe_statusbar();
#ifndef NANO_TINY
if (openfile->mark) {
copy_marked_region();
return;
}
#endif
/* When at the very end of the buffer, there is nothing to do. */
if (openfile->current->next == NULL && at_eol && (ISSET(CUT_FROM_CURSOR) ||
@ -706,10 +734,11 @@ void copy_text(void)
edit_redraw(was_current, FLOWING);
#ifndef NANO_TINY
openfile->last_action = COPY;
#endif
keep_cutbuffer = TRUE;
}
#endif /* !NANO_TINY */
/* Copy text from the cutbuffer into the current buffer. */
void paste_text(void)
@ -728,6 +757,7 @@ void paste_text(void)
statusline(AHEM, _("Cutbuffer is empty"));
return;
}
UNFOLD_SEGMENT(openfile->current);
#ifndef NANO_TINY
add_undo(PASTE, NULL);

View File

@ -1,7 +1,7 @@
/**************************************************************************
* definitions.h -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2014-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -195,6 +195,8 @@
#define ALT_RIGHT 0x422
#define ALT_UP 0x423
#define ALT_DOWN 0x424
#define ALT_HOME 0x425
#define ALT_END 0x426
#define ALT_PAGEUP 0x427
#define ALT_PAGEDOWN 0x428
#define ALT_INSERT 0x42C
@ -203,8 +205,6 @@
#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
@ -214,22 +214,28 @@
#define SHIFT_DELETE 0x45D
#define SHIFT_TAB 0x45F
#define FOCUS_IN 0x491
#define FOCUS_OUT 0x499
#define FOCUS_IN 0x491
#define FOCUS_OUT 0x499
/* Custom keycodes for signaling the start and end of a bracketed paste. */
#define START_OF_PASTE 0x4B5
#define END_OF_PASTE 0x4BE
/* Special keycodes for when a string bind has been partially implanted
* or has an unpaired opening brace, or when a function in a string bind
* needs execution or a specified function name is invalid. */
#define MORE_PLANTS 0x4EA
#define MISSING_BRACE 0x4EB
#define PLANTED_A_COMMAND 0x4EC
#define NO_SUCH_FUNCTION 0x4EF
#define MORE_PLANTS 0x4EA
#define MISSING_BRACE 0x4EB
#define PLANTED_A_COMMAND 0x4EC
#define NO_SUCH_FUNCTION 0x4EF
/* A special keycode for when <Tab> is pressed while the mark is on. */
#define INDENT_KEY 0x4F1
#ifndef NANO_TINY
/* A special keycode for Ctrl + the central key on the numeric keypad. */
#define KEY_CENTER 0x4F0
/* A special keycode to signal the beginning and end of a bracketed paste. */
#define BRACKETED_PASTE_MARKER 0x4FB
/* A special keycode for when we get a SIGWINCH (a window resize). */
#define THE_WINDOW_RESIZED 0x4F7
#endif
/* A special keycode for when a key produces an unknown escape sequence. */
#define FOREIGN_SEQUENCE 0x4FC
@ -238,9 +244,6 @@
#define KEY_FRESH 0x4FE
#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)
@ -276,6 +279,15 @@
#define MSOME MMAIN|MBROWSER
#endif
#ifdef ENABLE_FOLDING
#define UNFOLD_SEGMENT(line) unfold_folded_segment(line)
#else
#define UNFOLD_SEGMENT(line)
#endif
#define ALLOW_FOLDED TRUE
#define DISALLOW_FOLDED FALSE
/* Enumeration types. */
typedef enum {
UNSPECIFIED, NIX_FILE, DOS_FILE, MAC_FILE
@ -286,7 +298,7 @@ typedef enum {
} message_type;
typedef enum {
OVERWRITE, APPEND, PREPEND
OVERWRITE, APPEND, PREPEND, EMERGENCY
} kind_of_writing_type;
typedef enum {
@ -321,6 +333,7 @@ enum {
ERROR_MESSAGE,
KEY_COMBO,
FUNCTION_TAG,
FOLDED_LINE,
NUMBER_OF_ELEMENTS
};
@ -371,12 +384,20 @@ enum {
EMPTY_LINE,
INDICATOR,
BOOKSTYLE,
COLON_PARSING,
STATEFLAGS,
USE_MAGIC,
MINIBAR,
ZERO
ZERO,
MODERN_BINDINGS
};
typedef enum {
FOUND_BRACKET = 0,
NOT_FOUND_BRACKET,
NOT_A_BRACKET
} bracket_search_result;
/* Structure types. */
#ifdef ENABLE_COLOR
typedef struct colortype {
@ -443,7 +464,7 @@ typedef struct syntaxtype {
#endif
colortype *color;
/* The colors and their regexes used in this syntax. */
short nmultis;
short multiscore;
/* How many multiline regex strings this syntax has. */
struct syntaxtype *next;
/* Next syntax. */
@ -483,6 +504,10 @@ typedef struct linestruct {
bool has_anchor;
/* Whether the user has placed an anchor at this line. */
#endif
#ifdef ENABLE_FOLDING
bool folded;
/* Whether or not this line is in a fold segment */
#endif
} linestruct;
#ifndef NANO_TINY
@ -558,8 +583,8 @@ typedef struct openfilestruct {
/* The file's x-coordinate position. */
size_t placewewant;
/* The file's x position we would like. */
ssize_t current_y;
/* The file's y-coordinate position. */
ssize_t cursor_row;
/* The row in the edit window that the cursor is on. */
struct stat *statinfo;
/* The file's stat information from when it was opened or last saved. */
#ifdef ENABLE_WRAPPING

View File

@ -1,7 +1,7 @@
/**************************************************************************
* files.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2015-2022 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -73,7 +73,7 @@ void make_new_buffer(void)
openfile->current = openfile->filetop;
openfile->current_x = 0;
openfile->placewewant = 0;
openfile->current_y = 0;
openfile->cursor_row = 0;
openfile->edittop = openfile->filetop;
openfile->firstcolumn = 0;
@ -682,6 +682,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
if (ISSET(SOFTWRAP))
was_leftedge = leftedge_for(xplustabs(), openfile->current);
#endif
UNFOLD_SEGMENT(openfile->current);
/* Create an empty buffer. */
topline = make_new_node(NULL);
@ -830,18 +831,20 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
if (!writable)
statusline(ALERT, _("File '%s' is unwritable"), filename);
else if ((ISSET(ZERO) || ISSET(MINIBAR)) && !(we_are_running && undoable))
; /* No blurb for new buffers with --zero or --mini. */
#ifndef NANO_TINY
else if (format == MAC_FILE)
/* TRANSLATORS: Keep the next three messages at most 78 characters. */
statusline(REMARK, P_("Read %zu line (Converted from Mac format)",
"Read %zu lines (Converted from Mac format)",
statusline(REMARK, P_("Read %zu line (converted from Mac format)",
"Read %zu lines (converted from Mac format)",
num_lines), num_lines);
else if (format == DOS_FILE)
statusline(REMARK, P_("Read %zu line (Converted from DOS format)",
"Read %zu lines (Converted from DOS format)",
statusline(REMARK, P_("Read %zu line (converted from DOS format)",
"Read %zu lines (converted from DOS format)",
num_lines), num_lines);
#endif
else if ((!ISSET(MINIBAR) && !ISSET(ZERO)) || (we_are_running && undoable))
else
statusline(REMARK, P_("Read %zu line", "Read %zu lines",
num_lines), num_lines);
@ -1013,7 +1016,7 @@ void send_data(const linestruct *line, int fd)
/* Execute the given command in a shell. */
void execute_command(const char *command)
{
#if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAIT)
#if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)
int from_fd[2], to_fd[2];
/* The pipes through which text will be written and read. */
struct sigaction oldaction, newaction = {{0}};
@ -1195,6 +1198,12 @@ void insert_a_file_or(bool execute)
/* Reset the flag that is set by the Spell Checker and Linter and such. */
ran_a_tool = FALSE;
#ifndef NANO_TINY
/* If something was typed at the Execute prompt without being run, restore it. */
if (execute && *foretext)
given = mallocstrcpy(given, foretext);
#endif
while (TRUE) {
#ifndef NANO_TINY
if (execute) {
@ -1761,6 +1770,8 @@ bool write_file(const char *name, FILE *thefile, bool normal,
#endif
char *realname = real_dir_from_tilde(name);
/* The filename after tilde expansion. */
int descriptor = 0;
/* The descriptor that gets assigned when opening the file. */
char *tempname = NULL;
/* The name of the temporary file we use when prepending. */
linestruct *line = openfile->filetop;
@ -1844,7 +1855,6 @@ bool write_file(const char *name, FILE *thefile, bool normal,
* For an emergency file, access is restricted to just the owner. */
if (thefile == NULL) {
mode_t permissions = (normal ? RW_FOR_ALL : S_IRUSR|S_IWUSR);
int fd;
#ifndef NANO_TINY
block_sigwinch(TRUE);
@ -1853,7 +1863,7 @@ bool write_file(const char *name, FILE *thefile, bool normal,
#endif
/* Now open the file. Use O_EXCL for an emergency file. */
fd = open(realname, O_WRONLY | O_CREAT | ((method == APPEND) ?
descriptor = open(realname, O_WRONLY | O_CREAT | ((method == APPEND) ?
O_APPEND : (normal ? O_TRUNC : O_EXCL)), permissions);
#ifndef NANO_TINY
@ -1863,7 +1873,7 @@ bool write_file(const char *name, FILE *thefile, bool normal,
#endif
/* If we couldn't open the file, give up. */
if (fd == -1) {
if (descriptor < 0) {
if (errno == EINTR || errno == 0)
statusline(ALERT, _("Interrupted"));
else
@ -1875,11 +1885,11 @@ bool write_file(const char *name, FILE *thefile, bool normal,
goto cleanup_and_exit;
}
thefile = fdopen(fd, (method == APPEND) ? "ab" : "wb");
thefile = fdopen(descriptor, (method == APPEND) ? "ab" : "wb");
if (thefile == NULL) {
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
close(fd);
close(descriptor);
goto cleanup_and_exit;
}
}
@ -1970,6 +1980,16 @@ bool write_file(const char *name, FILE *thefile, bool normal,
}
#endif
#if !defined(NANO_TINY) && defined(HAVE_CHMOD) && defined(HAVE_CHOWN)
/* Change permissions and owner of an emergency save file to the values
* of the original file, but ignore any failure as we are in a hurry. */
if (method == EMERGENCY && descriptor && openfile->statinfo) {
IGNORE_CALL_RESULT(fchmod(descriptor, openfile->statinfo->st_mode));
IGNORE_CALL_RESULT(fchown(descriptor, openfile->statinfo->st_uid,
openfile->statinfo->st_gid));
}
#endif
if (fclose(thefile) != 0) {
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
@ -2143,11 +2163,11 @@ int write_it_out(bool exiting, bool withprompt)
(method == APPEND) ? _("Append Selection to File") :
_("Write Selection to File");
else if (method != OVERWRITE)
msg = (method == PREPEND) ? _("File Name to Prepend to") :
_("File Name to Append to");
/* TRANSLATORS: Next three prompts are analogous to the above three. */
msg = (method == PREPEND) ? _("Prepend to File") : _("Append to File");
else
#endif
msg = _("File Name to Write");
msg = _("Write to File");
present_path = mallocstrcpy(present_path, "./");
@ -2183,7 +2203,7 @@ int write_it_out(bool exiting, bool withprompt)
given = mallocstrcpy(given, answer);
#ifdef ENABLE_BROWSER
if (function == to_files) {
if (function == to_files && !ISSET(RESTRICTED)) {
char *chosen = browse_in(answer);
if (chosen == NULL)
@ -2200,10 +2220,10 @@ int write_it_out(bool exiting, bool withprompt)
} else if (function == mac_format) {
openfile->fmt = (openfile->fmt == MAC_FILE) ? NIX_FILE : MAC_FILE;
continue;
} else if (function == back_it_up) {
} else if (function == back_it_up && !ISSET(RESTRICTED)) {
TOGGLE(MAKE_BACKUP);
continue;
} else if (function == prepend_it || function == append_it) {
} else if ((function == prepend_it || function == append_it) && !ISSET(RESTRICTED)) {
if (function == prepend_it)
method = (method == PREPEND) ? OVERWRITE : PREPEND;
else
@ -2534,9 +2554,7 @@ char **filename_completion(const char *morsel, size_t *num_matches)
if (strncmp(entry->d_name, filename, filenamelen) == 0 &&
strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0) {
fullname = nrealloc(fullname, strlen(dirname) +
strlen(entry->d_name) + 1);
fullname = nrealloc(fullname, strlen(dirname) + strlen(entry->d_name) + 1);
sprintf(fullname, "%s%s", dirname, entry->d_name);
#ifdef ENABLE_OPERATINGDIR

158
src/folding.c Normal file
View File

@ -0,0 +1,158 @@
/**************************************************************************
* folding.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2023 rexy712 *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
#include "prototypes.h"
#include <string.h>
#ifdef ENABLE_FOLDING
/* Unfold a folded segment containing the given line. */
void unfold_folded_segment(linestruct *line)
{
line = get_start_of_folded_segment(line);
if (line != NULL)
refresh_needed = TRUE;
for (; line != NULL && line->folded; line = line->next)
line->folded = FALSE;
}
/* Get the first line of the folded segment. */
linestruct *get_start_of_folded_segment(linestruct *line)
{
if (!line->folded)
return line;
while (line->prev != NULL && line->prev->folded)
line = line->prev;
return line;
}
/* Get the last line of the folded segment. */
linestruct *get_end_of_folded_segment(linestruct *line)
{
if (!line->folded)
return line;
while (line->next != NULL && line->next->folded)
line = line->next;
return line;
}
/* Get the number of lines in a folded segment. */
int get_folded_segment_length(linestruct *line)
{
int i = 1;
if (!line->folded)
return 0;
line = get_start_of_folded_segment(line);
for (; line->next != NULL && line->next->folded; line = line->next)
++i;
return i;
}
/* Unfolds a folded segment containing line, or if line is not folded
* does nothing. Returns true if any segments are unfolded. */
bool do_unfold_segment(linestruct *line)
{
/* If current line is folded, just unfold and finish. */
if (line->folded) {
unfold_folded_segment(line);
return TRUE;
}
/* If all else fails, attempt to find the next folded line in the file. */
for (line = openfile->current; line != NULL; line = line->next) {
if (line->folded) {
unfold_folded_segment(line);
openfile->current = line;
if (line->prev)
do_up();
else
move_cursor_to_proper_column();
return TRUE;
}
}
return FALSE;
}
/* Fold the currently selected lines unless the current line is
* a folded lines. In that case, remove unfold the lines. */
void do_fold_segment(void)
{
linestruct *top, *bot, *line;
get_range(&top, &bot);
size_t top_pos, bot_pos;
bool region_found = (top != bot);
if (top == bot) {
/* First try to unfold if this line/bracketed region is folded. */
if (top->folded) {
unfold_folded_segment(top);
return;
}
/* When no selection is made, attempt to find the next line
* ending with an opening bracket as the top bound. */
for (; find_terminus_of_bracketed_region(&top, &top_pos, get_matchbrackets_halfway(), FALSE)
; top = top->next) {
bot = top;
bot_pos = top_pos;
if (find_matching_bracket_pos(&bot, &bot_pos) == FOUND_BRACKET
&& bot->lineno - top->lineno >= 2) {
top = top->next;
bot = bot->prev;
/* Unfold if already folded. */
region_found = !top->folded;
break;
}
}
}
if (region_found == TRUE) {
for (line = top; line != bot->next; line = line->next)
line->folded = TRUE;
/* Place the cursor after the new fold, accounting for possible
* fold concatenations occurring. */
openfile->current = get_end_of_folded_segment(bot);
if (bot->next)
do_down();
else
move_cursor_to_proper_column();
if (top->lineno < openfile->edittop->lineno &&
bot->lineno > openfile->edittop->lineno)
openfile->edittop = top;
openfile->mark = NULL;
refresh_needed = TRUE;
} else
if (!do_unfold_segment(openfile->current))
statusline(AHEM, _("No valid region found for automatic fold"));
}
#endif /* ENABLE_FOLDING */

View File

@ -1,7 +1,7 @@
/**************************************************************************
* global.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2014-2022 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -24,6 +24,7 @@
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <term.h>
/* Global variables. */
#ifndef NANO_TINY
@ -42,8 +43,6 @@ bool shift_held;
/* Whether Shift was being held together with a movement key. */
bool mute_modifiers = FALSE;
/* Whether to ignore modifier keys while running a macro or string bind. */
bool bracketed_paste = FALSE;
/* Whether text is being pasted into nano from outside. */
bool we_are_running = FALSE;
/* Becomes TRUE as soon as all options and files have been read. */
@ -51,8 +50,13 @@ 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. */
#ifndef NANO_TINY
char *foretext = NULL;
/* What was typed at the Execute prompt before invoking a tool. */
#endif
bool inhelp = FALSE;
/* Whether we are in the help viewer. */
@ -99,11 +103,11 @@ int controlleft, controlright, controlup, controldown;
int controlhome, controlend;
#ifndef NANO_TINY
int controldelete, controlshiftdelete;
int shiftleft, shiftright, shiftup, shiftdown;
int shiftup, shiftdown;
int shiftcontrolleft, shiftcontrolright, shiftcontrolup, shiftcontroldown;
int shiftcontrolhome, shiftcontrolend;
int altleft, altright, altup, altdown;
int altpageup, altpagedown;
int althome, altend, altpageup, altpagedown;
int altinsert, altdelete;
int shiftaltleft, shiftaltright, shiftaltup, shiftaltdown;
#endif
@ -131,13 +135,16 @@ int editwincols = -1;
/* The number of usable columns in the edit window: COLS - margin. */
int margin = 0;
/* The amount of space reserved at the left for line numbers. */
int thebar = 0;
/* Becomes 1 when a scrollbar is shown. */
int sidebar = 0;
/* Becomes 1 when the indicator "scroll bar" must be shown. */
#ifndef NANO_TINY
int *bardata = NULL;
/* An array of characters that together depict the scrollbar. */
ssize_t stripe_column = 0;
/* The column at which a vertical bar will be drawn. */
int cycling_aim = 0;
/* Whether to center the line with the cursor (0), push it
* to the top of the viewport (1), or to the bottom (2). */
#endif
linestruct *cutbuffer = NULL;
@ -387,6 +394,15 @@ int keycode_from_string(const char *keystring)
return -1;
}
#if defined(ENABLE_EXTRA) && defined(NCURSES_VERSION_PATCH)
/* Report the version of ncurses that nano is linked against. */
void show_curses_version(void)
{
statusline(INFO, "ncurses-%i.%i, patch %li", NCURSES_VERSION_MAJOR,
NCURSES_VERSION_MINOR, NCURSES_VERSION_PATCH);
}
#endif
/* Add a key combo to the linked list of shortcuts. */
void add_to_sclist(int menus, const char *scstring, const int keycode,
void (*function)(void), int toggle)
@ -462,11 +478,6 @@ const keystruct *get_shortcut(const int keycode)
if (meta_key && keycode < 0x20)
return NULL;
#ifndef NANO_TINY
/* During a paste at a prompt, ignore all command keycodes. */
if (bracketed_paste && keycode != BRACKETED_PASTE_MARKER)
return NULL;
#endif
#ifdef ENABLE_NANORC
if (keycode == PLANTED_A_COMMAND)
return planted_shortcut;
@ -494,7 +505,7 @@ functionptrtype func_from_key(const int keycode)
* with Pico or to mimic 'less' and similar text viewers. */
functionptrtype interpret(const int keycode)
{
if (!meta_key) {
if (!meta_key && keycode < 0x7F) {
if (keycode == 'N')
return do_findprevious;
if (keycode == 'n')
@ -560,6 +571,8 @@ void shortcut_init(void)
N_("Search backward for a string or a regular expression");
const char *cut_gist =
N_("Cut current line (or marked region) and store it in cutbuffer");
const char *copy_gist =
N_("Copy current line (or marked region) and store it in cutbuffer");
const char *paste_gist =
N_("Paste the contents of cutbuffer at current cursor position");
const char *cursorpos_gist = N_("Display the position of the cursor");
@ -569,9 +582,8 @@ void shortcut_init(void)
const char *replace_gist = N_("Replace a string or a regular expression");
const char *gotoline_gist = N_("Go to line and column number");
#ifndef NANO_TINY
const char *bracket_gist = N_("Go to the matching bracket");
const char *mark_gist = N_("Mark text starting from the cursor position");
const char *copy_gist =
N_("Copy current line (or marked region) and store it in cutbuffer");
const char *zap_gist = N_("Throw away the current line (or marked region)");
const char *indent_gist = N_("Indent the current line (or marked lines)");
const char *unindent_gist = N_("Unindent the current line (or marked lines)");
@ -593,20 +605,22 @@ void shortcut_init(void)
N_("Go to beginning of paragraph; then of previous paragraph");
const char *paraend_gist =
N_("Go just beyond end of paragraph; then of next paragraph");
#endif
#ifndef NANO_TINY
const char *toprow_gist = N_("Go to first row in the viewport");
const char *bottomrow_gist = N_("Go to last row in the viewport");
const char *center_gist = N_("Center the line where the cursor is");
const char *cycle_gist = N_("Push the cursor line to the center, then top, then bottom");
#endif
const char *prevpage_gist = N_("Go one screenful up");
const char *nextpage_gist = N_("Go one screenful down");
const char *firstline_gist = N_("Go to the first line of the file");
const char *lastline_gist = N_("Go to the last line of the file");
#ifndef NANO_TINY
const char *bracket_gist = N_("Go to the matching bracket");
#endif
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
const char *scrollup_gist =
N_("Scroll up one line without moving the cursor textually");
const char *scrolldown_gist =
N_("Scroll down one line without moving the cursor textually");
const char *center_gist = N_("Center the line where the cursor is");
#endif
#ifdef ENABLE_MULTIBUFFER
const char *prevfile_gist = N_("Switch to the previous file buffer");
@ -646,6 +660,9 @@ void shortcut_init(void)
const char *savefile_gist = N_("Save file without prompting");
const char *findprev_gist = N_("Search next occurrence backward");
const char *findnext_gist = N_("Search next occurrence forward");
#ifdef ENABLE_FOLDING
const char *fold_gist = N_("Fold/unfold the currently selected lines");
#endif
#ifndef NANO_TINY
const char *recordmacro_gist = N_("Start/stop recording a macro");
const char *runmacro_gist = N_("Run the last recorded macro");
@ -669,6 +686,10 @@ void shortcut_init(void)
const char *execute_gist = N_("Execute a function or an external command");
const char *pipe_gist =
N_("Pipe the current buffer (or marked region) to the command");
#ifdef ENABLE_HISTORIES
const char *older_command_gist = N_("Recall the previous command");
const char *newer_command_gist = N_("Recall the next command");
#endif
const char *convert_gist = N_("Do not convert from DOS/Mac format");
#endif
#ifdef ENABLE_MULTIBUFFER
@ -704,6 +725,10 @@ void shortcut_init(void)
#endif
#endif /* ENABLE_HELP */
/* If Backspace is not ^H, then ^H can be used for Help. */
char *bsp_string = tgetstr("kb", NULL);
char *help_key = (bsp_string && *bsp_string != 0x08) ? "^H" : "^N";
#ifdef ENABLE_HELP
#define WHENHELP(description) description
#else
@ -770,12 +795,12 @@ void shortcut_init(void)
#ifdef NANO_TINY
add_to_funcs(do_search_backward, MHELP,
N_("Where Was"), WHENHELP(wherewas_gist), TOGETHER);
"Where Was", WHENHELP(wherewas_gist), TOGETHER);
add_to_funcs(do_findprevious, MMAIN|MHELP,
N_("Previous"), WHENHELP(findprev_gist), TOGETHER);
"Previous", WHENHELP(findprev_gist), TOGETHER);
add_to_funcs(do_findnext, MMAIN|MHELP,
N_("Next"), WHENHELP(findnext_gist), BLANKAFTER);
"Next", WHENHELP(findnext_gist), BLANKAFTER);
#endif
add_to_funcs(cut_text, MMAIN,
@ -808,7 +833,7 @@ void shortcut_init(void)
#ifndef NANO_TINY
add_to_funcs(do_undo, MMAIN,
/* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */
/* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */
N_("Undo"), WHENHELP(undo_gist), TOGETHER);
add_to_funcs(do_redo, MMAIN,
N_("Redo"), WHENHELP(redo_gist), BLANKAFTER);
@ -836,6 +861,12 @@ void shortcut_init(void)
N_("Older"), WHENHELP(older_gist), TOGETHER);
add_to_funcs(get_newer_item, MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE,
N_("Newer"), WHENHELP(newer_gist), BLANKAFTER);
#ifndef NANO_TINY
add_to_funcs(get_older_item, MEXECUTE,
N_("Older"), WHENHELP(older_command_gist), TOGETHER);
add_to_funcs(get_newer_item, MEXECUTE,
N_("Newer"), WHENHELP(newer_command_gist), BLANKAFTER);
#endif
#endif
#ifdef ENABLE_BROWSER
@ -891,23 +922,26 @@ void shortcut_init(void)
#ifndef NANO_TINY
add_to_funcs(to_prev_word, MMAIN,
/* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */
/* TRANSLATORS: Try to keep the next four strings at most 12 characters. */
N_("Prev Word"), WHENHELP(prevword_gist), TOGETHER);
add_to_funcs(to_next_word, MMAIN,
N_("Next Word"), WHENHELP(nextword_gist), TOGETHER);
#endif
add_to_funcs(do_home, MMAIN,
/* TRANSLATORS: These two mean: "to beginning of line", "to end of line". */
N_("Home"), WHENHELP(home_gist), TOGETHER);
add_to_funcs(do_end, MMAIN,
N_("End"), WHENHELP(end_gist), BLANKAFTER);
add_to_funcs(do_up, MMAIN|MBROWSER|MHELP,
/* TRANSLATORS: Try to keep the next two strings at most 10 characters. */
N_("Prev Line"), WHENHELP(prevline_gist), TOGETHER);
add_to_funcs(do_down, MMAIN|MBROWSER|MHELP,
N_("Next Line"), WHENHELP(nextline_gist), TOGETHER);
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
add_to_funcs(do_scroll_up, MMAIN,
/* TRANSLATORS: Try to keep the next four strings at most 12 characters. */
N_("Scroll Up"), WHENHELP(scrollup_gist), TOGETHER);
add_to_funcs(do_scroll_down, MMAIN,
N_("Scroll Down"), WHENHELP(scrolldown_gist), BLANKAFTER);
@ -925,8 +959,15 @@ void shortcut_init(void)
N_("End of Paragraph"), WHENHELP(paraend_gist), BLANKAFTER);
#endif
#ifndef NANO_TINY
add_to_funcs(to_top_row, MMAIN,
N_("Top Row"), WHENHELP(toprow_gist), TOGETHER);
add_to_funcs(to_bottom_row, MMAIN,
N_("Bottom Row"), WHENHELP(bottomrow_gist), BLANKAFTER);
#endif
add_to_funcs(do_page_up, MMAIN|MHELP,
/* TRANSLATORS: Try to keep the next six strings at most 12 characters. */
/* TRANSLATORS: Try to keep the next four strings at most 10 characters. */
N_("Prev Page"), WHENHELP(prevpage_gist), TOGETHER);
add_to_funcs(do_page_down, MMAIN|MHELP,
N_("Next Page"), WHENHELP(nextpage_gist), TOGETHER);
@ -938,6 +979,7 @@ void shortcut_init(void)
#ifdef ENABLE_MULTIBUFFER
add_to_funcs(switch_to_prev_buffer, MMAIN,
/* TRANSLATORS: Try to keep these two strings at most 15 characters. */
N_("Prev File"), WHENHELP(prevfile_gist), TOGETHER);
add_to_funcs(switch_to_next_buffer, MMAIN,
N_("Next File"), WHENHELP(nextfile_gist), BLANKAFTER);
@ -977,6 +1019,9 @@ void shortcut_init(void)
#ifndef NANO_TINY
add_to_funcs(count_lines_words_and_characters, MMAIN,
N_("Word Count"), WHENHELP(wordcount_gist), TOGETHER);
#else
add_to_funcs(copy_text, MMAIN,
N_("Copy"), WHENHELP(copy_gist), BLANKAFTER);
#endif
add_to_funcs(do_verbatim_input, MMAIN,
@ -984,7 +1029,7 @@ void shortcut_init(void)
#ifdef NANO_TINY
add_to_funcs(do_search_backward, MMAIN,
N_("Where Was"), WHENHELP(wherewas_gist), BLANKAFTER);
"Where Was", WHENHELP(wherewas_gist), BLANKAFTER);
#else
add_to_funcs(do_indent, MMAIN,
N_("Indent"), WHENHELP(indent_gist), TOGETHER);
@ -1005,7 +1050,14 @@ void shortcut_init(void)
N_("Record"), WHENHELP(recordmacro_gist), TOGETHER);
add_to_funcs(run_macro, MMAIN,
N_("Run Macro"), WHENHELP(runmacro_gist), BLANKAFTER);
#endif
#ifdef ENABLE_FOLDING
add_to_funcs(do_fold_segment, MMAIN, N_("Fold"),
WHENHELP(fold_gist), BLANKAFTER);
#endif
#ifndef NANO_TINY
add_to_funcs(zap_text, MMAIN,
/* TRANSLATORS: This refers to deleting a line or marked region. */
N_("Zap"), WHENHELP(zap_gist), BLANKAFTER);
@ -1040,11 +1092,13 @@ void shortcut_init(void)
#ifdef ENABLE_HELP
add_to_funcs(full_refresh, MMAIN,
N_("Refresh"), WHENHELP(refresh_gist), TOGETHER);
N_("Refresh"), WHENHELP(refresh_gist), BLANKAFTER);
#endif
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
#ifndef NANO_TINY
add_to_funcs(do_center, MMAIN,
N_("Center"), WHENHELP(center_gist), BLANKAFTER);
N_("Center"), WHENHELP(center_gist), TOGETHER);
add_to_funcs(do_cycle, MMAIN,
N_("Cycle"), WHENHELP(cycle_gist), BLANKAFTER);
#endif
add_to_funcs(do_savefile, MMAIN,
@ -1062,6 +1116,7 @@ void shortcut_init(void)
#endif
#ifdef ENABLE_SPELLER
add_to_funcs(do_spell, MEXECUTE,
/* TRANSLATORS: Try to keep the next four strings at most 12 characters. */
N_("Spell Check"), WHENHELP(spell_gist), TOGETHER);
#endif
#ifdef ENABLE_LINTER
@ -1168,34 +1223,69 @@ void shortcut_init(void)
/* 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);
add_to_sclist(MMOST, "^H", '\b', do_backspace, 0);
add_to_sclist(MMOST, "Bsp", KEY_BACKSPACE, do_backspace, 0);
add_to_sclist(MMOST, "Sh-Del", SHIFT_DELETE, do_backspace, 0);
add_to_sclist(MMOST, "^D", 0, do_delete, 0);
add_to_sclist(MMOST, "Del", KEY_DC, do_delete, 0);
add_to_sclist(MMOST, "^I", '\t', do_tab, 0);
add_to_sclist(MMOST, "Tab", '\t', do_tab, 0);
add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, "^G", 0, do_help, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^X", 0, do_exit, 0);
if (!ISSET(PRESERVE))
add_to_sclist(MMAIN|MBROWSER|MHELP, "^B", 0, do_search_backward, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^F", 0, do_search_forward, 0);
if (ISSET(MODERN_BINDINGS)) {
add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, help_key, 0, do_help, 0);
add_to_sclist(MHELP, help_key, 0, do_exit, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^Q", 0, do_exit, 0);
add_to_sclist(MMAIN, "^S", 0, do_savefile, 0);
add_to_sclist(MMAIN, "^O", 0, do_writeout, 0);
add_to_sclist(MMAIN, "^R", 0, do_insertfile, 0);
add_to_sclist(MMAIN, "^W", 0, do_writeout, 0);
add_to_sclist(MMAIN, "^O", 0, do_insertfile, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^D", 0, do_findprevious, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^G", 0, do_findnext, 0);
add_to_sclist(MMAIN, "^R", 0, do_replace, 0);
add_to_sclist(MMAIN, "^T", 0, do_gotolinecolumn, 0);
add_to_sclist(MMAIN, "^P", 0, report_cursor_position, 0);
#ifndef NANO_TINY
add_to_sclist(MMAIN, "^Z", 0, do_undo, 0);
add_to_sclist(MMAIN, "^Y", 0, do_redo, 0);
add_to_sclist(MMAIN, "^A", 0, do_mark, 0);
#endif
add_to_sclist(MMAIN, "^X", 0, cut_text, 0);
add_to_sclist(MMAIN, "^C", 0, copy_text, 0);
add_to_sclist(MMAIN, "^V", 0, paste_text, 0);
} else {
add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, "^G", 0, do_help, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^X", 0, do_exit, 0);
if (!ISSET(PRESERVE))
add_to_sclist(MMAIN, "^S", 0, do_savefile, 0);
add_to_sclist(MMAIN, "^O", 0, do_writeout, 0);
add_to_sclist(MMAIN, "^R", 0, do_insertfile, 0);
if (!ISSET(PRESERVE))
add_to_sclist(MMAIN|MBROWSER|MHELP, "^Q", 0, do_search_backward, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^W", 0, do_search_forward, 0);
add_to_sclist(MMOST, "^A", 0, do_home, 0);
add_to_sclist(MMOST, "^E", 0, do_end, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^P", 0, do_up, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^N", 0, do_down, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "^Y", 0, do_page_up, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "^V", 0, do_page_down, 0);
add_to_sclist(MMAIN, "^C", 0, report_cursor_position, 0);
add_to_sclist(MMOST, "^H", '\b', do_backspace, 0);
add_to_sclist(MMOST, "^D", 0, do_delete, 0);
}
add_to_sclist(MMOST, "Bsp", KEY_BACKSPACE, do_backspace, 0);
add_to_sclist(MMOST, "Sh-Del", SHIFT_DELETE, do_backspace, 0);
add_to_sclist(MMOST, "Del", KEY_DC, do_delete, 0);
add_to_sclist(MMAIN, "Ins", KEY_IC, do_insertfile, 0);
if (!ISSET(PRESERVE))
add_to_sclist(MMAIN|MBROWSER|MHELP, "^Q", 0, do_search_backward, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^W", 0, do_search_forward, 0);
add_to_sclist(MMAIN, "^\\", 0, do_replace, 0);
add_to_sclist(MMAIN, "M-R", 0, do_replace, 0);
add_to_sclist(MMOST, "^K", 0, cut_text, 0);
#ifdef NANO_TINY
add_to_sclist(MMAIN, "M-6", 0, copy_text, 0);
add_to_sclist(MMAIN, "M-^", 0, copy_text, 0);
add_to_sclist(MMAIN, "^U", 0, paste_text, 0);
#ifdef ENABLE_SPELLER
add_to_sclist(MMAIN, "^T", 0, do_spell, 0);
add_to_sclist(MMAIN, ISSET(MODERN_BINDINGS) ? "^E" : "^T", 0, do_spell, 0);
#endif
#else
add_to_sclist(MMOST, "M-6", 0, copy_text, 0);
add_to_sclist(MMOST, "M-^", 0, copy_text, 0);
add_to_sclist(MMOST, "^U", 0, paste_text, 0);
add_to_sclist(MMAIN, "^T", 0, do_execute, 0);
add_to_sclist(MMAIN, ISSET(MODERN_BINDINGS) ? "^E" : "^T", 0, do_execute, 0);
#ifdef ENABLE_SPELLER
if (!ISSET(PRESERVE))
add_to_sclist(MEXECUTE, "^S", 0, do_spell, 0);
@ -1206,20 +1296,18 @@ void shortcut_init(void)
add_to_sclist(MMAIN, "^J", '\n', do_justify, 0);
#endif
#ifdef ENABLE_LINTER
add_to_sclist(MMAIN, "M-B", 0, do_linter, 0);
add_to_sclist(MEXECUTE, "^Y", 0, do_linter, 0);
#endif
#ifdef ENABLE_FORMATTER
add_to_sclist(MMAIN, "M-F", 0, do_formatter, 0);
add_to_sclist(MEXECUTE, "^O", 0, do_formatter, 0);
#endif
add_to_sclist(MMAIN, "^C", 0, report_cursor_position, 0);
#ifdef ENABLE_FOLDING
add_to_sclist(MMAIN, "M-[", 0, do_fold_segment, 0);
#endif
add_to_sclist(MMAIN, SLASH_OR_DASH, 0, do_gotolinecolumn, 0);
add_to_sclist(MMAIN, "M-G", 0, do_gotolinecolumn, 0);
add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn, 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);
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "PgDn", KEY_NPAGE, do_page_down, 0);
add_to_sclist(MBROWSER|MHELP, "Bsp", KEY_BACKSPACE, do_page_up, 0);
add_to_sclist(MBROWSER|MHELP, "Sh-Del", SHIFT_DELETE, do_page_up, 0);
@ -1228,26 +1316,23 @@ void shortcut_init(void)
add_to_sclist(MMAIN|MHELP, "^Home", CONTROL_HOME, to_first_line, 0);
add_to_sclist(MMAIN|MHELP, "M-/", 0, to_last_line, 0);
add_to_sclist(MMAIN|MHELP, "^End", CONTROL_END, to_last_line, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "M-B", 0, do_findprevious, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "M-F", 0, do_findnext, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "M-W", 0, do_findnext, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "M-Q", 0, do_findprevious, 0);
#ifdef NANO_TINY
#ifdef ENABLE_LINENUMBERS
add_to_sclist(MMAIN, "M-N", 0, toggle_numbers, 0);
#else
add_to_sclist(MMAIN, "M-B", 0, to_prev_word, 0);
add_to_sclist(MMAIN, "M-N", 0, to_next_word, 0);
#endif
add_to_sclist(MMAIN, "M-D", 0, to_prev_word, 0);
add_to_sclist(MMAIN, "M-F", 0, to_next_word, 0);
#else
add_to_sclist(MMAIN, "M-]", 0, do_find_bracket, 0);
add_to_sclist(MMAIN, "M-A", 0, do_mark, 0);
add_to_sclist(MMAIN, "^6", 0, do_mark, 0);
add_to_sclist(MMAIN, "^^", 0, do_mark, 0);
add_to_sclist(MMOST, "M-6", 0, copy_text, 0);
add_to_sclist(MMOST, "M-^", 0, copy_text, 0);
add_to_sclist(MMAIN, "M-}", 0, do_indent, 0);
add_to_sclist(MMAIN, "", INDENT_KEY, do_indent, 0);
add_to_sclist(MMAIN, "M-{", 0, do_unindent, 0);
add_to_sclist(MMAIN, "Sh-Tab", SHIFT_TAB, do_unindent, 0);
add_to_sclist(MMAIN, "M-:", 0, record_macro, 0);
@ -1259,8 +1344,12 @@ void shortcut_init(void)
add_to_sclist(MMAIN, "^Del", CONTROL_DELETE, chop_next_word, 0);
add_to_sclist(MMAIN, "M-Del", ALT_DELETE, zap_text, 0);
add_to_sclist(MMAIN, "M-Ins", ALT_INSERT, put_or_lift_anchor, 0);
add_to_sclist(MMAIN, "M-Home", ALT_HOME, to_top_row, 0);
add_to_sclist(MMAIN, "M-End", ALT_END, to_bottom_row, 0);
add_to_sclist(MMAIN, "M-PgUp", ALT_PAGEUP, to_prev_anchor, 0);
add_to_sclist(MMAIN, "M-PgDn", ALT_PAGEDOWN, to_next_anchor, 0);
add_to_sclist(MMAIN, "M-\"", 0, put_or_lift_anchor, 0);
add_to_sclist(MMAIN, "M-'", 0, to_next_anchor, 0);
#endif
#ifdef ENABLE_WORDCOMPLETION
add_to_sclist(MMAIN, "^]", 0, complete_a_word, 0);
@ -1268,8 +1357,8 @@ void shortcut_init(void)
#ifdef ENABLE_COMMENT
add_to_sclist(MMAIN, "M-3", 0, do_comment, 0);
#endif
add_to_sclist(MMOST|MBROWSER, "^B", 0, do_left, 0);
add_to_sclist(MMOST|MBROWSER, "^F", 0, do_right, 0);
add_to_sclist(MMOST & ~MMAIN, "^B", 0, do_left, 0);
add_to_sclist(MMOST & ~MMAIN, "^F", 0, do_right, 0);
#ifdef ENABLE_UTF8
if (using_utf8()) {
add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x97\x82", KEY_LEFT, do_left, 0);
@ -1298,12 +1387,8 @@ void shortcut_init(void)
}
add_to_sclist(MMOST, "M-Space", 0, to_prev_word, 0);
add_to_sclist(MMOST, "^Space", 0, to_next_word, 0);
add_to_sclist(MMOST, "^A", 0, do_home, 0);
add_to_sclist(MMOST, "Home", KEY_HOME, do_home, 0);
add_to_sclist(MMOST, "^E", 0, do_end, 0);
add_to_sclist(MMOST, "End", KEY_END, do_end, 0);
add_to_sclist(MMAIN|MBROWSER|MHELP, "^P", 0, do_up, 0);
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\xb4", KEY_UP, do_up, 0);
@ -1364,13 +1449,10 @@ void shortcut_init(void)
add_to_sclist(MMAIN, "M-J", 0, do_full_justify, 0);
add_to_sclist(MEXECUTE, "^J", 0, do_full_justify, 0);
#endif
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
add_to_sclist(MMAIN, "^L", 0, do_center, 0);
#ifndef NANO_TINY
add_to_sclist(MMAIN, "^L", 0, do_cycle, 0);
#endif
if (!ISSET(PRESERVE))
add_to_sclist(MMOST|MBROWSER|MHELP|MYESNO, "^L", 0, full_refresh, 0);
else
add_to_sclist(MMOST|MBROWSER|MYESNO, "^L", 0, full_refresh, 0);
add_to_sclist(MMOST|MBROWSER|MHELP|MYESNO, "^L", 0, full_refresh, 0);
#ifndef NANO_TINY
/* Group of "Appearance" toggles. */
@ -1500,11 +1582,16 @@ void shortcut_init(void)
#ifdef ENABLE_SPELLER
add_to_sclist(MMAIN, "F12", KEY_F(12), do_spell, 0);
#endif
#if defined(ENABLE_EXTRA) && defined(NCURSES_VERSION_PATCH)
add_to_sclist(MMAIN, "M-&", 0, show_curses_version, 0);
#endif
#ifndef NANO_TINY
add_to_sclist((MMOST & ~MMAIN) | MYESNO, "", KEY_CANCEL, do_cancel, 0);
add_to_sclist(MMAIN, "", KEY_CENTER, do_center, 0);
add_to_sclist(MMAIN, "", KEY_SIC, do_insertfile, 0);
/* Catch and ignore bracketed paste marker keys. */
add_to_sclist(MMOST|MBROWSER|MHELP|MYESNO, "", BRACKETED_PASTE_MARKER, do_nothing, 0);
add_to_sclist(MMAIN, "", START_OF_PASTE, suck_up_input_and_paste_it, 0);
add_to_sclist(MMOST, "", START_OF_PASTE, do_nothing, 0);
add_to_sclist(MMOST, "", END_OF_PASTE, do_nothing, 0);
#else
add_to_sclist(MMOST|MBROWSER|MHELP|MYESNO, "", KEY_FRESH, full_refresh, 0);
#endif

View File

@ -1,7 +1,7 @@
/**************************************************************************
* help.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2000-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 2000-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2017 Rishabh Dave *
* Copyright (C) 2014-2019 Benno Schulenberg *
* *
@ -67,8 +67,8 @@ void help_init(void)
htx[2] = NULL;
} else if (currmenu == MREPLACEWITH) {
htx[0] = N_("=== Replacement ===\n\n "
"Type the characters that should replace the characters that "
"you typed at the previous prompt, and press Enter.\n\n");
"Type the characters that should replace what you "
"typed at the previous prompt, and press Enter.\n\n");
htx[1] = N_(" The following function keys "
"are available at this prompt:\n\n");
htx[2] = NULL;
@ -325,7 +325,7 @@ void help_init(void)
void wrap_help_text_into_buffer(void)
{
/* Avoid overtight and overwide paragraphs in the introductory text. */
size_t wrapping_point = ((COLS < 40) ? 40 : (COLS > 74) ? 74 : COLS) - thebar;
size_t wrapping_point = ((COLS < 40) ? 40 : (COLS > 74) ? 74 : COLS) - sidebar;
const char *ptr = start_of_body;
size_t sum = 0;
@ -344,7 +344,7 @@ void wrap_help_text_into_buffer(void)
char *oneline;
if (ptr == end_of_intro)
wrapping_point = ((COLS < 40) ? 40 : COLS) - thebar;
wrapping_point = ((COLS < 40) ? 40 : COLS) - sidebar;
if (ptr < end_of_intro || *(ptr - 1) == '\n') {
length = break_line(ptr, wrapping_point, TRUE);
@ -352,7 +352,7 @@ void wrap_help_text_into_buffer(void)
shim = (*(ptr + length - 1) == ' ') ? 0 : 1;
snprintf(oneline, length + shim, "%s", ptr);
} else {
length = break_line(ptr, ((COLS < 40) ? 22 : COLS - 18) - thebar, TRUE);
length = break_line(ptr, ((COLS < 40) ? 22 : COLS - 18) - sidebar, TRUE);
oneline = nmalloc(length + 5);
snprintf(oneline, length + 5, "\t\t %s", ptr);
}
@ -433,7 +433,7 @@ void show_help(void)
UNSET(WHITESPACE_DISPLAY);
#ifdef ENABLE_LINENUMBERS
editwincols = COLS - thebar;
editwincols = COLS - sidebar;
margin = 0;
#endif
tabsize = 8;
@ -476,18 +476,11 @@ void show_help(void)
#ifndef NANO_TINY
spotlighted = FALSE;
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) {
beep();
continue;
}
#endif
function = interpret(kbinput);
if (function == full_refresh) {
full_refresh();
} else if (ISSET(SHOW_CURSOR) && (function == do_left || function == do_right ||
function == do_up || function == do_down)) {
if (ISSET(SHOW_CURSOR) && (function == do_left || function == do_right ||
function == do_up || function == do_down)) {
function();
} else if (function == do_up || function == do_scroll_up) {
do_scroll_up();
@ -511,9 +504,15 @@ void show_help(void)
get_mouseinput(&dummy_row, &dummy_col, TRUE);
#endif
#ifndef NANO_TINY
} else if (kbinput == KEY_WINCH) {
} else if (kbinput == START_OF_PASTE) {
while (get_kbinput(midwin, BLIND) != END_OF_PASTE)
;
statusline(AHEM, _("Paste is ignored"));
} else if (kbinput == THE_WINDOW_RESIZED) {
; /* Nothing to do. */
#endif
} else if (function == full_refresh) {
full_refresh();
} else if (function == do_exit) {
break;
} else
@ -539,7 +538,7 @@ void show_help(void)
#ifdef ENABLE_LINENUMBERS
margin = was_margin;
editwincols = COLS - margin - thebar;
editwincols = COLS - margin - sidebar;
#endif
tabsize = was_tabsize;
#ifdef ENABLE_COLOR

View File

@ -1,7 +1,7 @@
/**************************************************************************
* history.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2003-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 2003-2011, 2013-2025 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-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2014-2018 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -37,11 +37,17 @@ void to_first_line(void)
void to_last_line(void)
{
openfile->current = openfile->filebot;
openfile->current_x = (inhelp) ? 0 : strlen(openfile->filebot->data);
#ifdef ENABLE_FOLDING
if (openfile->current->folded) {
openfile->current = get_start_of_folded_segment(openfile->current);
openfile->current_x = 0;
} else
#endif
openfile->current_x = (inhelp) ? 0 : strlen(openfile->filebot->data);
openfile->placewewant = xplustabs();
/* Set the last line of the screen as the target for the cursor. */
openfile->current_y = editwinrows - 1;
openfile->cursor_row = editwinrows - 1;
refresh_needed = TRUE;
#ifdef ENABLE_COLOR
@ -112,6 +118,15 @@ void set_proper_index_and_pww(size_t *leftedge, size_t target, bool forward)
openfile->placewewant = *leftedge + target;
}
/* Move the cursor position on the current line to the desired column */
void move_cursor_to_proper_column(void)
{
size_t leftedge;
size_t target_column;
get_edge_and_target(&leftedge, &target_column);
set_proper_index_and_pww(&leftedge, target_column, TRUE);
}
/* Move up almost one screenful. */
void do_page_up(void)
{
@ -124,7 +139,7 @@ void do_page_up(void)
if (ISSET(JUMPY_SCROLLING)) {
openfile->current = openfile->edittop;
leftedge = openfile->firstcolumn;
openfile->current_y = 0;
openfile->cursor_row = 0;
target_column = 0;
} else
#endif
@ -156,7 +171,7 @@ void do_page_down(void)
if (ISSET(JUMPY_SCROLLING)) {
openfile->current = openfile->edittop;
leftedge = openfile->firstcolumn;
openfile->current_y = 0;
openfile->cursor_row = 0;
target_column = 0;
} else
#endif
@ -176,6 +191,61 @@ void do_page_down(void)
refresh_needed = TRUE;
}
#ifndef NANO_TINY
/* Place the cursor on the first row in the viewport. */
void to_top_row(void)
{
size_t leftedge, offset;
get_edge_and_target(&leftedge, &offset);
openfile->current = openfile->edittop;
leftedge = openfile->firstcolumn;
set_proper_index_and_pww(&leftedge, offset, FALSE);
refresh_needed = (openfile->mark != NULL);
}
/* Place the cursor on the last row in the viewport, when possible. */
void to_bottom_row(void)
{
size_t leftedge, offset;
get_edge_and_target(&leftedge, &offset);
openfile->current = openfile->edittop;
leftedge = openfile->firstcolumn;
go_forward_chunks(editwinrows - 1, &openfile->current, &leftedge);
set_proper_index_and_pww(&leftedge, offset, TRUE);
refresh_needed = (openfile->mark != NULL);
}
/* Put the cursor line at the center, then the top, then the bottom. */
void do_cycle(void)
{
if (cycling_aim == 0)
adjust_viewport(CENTERING);
else {
openfile->cursor_row = (cycling_aim == 1) ? 0 : editwinrows - 1;
adjust_viewport(STATIONARY);
}
cycling_aim = (cycling_aim + 1) % 3;
draw_all_subwindows();
full_refresh();
}
/* Scroll the line with the cursor to the center of the screen. */
void do_center(void)
{
do_cycle(); /* The main loop has set 'cycling_aim' to zero. */
}
#endif /* !NANO_TINY */
#ifdef ENABLE_JUSTIFY
/* Move to the first beginning of a paragraph before the current line. */
void do_para_begin(linestruct **line)
@ -235,19 +305,29 @@ void to_para_end(void)
void to_prev_block(void)
{
linestruct *was_current = openfile->current;
linestruct *line_step = get_prev_visible_line(openfile->current);
bool is_text = FALSE, seen_text = FALSE;
/* Skip backward until first blank line after some nonblank line(s). */
while (openfile->current->prev != NULL && (!seen_text || is_text)) {
openfile->current = openfile->current->prev;
while (line_step != NULL && (!seen_text || is_text)) {
openfile->current = line_step;
line_step = get_prev_visible_line(line_step);
#ifdef ENABLE_FOLDING
/* Skip over the visibly drawn line of the folded segment */
if (openfile->current->folded)
continue;
#endif
is_text = !white_string(openfile->current->data);
seen_text = seen_text || is_text;
}
/* Step forward one line again if we passed text but this line is blank. */
if (seen_text && openfile->current->next != NULL &&
white_string(openfile->current->data))
openfile->current = openfile->current->next;
line_step = get_next_visible_line(openfile->current);
if (seen_text && line_step != NULL &&
white_string(openfile->current->data)) {
openfile->current = line_step;
line_step = get_next_visible_line(line_step);
}
openfile->current_x = 0;
edit_redraw(was_current, CENTERING);
@ -257,12 +337,19 @@ void to_prev_block(void)
void to_next_block(void)
{
linestruct *was_current = openfile->current;
linestruct *line_step = get_next_visible_line(openfile->current);
bool is_white = white_string(openfile->current->data);
bool seen_white = is_white;
/* Skip forward until first nonblank line after some blank line(s). */
while (openfile->current->next != NULL && (!seen_white || is_white)) {
openfile->current = openfile->current->next;
while (line_step != NULL && (!seen_white || is_white)) {
openfile->current = line_step;
line_step = get_next_visible_line(line_step);
#ifdef ENABLE_FOLDING
/* Skip over the visibly drawn line of the folded segment */
if (openfile->current->folded)
continue;
#endif
is_white = white_string(openfile->current->data);
seen_white = seen_white || is_white;
}
@ -274,19 +361,35 @@ void to_next_block(void)
#endif
}
/* Move to the previous word. */
void do_prev_word(void)
/* Move to the previous word.
* When allow_folded is true, will move to previous word even if inside
* a folded segment. */
void do_prev_word(bool allow_folded)
{
bool punctuation_as_letters = ISSET(WORD_BOUNDS);
bool seen_a_word = FALSE, step_forward = FALSE;
#ifdef ENABLE_FOLDING
if (!allow_folded && openfile->current->folded) {
openfile->current = get_prev_visible_line(openfile->current);
openfile->current_x = strlen(openfile->current->data);
}
#endif
/* Move backward until we pass over the start of a word. */
while (TRUE) {
/* If at the head of a line, move to the end of the preceding one. */
if (openfile->current_x == 0) {
if (openfile->current->prev == NULL)
break;
openfile->current = openfile->current->prev;
#ifdef ENABLE_FOLDING
if (!allow_folded) {
openfile->current = get_prev_visible_line(openfile->current);
if (openfile->current->folded)
openfile->current = openfile->current->prev;
} else
#endif
openfile->current = openfile->current->prev;
openfile->current_x = strlen(openfile->current->data);
}
@ -315,11 +418,13 @@ void do_prev_word(void)
/* Move one character forward again to sit on the start of the word. */
openfile->current_x = step_right(openfile->current->data,
openfile->current_x);
UNFOLD_SEGMENT(openfile->current);
}
/* Move to the next word. If after_ends is TRUE, stop at the ends of words
* instead of at their beginnings. Return TRUE if we started on a word. */
bool do_next_word(bool after_ends)
* instead of at their beginnings. If allow_folded is true, go to next word
* even if it's inside a folded segment. Return TRUE if we started on a word. */
bool do_next_word(bool after_ends, bool allow_folded)
{
bool punctuation_as_letters = ISSET(WORD_BOUNDS);
bool started_on_word = is_word_char(openfile->current->data +
@ -329,6 +434,12 @@ bool do_next_word(bool after_ends)
bool seen_word = started_on_word;
#endif
#ifdef ENABLE_FOLDING
if (!allow_folded & openfile->current->folded) {
openfile->current = get_next_visible_line(openfile->current);
openfile->current_x = 0;
}
#endif
/* Move forward until we reach the start of a word. */
while (TRUE) {
/* If at the end of a line, move to the beginning of the next one. */
@ -336,7 +447,18 @@ bool do_next_word(bool after_ends)
/* When at end of file, stop. */
if (openfile->current->next == NULL)
break;
openfile->current = openfile->current->next;
#ifdef ENABLE_FOLDING
if (!allow_folded) {
openfile->current = get_next_visible_line(openfile->current);
if (openfile->current->folded) {
/* get_next_visible_line() gives the start of a folded segment,
* so skip to the end. */
openfile->current = get_end_of_folded_segment(openfile->current);
openfile->current = openfile->current->next;
}
} else
#endif
openfile->current = openfile->current->next;
openfile->current_x = 0;
seen_space = TRUE;
} else {
@ -376,6 +498,8 @@ bool do_next_word(bool after_ends)
}
}
UNFOLD_SEGMENT(openfile->current);
return started_on_word;
}
@ -384,7 +508,7 @@ void to_prev_word(void)
{
linestruct *was_current = openfile->current;
do_prev_word();
do_prev_word(DISALLOW_FOLDED);
edit_redraw(was_current, FLOWING);
}
@ -395,7 +519,7 @@ void to_next_word(void)
{
linestruct *was_current = openfile->current;
do_next_word(ISSET(AFTER_ENDS));
do_next_word(ISSET(AFTER_ENDS), DISALLOW_FOLDED);
edit_redraw(was_current, FLOWING);
}
@ -413,6 +537,11 @@ void do_home(void)
size_t leftedge = 0;
size_t left_x = 0;
#ifdef ENABLE_FOLDING
if (openfile->current->folded)
return;
#endif
if (ISSET(SOFTWRAP)) {
leftedge = leftedge_for(was_column, openfile->current);
left_x = proper_x(openfile->current, &leftedge, FALSE, leftedge, NULL);
@ -470,6 +599,11 @@ void do_end(void)
size_t line_len = strlen(openfile->current->data);
bool moved_off_chunk = TRUE;
#ifdef ENABLE_FOLDING
if (openfile->current->folded)
return;
#endif
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
bool kickoff = TRUE;
@ -526,7 +660,8 @@ void do_up(void)
set_proper_index_and_pww(&leftedge, target_column, FALSE);
if (openfile->current_y == 0 && !ISSET(JUMPY_SCROLLING))
if (openfile->cursor_row == 0 && !ISSET(JUMPY_SCROLLING) &&
(tabsize < editwincols || !ISSET(SOFTWRAP)))
edit_scroll(BACKWARD);
else
edit_redraw(was_current, FLOWING);
@ -549,7 +684,8 @@ void do_down(void)
set_proper_index_and_pww(&leftedge, target_column, TRUE);
if (openfile->current_y == editwinrows - 1 && !ISSET(JUMPY_SCROLLING))
if (openfile->cursor_row == editwinrows - 1 && !ISSET(JUMPY_SCROLLING) &&
(tabsize < editwincols || !ISSET(SOFTWRAP)))
edit_scroll(FORWARD);
else
edit_redraw(was_current, FLOWING);
@ -566,7 +702,7 @@ void do_scroll_up(void)
if (openfile->edittop->prev == NULL && openfile->firstcolumn == 0)
return;
if (openfile->current_y == editwinrows - 1)
if (openfile->cursor_row == editwinrows - 1)
do_up();
if (editwinrows > 1)
@ -576,7 +712,7 @@ void do_scroll_up(void)
/* Scroll down one line or chunk without moving the cursor textwise. */
void do_scroll_down(void)
{
if (openfile->current_y == 0)
if (openfile->cursor_row == 0)
do_down();
if (editwinrows > 1 && (openfile->edittop->next != NULL
@ -587,14 +723,6 @@ void do_scroll_down(void)
))
edit_scroll(FORWARD);
}
/* Scroll the line with the cursor to the center of the screen. */
void do_center(void)
{
adjust_viewport(CENTERING);
draw_all_subwindows();
full_refresh();
}
#endif /* !NANO_TINY || ENABLE_HELP */
/* Move left one character. */
@ -612,7 +740,7 @@ void do_left(void)
openfile->current_x);
#endif
} else if (openfile->current != openfile->filetop) {
openfile->current = openfile->current->prev;
openfile->current = get_prev_visible_line(openfile->current);
openfile->current_x = strlen(openfile->current->data);
}
@ -624,6 +752,13 @@ void do_right(void)
{
linestruct *was_current = openfile->current;
#ifdef ENABLE_FOLDING
if (openfile->current->folded) {
openfile->current = get_next_visible_line(openfile->current);
if (openfile->current == NULL)
openfile->current = was_current;
} else
#endif
if (openfile->current->data[openfile->current_x] != '\0') {
openfile->current_x = step_right(openfile->current->data,
openfile->current_x);
@ -634,7 +769,7 @@ void do_right(void)
openfile->current_x);
#endif
} else if (openfile->current != openfile->filebot) {
openfile->current = openfile->current->next;
openfile->current = get_next_visible_line(openfile->current);
openfile->current_x = 0;
}

View File

@ -1,7 +1,7 @@
/**************************************************************************
* nano.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2014-2022 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -78,6 +78,9 @@ linestruct *make_new_node(linestruct *prevnode)
#ifndef NANO_TINY
newnode->has_anchor = FALSE;
#endif
#ifdef ENABLE_FOLDING
newnode->folded = FALSE;
#endif
return newnode;
}
@ -117,6 +120,7 @@ void delete_node(linestruct *line)
/* Disconnect a node from a linked list of linestructs and delete it. */
void unlink_node(linestruct *line)
{
UNFOLD_SEGMENT(line);
if (line->prev != NULL)
line->prev->next = line->next;
if (line->next != NULL)
@ -156,6 +160,9 @@ linestruct *copy_node(const linestruct *src)
#ifndef NANO_TINY
dst->has_anchor = src->has_anchor;
#endif
#ifdef ENABLE_FOLDING
dst->folded = src->folded;
#endif
return dst;
}
@ -337,18 +344,8 @@ void emergency_save(const char *filename)
if (*targetname == '\0')
fprintf(stderr, _("\nToo many .save files\n"));
else if (write_file(targetname, NULL, SPECIAL, OVERWRITE, NONOTES)) {
else if (write_file(targetname, NULL, SPECIAL, EMERGENCY, NONOTES))
fprintf(stderr, _("\nBuffer written to %s\n"), targetname);
#if !defined(NANO_TINY) && defined(HAVE_CHMOD) && defined(HAVE_CHOWN)
/* Try to chmod/chown the saved file to the values of the original file,
* but ignore any failure as we are in a hurry to get out. */
if (openfile->statinfo) {
IGNORE_CALL_RESULT(chmod(targetname, openfile->statinfo->st_mode));
IGNORE_CALL_RESULT(chown(targetname, openfile->statinfo->st_uid,
openfile->statinfo->st_gid));
}
#endif
}
free(targetname);
free(plainname);
@ -420,8 +417,9 @@ void window_init(void)
midwin = newwin(editwinrows, COLS, 0, 0);
footwin = newwin(1, COLS, LINES - 1, 0);
} else {
int toprows = ((ISSET(EMPTY_LINE) && LINES > 6) ? 2 : 1);
int bottomrows = ((ISSET(NO_HELP) || LINES < 6) ? 1 : 3);
int minimum = (ISSET(ZERO) ? 3 : ISSET(MINIBAR) ? 4 : 5);
int toprows = ((ISSET(EMPTY_LINE) && LINES > minimum) ? 2 : 1);
int bottomrows = ((ISSET(NO_HELP) || LINES < minimum) ? 1 : 3);
if (ISSET(MINIBAR) || ISSET(ZERO))
toprows = 0;
@ -583,8 +581,7 @@ void usage(void)
N_("Which other characters are word parts"));
#endif
#ifdef ENABLE_COLOR
if (!ISSET(RESTRICTED))
print_opt(_("-Y <name>"), _("--syntax=<name>"),
print_opt(_("-Y <name>"), _("--syntax=<name>"),
N_("Syntax definition to use for coloring"));
#endif
#ifndef NANO_TINY
@ -651,14 +648,19 @@ void usage(void)
#ifndef NANO_TINY
print_opt("-y", "--afterends", N_("Make Ctrl+Right stop at word ends"));
#endif
#ifdef ENABLE_COLOR
print_opt("-z", "--listsyntaxes", N_("List the names of available syntaxes"));
#endif
#ifdef HAVE_LIBMAGIC
print_opt("-!", "--magic", N_("Also try magic to determine syntax"));
#endif
#ifndef NANO_TINY
print_opt("-@", "--colonparsing", N_("Accept 'filename:linenumber' notation"));
print_opt("-%", "--stateflags", N_("Show some states on the title bar"));
print_opt("-_", "--minibar", N_("Show a feedback bar at the bottom"));
print_opt("-0", "--zero", N_("Hide all bars, use whole terminal"));
#endif
print_opt("-/", "--modernbindings", N_("Use better-known key bindings"));
}
/* Display the version number of this nano, a copyright notice, some contact
@ -672,7 +674,7 @@ void version(void)
#endif
#ifndef NANO_TINY
/* TRANSLATORS: The %s is the year of the latest release. */
printf(_(" (C) %s the Free Software Foundation and various contributors\n"), "2023");
printf(_(" (C) %s the Free Software Foundation and various contributors\n"), "2025");
#endif
printf(_(" Compiled options:"));
@ -803,6 +805,27 @@ void version(void)
printf("\n");
}
#ifdef ENABLE_COLOR
/* List the names of the available syntaxes. */
void list_syntax_names(void)
{
int width = 0;
printf(_("Available syntaxes:\n"));
for (syntaxtype *sntx = syntaxes; sntx != NULL; sntx = sntx->next) {
if (width > 45) {
printf("\n");
width = 0;
}
printf(" %s", sntx->name);
width += wideness(sntx->name, 45 * 4);
}
printf("\n");
}
#endif
/* Register that Ctrl+C was pressed during some system call. */
void make_a_note(int signal)
{
@ -870,9 +893,9 @@ bool scoop_stdin(void)
/* Set up a signal handler so that ^C will stop the reading. */
install_handler_for_Ctrl_C();
/* Read the input into a new buffer. */
/* Read the input into a new buffer, undoably. */
make_new_buffer();
read_file(stream, 0, "stdin", TRUE);
read_file(stream, 0, "stdin", FALSE);
#ifdef ENABLE_COLOR
find_and_prime_applicable_syntax();
#endif
@ -1046,10 +1069,10 @@ void regenerate_screen(void)
endwin();
refresh();
thebar = (ISSET(INDICATOR) && LINES > 5 && COLS > 9) ? 1 : 0;
sidebar = (ISSET(INDICATOR) && LINES > 5 && COLS > 9) ? 1 : 0;
bardata = nrealloc(bardata, LINES * sizeof(int));
editwincols = COLS - margin - thebar;
editwincols = COLS - margin - sidebar;
/* Put the terminal in the desired state again, and
* recreate the subwindows with their (new) sizes. */
@ -1059,7 +1082,8 @@ void regenerate_screen(void)
/* If we have an open buffer, redraw the contents of the subwindows. */
if (openfile) {
ensure_firstcolumn_is_aligned();
draw_all_subwindows();
if (currmenu & ~(MBROWSER|MWHEREISFILE|MGOTODIR))
draw_all_subwindows();
}
}
@ -1077,7 +1101,7 @@ void toggle_this(int flag)
draw_all_subwindows();
return;
case NO_HELP:
if (LINES < 6) {
if (LINES < (ISSET(ZERO) ? 3 : ISSET(MINIBAR) ? 4 : 5)) {
statusline(AHEM, _("Too tiny"));
TOGGLE(flag);
return;
@ -1086,9 +1110,12 @@ void toggle_this(int flag)
draw_all_subwindows();
break;
case CONSTANT_SHOW:
if (ISSET(ZERO) || LINES == 1) {
statusline(AHEM, _("Not possible"));
if (LINES == 1) {
statusline(AHEM, _("Too tiny"));
TOGGLE(flag);
} else if (ISSET(ZERO)) {
SET(CONSTANT_SHOW);
toggle_this(ZERO);
} else if (!ISSET(MINIBAR))
wipe_statusbar();
return;
@ -1259,7 +1286,7 @@ void confirm_margin(void)
bool keep_focus = (margin > 0) && focusing;
margin = needed_margin;
editwincols = COLS - margin - thebar;
editwincols = COLS - margin - sidebar;
#ifndef NANO_TINY
/* Ensure a proper starting column for the first screen row. */
@ -1329,13 +1356,11 @@ int do_mouse(void)
/* If the click was in the edit window, put the cursor in that spot. */
if (wmouse_trafo(midwin, &click_row, &click_col, FALSE)) {
linestruct *current_save = openfile->current;
ssize_t row_count = click_row - openfile->current_y;
linestruct *was_current = openfile->current;
ssize_t row_count = click_row - openfile->cursor_row;
size_t leftedge;
#ifndef NANO_TINY
size_t current_x_save = openfile->current_x;
bool sameline = (click_row == openfile->current_y);
/* Whether the click was on the row where the cursor is. */
size_t was_x = openfile->current_x;
if (ISSET(SOFTWRAP))
leftedge = leftedge_for(xplustabs(), openfile->current);
@ -1353,9 +1378,8 @@ int do_mouse(void)
actual_last_column(leftedge, click_col));
#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) {
/* Clicking there where the cursor is toggles the mark. */
if (row_count == 0 && openfile->current_x == was_x) {
do_mark();
if (ISSET(STATEFLAGS))
titlebar(NULL);
@ -1364,7 +1388,7 @@ int do_mouse(void)
/* The cursor moved; clean the cutbuffer on the next cut. */
keep_cutbuffer = FALSE;
edit_redraw(current_save, CENTERING);
edit_redraw(was_current, CENTERING);
}
/* No more handling is needed. */
@ -1422,25 +1446,25 @@ void suck_up_input_and_paste_it(void)
linestruct *was_cutbuffer = cutbuffer;
linestruct *line = make_new_node(NULL);
size_t index = 0;
int input = ERR;
line->data = copy_of("");
cutbuffer = line;
while (bracketed_paste) {
int input = get_kbinput(midwin, BLIND);
while (TRUE) {
input = get_kbinput(midwin, BLIND);
if (input == '\r' || input == '\n') {
if ((0x20 <= input && input <= 0xFF && input != DEL_CODE) || input == '\t') {
line->data = nrealloc(line->data, index + 2);
line->data[index++] = (char)input;
line->data[index] = '\0';
} else if (input == '\r' || input == '\n') {
line->next = make_new_node(line);
line = line->next;
line->data = copy_of("");
index = 0;
} else if ((0x20 <= input && input <= 0xFF && input != DEL_CODE) ||
input == '\t') {
line->data = nrealloc(line->data, index + 2);
line->data[index++] = (char)input;
line->data[index] = '\0';
} else if (input != BRACKETED_PASTE_MARKER)
beep();
} else
break;
}
if (ISSET(VIEW_MODE))
@ -1448,6 +1472,9 @@ void suck_up_input_and_paste_it(void)
else
paste_text();
if (input != END_OF_PASTE)
statusline(ALERT, _("Flawed paste"));
free_lines(cutbuffer);
cutbuffer = was_cutbuffer;
}
@ -1461,9 +1488,10 @@ void inject(char *burst, size_t count)
#ifndef NANO_TINY
size_t original_row = 0;
size_t old_amount = 0;
UNFOLD_SEGMENT(thisline);
if (ISSET(SOFTWRAP)) {
if (openfile->current_y == editwinrows - 1)
if (openfile->cursor_row == editwinrows - 1)
original_row = chunk_for(xplustabs(), thisline);
old_amount = extra_chunks_in(thisline);
}
@ -1491,10 +1519,6 @@ void inject(char *burst, size_t count)
strncpy(thisline->data + openfile->current_x, burst, count);
#ifndef NANO_TINY
/* When the mark is to the right of the cursor, compensate its position. */
if (thisline == openfile->mark && openfile->current_x < openfile->mark_x)
openfile->mark_x += count;
/* When the cursor is on the top row and not on the first chunk
* of a line, adding text there might change the preceding chunk
* and thus require an adjustment of firstcolumn. */
@ -1502,19 +1526,29 @@ void inject(char *burst, size_t count)
ensure_firstcolumn_is_aligned();
refresh_needed = TRUE;
}
/* When the mark is to the right of the cursor, compensate its position. */
if (thisline == openfile->mark && openfile->current_x < openfile->mark_x)
openfile->mark_x += count;
#endif
/* If text was added to the magic line, create a new magic line. */
if (thisline == openfile->filebot && !ISSET(NO_NEWLINES)) {
new_magicline();
if (margin > 0)
refresh_needed = TRUE;
}
openfile->current_x += count;
openfile->totsize += mbstrlen(burst);
set_modified();
/* If text was added to the magic line, create a new magic line. */
if (thisline == openfile->filebot && !ISSET(NO_NEWLINES)) {
new_magicline();
#ifdef ENABLE_COLOR
if (margin || (openfile->syntax && openfile->syntax->multiscore))
#else
if (margin)
#endif
if (openfile->cursor_row < editwinrows - 1)
update_line(thisline->next, 0);
}
#ifndef NANO_TINY
update_undo(ADD);
#endif
@ -1524,20 +1558,20 @@ void inject(char *burst, size_t count)
do_wrap();
#endif
openfile->placewewant = xplustabs();
#ifndef NANO_TINY
/* 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) && (extra_chunks_in(openfile->current) != old_amount ||
(openfile->current_y == editwinrows - 1 &&
chunk_for(xplustabs(), openfile->current) > original_row))) {
(openfile->cursor_row == editwinrows - 1 &&
chunk_for(openfile->placewewant, openfile->current) > original_row))) {
refresh_needed = TRUE;
focusing = FALSE;
}
#endif
openfile->placewewant = xplustabs();
#ifdef ENABLE_COLOR
if (!refresh_needed)
check_the_multis(openfile->current);
@ -1570,7 +1604,7 @@ void process_a_keystroke(void)
lastmessage = VACUUM;
#ifndef NANO_TINY
if (input == KEY_WINCH)
if (input == THE_WINDOW_RESIZED)
return;
#endif
#ifdef ENABLE_MOUSE
@ -1621,6 +1655,11 @@ void process_a_keystroke(void)
depth = 0;
}
#ifndef NANO_TINY
if (function != do_cycle)
cycling_aim = 0;
#endif
if (!function) {
pletion_line = NULL;
keep_cutbuffer = FALSE;
@ -1640,9 +1679,9 @@ void process_a_keystroke(void)
give_a_hint = FALSE;
/* When not cutting or copying text, drop the cutbuffer the next time. */
if (function != cut_text) {
if (function != cut_text && function != copy_text) {
#ifndef NANO_TINY
if (function != copy_text && function != zap_text)
if (function != zap_text)
#endif
keep_cutbuffer = FALSE;
}
@ -1692,9 +1731,6 @@ void process_a_keystroke(void)
} else if (openfile->current != was_current)
also_the_last = FALSE;
if (bracketed_paste)
suck_up_input_and_paste_it();
if (ISSET(STATEFLAGS) && openfile->mark != was_mark)
titlebar(NULL);
#endif
@ -1774,6 +1810,10 @@ int main(int argc, char **argv)
{"nowrap", 0, NULL, 'w'},
#endif
{"nohelp", 0, NULL, 'x'},
#ifdef ENABLE_COLOR
{"listsyntaxes", 0, NULL, 'z'},
#endif
{"modernbindings", 0, NULL, '/'},
#ifndef NANO_TINY
{"smarthome", 0, NULL, 'A'},
{"backup", 0, NULL, 'B'},
@ -1800,6 +1840,7 @@ int main(int argc, char **argv)
{"indicator", 0, NULL, 'q'},
{"unix", 0, NULL, 'u'},
{"afterends", 0, NULL, 'y'},
{"colonparsing", 0, NULL, '@'},
{"stateflags", 0, NULL, '%'},
{"minibar", 0, NULL, '_'},
{"zero", 0, NULL, '0'},
@ -1848,8 +1889,8 @@ int main(int argc, char **argv)
if (*(tail(argv[0])) == 'r')
SET(RESTRICTED);
while ((optchr = getopt_long(argc, argv, "ABC:DEFGHIJ:KLMNOPQ:RS$T:UVWX:Y:Z"
"abcdef:ghijklmno:pqr:s:tuvwxy!%_0", long_options, NULL)) != -1) {
while ((optchr = getopt_long(argc, argv, "ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Z"
"abcdef:ghijklmno:pqr:s:tuvwxyz!@%_0/", long_options, NULL)) > 0) {
switch (optchr) {
#ifndef NANO_TINY
case 'A':
@ -1935,7 +1976,6 @@ int main(int argc, char **argv)
break;
#ifndef NANO_TINY
case 'S':
case '$': /* Deprecated; remove in 2024. */
SET(SOFTWRAP);
break;
case 'T':
@ -2082,12 +2122,23 @@ int main(int argc, char **argv)
SET(AFTER_ENDS);
break;
#endif
#ifdef ENABLE_COLOR
case 'z':
if (!ignore_rcfiles)
do_rcfiles();
if (syntaxes)
list_syntax_names();
exit(0);
#endif
#ifdef HAVE_LIBMAGIC
case '!':
SET(USE_MAGIC);
break;
#endif
#ifndef NANO_TINY
case '@':
SET(COLON_PARSING);
break;
case '%':
SET(STATEFLAGS);
break;
@ -2098,6 +2149,9 @@ int main(int argc, char **argv)
SET(ZERO);
break;
#endif
case '/':
SET(MODERN_BINDINGS);
break;
default:
printf(_("Type '%s -h' for a list of available options.\n"), argv[0]);
exit(1);
@ -2204,9 +2258,7 @@ 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 == ' ' || *alt_speller == '\t'))
memmove(alt_speller, alt_speller + 1, strlen(alt_speller));
strip_leading_blanks_from(alt_speller);
#endif
/* If an rcfile undid the default setting, copy it to the new flag. */
@ -2244,6 +2296,10 @@ int main(int argc, char **argv)
if (ISSET(RAW_SEQUENCES))
UNSET(USE_MOUSE);
/* When --modernbindings is used, ^Q and ^S need to be functional. */
if (ISSET(MODERN_BINDINGS))
UNSET(PRESERVE);
/* When suppressing title bar or minibar, suppress also the help lines. */
if (ISSET(ZERO))
SET(NO_HELP);
@ -2336,6 +2392,9 @@ int main(int argc, char **argv)
whitelen[1] = 1;
}
}
/* Initialize a special stash for something typed at the Execute prompt. */
foretext = copy_of("");
#endif /* !NANO_TINY */
/* Initialize the search string. */
@ -2375,10 +2434,10 @@ int main(int argc, char **argv)
curs_set(0);
#ifndef NANO_TINY
thebar = (ISSET(INDICATOR) && LINES > 5 && COLS > 9) ? 1 : 0;
sidebar = (ISSET(INDICATOR) && LINES > 5 && COLS > 9) ? 1 : 0;
bardata = nrealloc(bardata, LINES * sizeof(int));
#endif
editwincols = COLS - thebar;
editwincols = COLS - sidebar;
/* Set up the signal handlers. */
signal_init();
@ -2416,6 +2475,8 @@ int main(int argc, char **argv)
altup = get_keycode("kUP3", ALT_UP);
altdown = get_keycode("kDN3", ALT_DOWN);
althome = get_keycode("kHOM3", ALT_HOME);
altend = get_keycode("kEND3", ALT_END);
altpageup = get_keycode("kPRV3", ALT_PAGEUP);
altpagedown = get_keycode("kNXT3", ALT_PAGEDOWN);
altinsert = get_keycode("kIC3", ALT_INSERT);
@ -2425,10 +2486,17 @@ int main(int argc, char **argv)
shiftaltright = get_keycode("kRIT4", SHIFT_ALT_RIGHT);
shiftaltup = get_keycode("kUP4", SHIFT_ALT_UP);
shiftaltdown = get_keycode("kDN4", SHIFT_ALT_DOWN);
/* Tell ncurses to transform bracketed-paste sequences into keycodes. */
define_key("\e[200~", START_OF_PASTE);
define_key("\e[201~", END_OF_PASTE);
#endif
mousefocusin = get_keycode("kxIN", FOCUS_IN);
mousefocusout = get_keycode("kxOUT", FOCUS_OUT);
/* Disable the type-ahead checking that ncurses normally does. */
typeahead(-1);
#ifdef HAVE_SET_ESCDELAY
/* Tell ncurses to pass the Esc key quickly. */
set_escdelay(50);
@ -2486,21 +2554,32 @@ int main(int argc, char **argv)
#endif
{
char *filename = argv[optind++];
char *colon = filename + (*filename ? 1 : 0);
#ifndef NANO_TINY
struct stat fileinfo;
/* Search the filename for a colon. If the colon is preceded by
* a backslash, elide the backslash and skip the colon. If there
* is a valid number after the colon, chop colon and number off.
/* If the filename contains a colon and this file does not exist,
* then check if the filename ends with digits preceded by a colon
* (possibly preceded by more digits and a colon). If there is or
* are such trailing numbers, chop the colons plus numbers off.
* The number is later used to place the cursor on that line. */
while ((colon = strchr(colon, ':'))) {
if (*(colon - 1) == '\\')
memmove(colon - 1, colon, strlen(colon) + 1);
else if (parse_line_column(colon + 1, &givenline, &givencol))
*colon = '\0';
else
++colon;
if (ISSET(COLON_PARSING) && !givenline && strchr(filename, ':') &&
!givencol && stat(filename, &fileinfo) < 0) {
char *coda = filename + strlen(filename);
maybe_two:
while (--coda > filename + 1 && ('0' <= *coda && *coda <= '9'))
;
if (*coda == ':' && ('0' <= *(coda + 1) && *(coda + 1) <= '9')) {
*coda = '\0';
if (stat(filename, &fileinfo) < 0) {
*coda = ':';
/* If this was the first colon, look for a second one. */
if (!strchr(coda + 1, ':'))
goto maybe_two;
} else if (!parse_line_column(coda + 1, &givenline, &givencol))
die(_("Invalid number\n"));
}
}
#endif
if (!open_buffer(filename, TRUE))
continue;
}
@ -2612,6 +2691,16 @@ int main(int argc, char **argv)
as_an_at = TRUE;
#if defined(ENABLE_UTF8) && !defined(NANO_TINY)
#define byte(n) (unsigned char)openfile->current->data[n]
/* Tell the user when the cursor sits on a BOM. */
if (openfile->current_x == 0 && byte(0) == 0xEF && byte(1) == 0xBB &&
byte(2) == 0xBF && using_utf8()) {
statusline(NOTICE, _("Byte Order Mark"));
set_blankdelay_to_one();
}
#endif
if ((refresh_needed && LINES > 1) || (LINES == 1 && lastmessage <= HUSH))
edit_refresh();
else
@ -2621,7 +2710,7 @@ int main(int argc, char **argv)
/* In barless mode, either redraw a relevant status message,
* or overwrite a minor, redundant one. */
if (ISSET(ZERO) && lastmessage > HUSH) {
if (openfile->current_y == editwinrows - 1 && LINES > 1) {
if (openfile->cursor_row == editwinrows - 1 && LINES > 1) {
edit_scroll(FORWARD);
wnoutrefresh(midwin);
}

View File

@ -1,7 +1,7 @@
/**************************************************************************
* prompt.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2016, 2018, 2020, 2022 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -261,7 +261,7 @@ void absorb_character(int input, functionptrtype function)
* Apart from that, only accept input when not in restricted mode, or when
* not at the "Write File" prompt, or when there is no filename yet. */
if (!function) {
if (input < 0x20 || input > 0xFF || meta_key)
if ((input < 0x20 && input != '\t') || meta_key || input > 0xFF)
beep();
else if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
openfile->filename[0] == '\0') {
@ -392,6 +392,7 @@ void draw_the_promptbar(void)
/* Place the cursor at the right spot. */
wmove(footwin, 0, column - the_page);
wnoutrefresh(footwin);
}
@ -425,6 +426,9 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
size_t fragment_length = 0;
/* The length of the fragment that the user tries to tab complete. */
#endif
#endif
#ifndef NANO_TINY
bool bracketed_paste = FALSE;
#endif
const keystruct *shortcut;
functionptrtype function;
@ -441,14 +445,16 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
#ifndef NANO_TINY
/* If the window size changed, go reformat the prompt string. */
if (input == KEY_WINCH) {
if (input == THE_WINDOW_RESIZED) {
refresh_func(); /* Only needed when in file browser. */
*actual = KEY_WINCH;
*actual = THE_WINDOW_RESIZED;
#ifdef ENABLE_HISTORIES
free(stored_string);
#endif
return NULL;
}
if (input == START_OF_PASTE || input == END_OF_PASTE)
bracketed_paste = (input == START_OF_PASTE);
#endif
#ifdef ENABLE_MOUSE
/* For a click on a shortcut, read in the resulting keycode. */
@ -461,10 +467,23 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
/* Check for a shortcut in the current list. */
shortcut = get_shortcut(input);
function = (shortcut ? shortcut->func : NULL);
#ifndef NANO_TINY
/* Tabs in an external paste are not commands. */
if (input == '\t' && bracketed_paste)
function = NULL;
#endif
/* When it's a normal character, add it to the answer. */
absorb_character(input, function);
#ifndef NANO_TINY
/* Ignore any commands inside an external paste. */
if (bracketed_paste) {
if (function && function != do_nothing)
beep();
continue;
}
#endif
if (function == do_cancel || function == do_enter)
break;
@ -537,6 +556,11 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
else if (function && !handle_editing(function)) {
/* When it's a permissible shortcut, run it and done. */
if (!ISSET(VIEW_MODE) || !changes_something(function)) {
#ifndef NANO_TINY
/* When invoking a tool at the Execute prompt, stash an "answer". */
if (currmenu == MEXECUTE)
foretext = mallocstrcpy(foretext, answer);
#endif
function();
break;
} else
@ -548,6 +572,11 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
#endif
}
#ifndef NANO_TINY
/* When an external command was run, clear a possibly stashed answer. */
if (currmenu == MEXECUTE && function == do_enter)
*foretext = '\0';
#endif
#ifdef ENABLE_HISTORIES
/* If the history pointer was moved, point it at the bottom again. */
if (stored_string != NULL) {
@ -597,13 +626,17 @@ int do_prompt(int menu, const char *provided, linestruct **history_list,
free(prompt);
#ifndef NANO_TINY
if (retval == KEY_WINCH)
if (retval == THE_WINDOW_RESIZED)
goto redo_theprompt;
#endif
/* Restore a possible previous prompt and maybe the typing position. */
prompt = saved_prompt;
if (function == do_cancel || function == do_enter)
if (function == do_cancel || function == do_enter ||
#ifdef ENABLE_BROWSER
function == to_first_file || function == to_last_file ||
#endif
function == to_first_line || function == to_last_line)
typing_x = was_typing_x;
/* Set the proper return value for Cancel and Enter. */
@ -692,14 +725,15 @@ int ask_user(bool withall, const char *question)
kbinput = get_kbinput(footwin, !withall);
#ifndef NANO_TINY
if (kbinput == KEY_WINCH)
if (kbinput == THE_WINDOW_RESIZED)
continue;
/* Accept first character of an external paste and ignore the rest. */
if (bracketed_paste)
if (kbinput == START_OF_PASTE) {
kbinput = get_kbinput(footwin, BLIND);
while (bracketed_paste)
get_kbinput(footwin, BLIND);
while (get_kbinput(footwin, BLIND) != END_OF_PASTE)
;
}
#endif
#ifdef ENABLE_NLS
@ -752,12 +786,15 @@ int ask_user(bool withall, const char *question)
focusing = TRUE;
}
#endif
/* Interpret ^N and ^Q as "No", to allow exiting in anger. */
else if (kbinput == '\x0E' || kbinput == '\x11')
/* Interpret ^N as "No", to allow exiting in anger, and ^Q or ^X too. */
else if (kbinput == '\x0E' || (kbinput == '\x11' && !ISSET(MODERN_BINDINGS)) ||
(kbinput == '\x18' && ISSET(MODERN_BINDINGS)))
choice = NO;
/* And interpret ^Y as "Yes". */
/* Also, interpret ^Y as "Yes, and ^A as "All". */
else if (kbinput == '\x19')
choice = YES;
else if (kbinput == '\x01' && withall)
choice = ALL;
#ifdef ENABLE_MOUSE
else if (kbinput == KEY_MOUSE) {
int mouse_x, mouse_y;

View File

@ -1,7 +1,7 @@
/**************************************************************************
* prototypes.h -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 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 *
@ -32,12 +32,13 @@ extern bool shifted_metas;
extern bool meta_key;
extern bool shift_held;
extern bool mute_modifiers;
extern bool bracketed_paste;
extern bool we_are_running;
extern bool more_than_one;
extern bool report_size;
extern bool ran_a_tool;
extern char *foretext;
extern bool inhelp;
extern char *title;
@ -68,13 +69,13 @@ extern int controlup, controldown;
extern int controlhome, controlend;
#ifndef NANO_TINY
extern int controldelete, controlshiftdelete;
extern int shiftleft, shiftright;
extern int shiftup, shiftdown;
extern int shiftcontrolleft, shiftcontrolright;
extern int shiftcontrolup, shiftcontroldown;
extern int shiftcontrolhome, shiftcontrolend;
extern int altleft, altright;
extern int altup, altdown;
extern int althome, altend;
extern int altpageup, altpagedown;
extern int altinsert, altdelete;
extern int shiftaltleft, shiftaltright;
@ -93,10 +94,11 @@ extern WINDOW *footwin;
extern int editwinrows;
extern int editwincols;
extern int margin;
extern int thebar;
extern int sidebar;
#ifndef NANO_TINY
extern int *bardata;
extern ssize_t stripe_column;
extern int cycling_aim;
#endif
extern linestruct *cutbuffer;
@ -238,6 +240,9 @@ 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);
#if defined(ENABLE_SPELLER) || defined(ENABLE_COLOR)
void strip_leading_blanks_from(char *string);
#endif
/* Most functions in color.c. */
#ifdef ENABLE_COLOR
@ -249,6 +254,7 @@ void precalc_multicolorinfo(void);
#endif
/* Most functions in cut.c. */
void expunge(undo_type action);
void do_delete(void);
void do_backspace(void);
#ifndef NANO_TINY
@ -267,8 +273,8 @@ void cut_text(void);
void cut_till_eof(void);
void zap_text(void);
void copy_marked_region(void);
void copy_text(void);
#endif
void copy_text(void);
void paste_text(void);
/* Most functions in files.c. */
@ -358,6 +364,12 @@ void to_first_line(void);
void to_last_line(void);
void do_page_up(void);
void do_page_down(void);
#ifndef NANO_TINY
void to_top_row(void);
void to_bottom_row(void);
void do_cycle(void);
void do_center(void);
#endif
#ifdef ENABLE_JUSTIFY
void do_para_begin(linestruct **line);
void do_para_end(linestruct **line);
@ -366,8 +378,8 @@ void to_para_end(void);
#endif
void to_prev_block(void);
void to_next_block(void);
void do_prev_word(void);
bool do_next_word(bool after_ends);
void do_prev_word(bool allow_folded);
bool do_next_word(bool after_ends, bool allow_folded);
void to_prev_word(void);
void to_next_word(void);
void do_home(void);
@ -377,10 +389,10 @@ void do_down(void);
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
void do_scroll_up(void);
void do_scroll_down(void);
void do_center(void);
#endif
void do_left(void);
void do_right(void);
void move_cursor_to_proper_column(void);
/* Most functions in nano.c. */
linestruct *make_new_node(linestruct *prevnode);
@ -429,6 +441,7 @@ void confirm_margin(void);
#endif
void unbound_key(int code);
bool changes_something(functionptrtype f);
void suck_up_input_and_paste_it(void);
void inject(char *burst, size_t count);
/* Most functions in prompt.c. */
@ -477,6 +490,11 @@ void goto_line_and_column(ssize_t line, ssize_t column, bool retain_answer,
bool interactive);
void do_gotolinecolumn(void);
#ifndef NANO_TINY
size_t get_matchbrackets_halfway(void);
int find_matching_bracket_pos(linestruct **line, size_t *xpos);
bool find_terminus_of_bracketed_region(linestruct **line, size_t *xpos, size_t bracket_half, bool reverse);
bool find_bracketed_region(linestruct *in_region,
linestruct **top, linestruct **bot);
void do_find_bracket(void);
void put_or_lift_anchor(void);
void to_prev_anchor(void);
@ -580,12 +598,14 @@ linestruct *line_from_number(ssize_t number);
#endif
/* Most functions in winio.c. */
linestruct *get_next_visible_line(linestruct *line);
linestruct *get_prev_visible_line(linestruct *line);
#ifndef NANO_TINY
void record_macro(void);
void run_macro(void);
#endif
void reserve_space_for(size_t newsize);
size_t waiting_keycodes(void);
void put_back(int keycode);
#ifdef ENABLE_NANORC
void implant(const char *string);
#endif
@ -599,7 +619,7 @@ void blank_edit(void);
void blank_statusbar(void);
void wipe_statusbar(void);
void blank_bottombars(void);
void check_statusblank(void);
void blank_it_when_expired(void);
void set_blankdelay_to_one(void);
char *display_string(const char *buf, size_t column, size_t span,
bool isdata, bool isprompt);
@ -611,6 +631,7 @@ void warn_and_briefly_pause(const char *msg);
void bottombars(int menu);
void post_one_key(const char *keystroke, const char *tag, int width);
void place_the_cursor(void);
int update_line_at(linestruct *line, size_t index, int row);
int update_line(linestruct *line, size_t index);
#ifndef NANO_TINY
int update_softwrapped_line(linestruct *line);
@ -675,3 +696,12 @@ void flip_newbuffer(void);
#endif
void discard_buffer(void);
void do_cancel(void);
/* Most functions in folding.c. */
#ifdef ENABLE_FOLDING
void do_fold_segment(void);
void unfold_folded_segment(linestruct *line);
linestruct *get_start_of_folded_segment(linestruct* line);
linestruct *get_end_of_folded_segment(linestruct* line);
int get_folded_segment_length(linestruct *line);
#endif

View File

@ -1,7 +1,7 @@
/**************************************************************************
* rcfile.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 2001-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2014 Mike Frysinger *
* Copyright (C) 2019 Brand Huntsman *
* Copyright (C) 2014-2021 Benno Schulenberg *
@ -69,7 +69,7 @@ static const rcoption rcopts[] = {
{"nohelp", NO_HELP},
{"nonewlines", NO_NEWLINES},
#ifdef ENABLE_WRAPPING
{"nowrap", NO_WRAP}, /* Deprecated; remove in 2024. */
{"nowrap", NO_WRAP}, /* Deprecated; remove in 2027. */
#endif
#ifdef ENABLE_OPERATINGDIR
{"operatingdir", 0},
@ -98,6 +98,7 @@ static const rcoption rcopts[] = {
{"backup", MAKE_BACKUP},
{"backupdir", 0},
{"bookstyle", BOOKSTYLE},
{"colonparsing", COLON_PARSING},
{"cutfromcursor", CUT_FROM_CURSOR},
{"emptyline", EMPTY_LINE},
{"guidestripe", 0},
@ -134,6 +135,7 @@ static const rcoption rcopts[] = {
{"errorcolor", 0},
{"keycolor", 0},
{"functioncolor", 0},
{"foldedcolor", 0},
#endif
{NULL, 0}
};
@ -245,6 +247,8 @@ keystruct *strtosc(const char *input)
s->func = do_replace;
else if (!strcmp(input, "cut"))
s->func = cut_text;
else if (!strcmp(input, "copy"))
s->func = copy_text;
else if (!strcmp(input, "paste"))
s->func = paste_text;
#ifndef NANO_TINY
@ -252,8 +256,6 @@ keystruct *strtosc(const char *input)
s->func = do_execute;
else if (!strcmp(input, "cutrestoffile"))
s->func = cut_till_eof;
else if (!strcmp(input, "copy"))
s->func = copy_text;
else if (!strcmp(input, "zap"))
s->func = zap_text;
else if (!strcmp(input, "mark"))
@ -321,6 +323,8 @@ keystruct *strtosc(const char *input)
s->func = do_undo;
else if (!strcmp(input, "redo"))
s->func = do_redo;
else if (!strcmp(input, "suspend"))
s->func = do_suspend;
#endif
else if (!strcmp(input, "left") ||
!strcmp(input, "back"))
@ -339,8 +343,6 @@ keystruct *strtosc(const char *input)
s->func = do_scroll_up;
else if (!strcmp(input, "scrolldown"))
s->func = do_scroll_down;
else if (!strcmp(input, "center"))
s->func = do_center;
#endif
else if (!strcmp(input, "prevword"))
s->func = to_prev_word;
@ -354,6 +356,16 @@ keystruct *strtosc(const char *input)
s->func = to_prev_block;
else if (!strcmp(input, "nextblock"))
s->func = to_next_block;
#ifndef NANO_TINY
else if (!strcmp(input, "toprow"))
s->func = to_top_row;
else if (!strcmp(input, "bottomrow"))
s->func = to_bottom_row;
else if (!strcmp(input, "center"))
s->func = do_center;
else if (!strcmp(input, "cycle"))
s->func = do_cycle;
#endif
else if (!strcmp(input, "pageup") ||
!strcmp(input, "prevpage"))
s->func = do_page_up;
@ -382,10 +394,6 @@ keystruct *strtosc(const char *input)
s->func = do_backspace;
else if (!strcmp(input, "refresh"))
s->func = full_refresh;
#ifndef NANO_TINY
else if (!strcmp(input, "suspend"))
s->func = do_suspend;
#endif
else if (!strcmp(input, "casesens"))
s->func = case_sens_void;
else if (!strcmp(input, "regexp"))
@ -463,8 +471,7 @@ keystruct *strtosc(const char *input)
else if (!strcmp(input, "cutfromcursor"))
s->toggle = CUT_FROM_CURSOR;
#ifdef ENABLE_WRAPPING
else if (!strcmp(input, "breaklonglines") ||
!strcmp(input, "nowrap")) /* Deprecated; remove in 2024. */
else if (!strcmp(input, "breaklonglines"))
s->toggle = BREAK_LONG_LINES;
#endif
else if (!strcmp(input, "tabstospaces"))
@ -519,9 +526,9 @@ char *menu_to_name(int menu)
return "boooo";
}
/* Parse the next word from the string, null-terminate it, and return
* a pointer to the first character after the null terminator. The
* returned pointer will point to '\0' if we hit the end of the line. */
/* Parse the next word from the string (if any), null-terminate it,
* and return a pointer to the next word. The returned pointer will
* point to '\0' when end-of-line was reached. */
char *parse_next_word(char *ptr)
{
while (!isblank((unsigned char)*ptr) && *ptr != '\0')
@ -539,10 +546,9 @@ char *parse_next_word(char *ptr)
return ptr;
}
/* Parse an argument, with optional quotes, after a keyword that takes
* one. If the next word starts with a ", we say that it ends with the
* last " of the line. Otherwise, we interpret it as usual, so that the
* arguments can contain "'s too. */
/* Parse an argument (optionally enveloped in double quotes). When the
* argument starts with a ", then the last " of the line indicates its
* end -- meaning that an argument can contain "'s either way. */
char *parse_argument(char *ptr)
{
const char *ptr_save = ptr;
@ -679,7 +685,7 @@ void begin_new_syntax(char *ptr)
live_syntax->comment = copy_of(GENERAL_COMMENT_CHARACTER);
#endif
live_syntax->color = NULL;
live_syntax->nmultis = 0;
live_syntax->multiscore = 0;
/* Hook the new syntax in at the top of the list. */
live_syntax->next = syntaxes;
@ -732,9 +738,11 @@ bool is_universal(void (*func)(void))
/* Bind or unbind a key combo, to or from a function. */
void parse_binding(char *ptr, bool dobind)
{
char *keyptr = NULL, *keycopy = NULL, *funcptr = NULL, *menuptr = NULL;
int keycode, menu, mask = 0;
char *keycopy, *keyptr, *menuptr;
keystruct *newsc = NULL;
char *funcptr = NULL;
int keycode, menu;
int mask = 0;
check_for_nonempty_syntax();
@ -753,7 +761,7 @@ void parse_binding(char *ptr, bool dobind)
else
keycopy[0] = toupper((unsigned char)keycopy[0]);
/* Verify that the key name is not too short, to allow the next call. */
/* Verify that the key name is not too short. */
if (keycopy[1] == '\0' || (keycopy[0] == 'M' && keycopy[2] == '\0')) {
jot_error(N_("Key name %s is invalid"), keycopy);
goto free_things;
@ -974,6 +982,11 @@ void parse_includes(char *ptr)
pattern++;
ptr = parse_argument(ptr);
if (strlen(pattern) > PATH_MAX) {
jot_error(N_("Path is too long"));
return;
}
/* Expand a tilde first, then try to match the globbing pattern. */
expanded = real_dir_from_tilde(pattern);
result = glob(expanded, GLOB_ERR|GLOB_NOCHECK, NULL, &files);
@ -1037,7 +1050,7 @@ short indices[COLORCOUNT] = { COLOR_RED, COLOR_GREEN, COLOR_BLUE,
short color_to_short(const char *colorname, bool *vivid, bool *thick)
{
if (strncmp(colorname, "bright", 6) == 0 && colorname[6] != '\0') {
/* Prefix "bright" is deprecated; remove in 2024. */
/* Prefix "bright" is deprecated; remove in 2027. */
*vivid = TRUE;
*thick = TRUE;
colorname += 6;
@ -1079,40 +1092,40 @@ short color_to_short(const char *colorname, bool *vivid, bool *thick)
/* Parse the color name (or pair of color names) in the given string.
* Return FALSE when any color name is invalid; otherwise return TRUE. */
bool parse_combination(char *combostr, short *fg, short *bg, int *attributes)
bool parse_combination(char *combotext, short *fg, short *bg, int *attributes)
{
bool vivid, thick;
char *comma;
*attributes = A_NORMAL;
if (strncmp(combostr, "bold", 4) == 0) {
if (strncmp(combotext, "bold", 4) == 0) {
*attributes |= A_BOLD;
if (combostr[4] != ',') {
if (combotext[4] != ',') {
jot_error(N_("An attribute requires a subsequent comma"));
return FALSE;
}
combostr += 5;
combotext += 5;
}
if (strncmp(combostr, "italic", 6) == 0) {
if (strncmp(combotext, "italic", 6) == 0) {
#ifdef A_ITALIC
*attributes |= A_ITALIC;
#endif
if (combostr[6] != ',') {
if (combotext[6] != ',') {
jot_error(N_("An attribute requires a subsequent comma"));
return FALSE;
}
combostr += 7;
combotext += 7;
}
comma = strchr(combostr, ',');
comma = strchr(combotext, ',');
if (comma)
*comma = '\0';
if (!comma || comma > combostr) {
*fg = color_to_short(combostr, &vivid, &thick);
if (!comma || comma > combotext) {
*fg = color_to_short(combotext, &vivid, &thick);
if (*fg == BAD_COLOR)
return FALSE;
if (vivid && !thick && COLORS > 8)
@ -1218,22 +1231,22 @@ void parse_rule(char *ptr, int rex_flags)
/* For a multiline rule, give it a number and increase the count. */
if (expectend) {
newcolor->id = live_syntax->nmultis;
live_syntax->nmultis++;
newcolor->id = live_syntax->multiscore;
live_syntax->multiscore++;
}
}
}
/* Parse the argument of an interface color option. */
colortype *parse_interface_color(char *combostr)
/* Set the colors for the given interface element to the given combination. */
void set_interface_color(int element, char *combotext)
{
colortype *trio = nmalloc(sizeof(colortype));
if (!parse_combination(combostr, &trio->fg, &trio->bg, &trio->attributes)) {
free(trio);
return NULL;
if (parse_combination(combotext, &trio->fg, &trio->bg, &trio->attributes)) {
free(color_combo[element]);
color_combo[element] = trio;
} else
return trio;
free(trio);
}
/* Read regex strings enclosed in double quotes from the line pointed at
@ -1293,7 +1306,7 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
}
}
/* Gather and store the string after a comment/linter command. */
/* Gather and store the string after a comment/linter/formatter/tabgives command. */
void pick_up_name(const char *kind, char *ptr, char **storage)
{
if (*ptr == '\0') {
@ -1332,19 +1345,21 @@ bool parse_syntax_commands(char *keyword, char *ptr)
#endif
} else if (strcmp(keyword, "tabgives") == 0) {
pick_up_name("tabgives", ptr, &live_syntax->tabstring);
} else if (strcmp(keyword, "linter") == 0)
} else if (strcmp(keyword, "linter") == 0) {
pick_up_name("linter", ptr, &live_syntax->linter);
else if (strcmp(keyword, "formatter") == 0)
strip_leading_blanks_from(live_syntax->linter);
} else if (strcmp(keyword, "formatter") == 0) {
pick_up_name("formatter", ptr, &live_syntax->formatter);
else
strip_leading_blanks_from(live_syntax->formatter);
} else
return FALSE;
return TRUE;
}
#endif /* ENABLE_COLOR */
/* Verify that the user has not unmapped every shortcut for a
* function that we consider 'vital' (such as "Exit"). */
/* Verify that the user has not unmapped every shortcut for
* a function that we consider 'vital' (such as "Exit"). */
static void check_vitals_mapped(void)
{
#define VITALS 4
@ -1353,7 +1368,7 @@ static void check_vitals_mapped(void)
for (int v = 0; v < VITALS; v++) {
for (funcstruct *f = allfuncs; f != NULL; f = f->next) {
if (f->func == vitals[v] && f->menus & inmenus[v]) {
if (f->func == vitals[v] && (f->menus & inmenus[v])) {
if (first_sc_for(inmenus[v], f->func) == NULL) {
jot_error(N_("No key is bound to function '%s' in menu '%s'. "
" Exiting.\n"), f->tag, menu_to_name(inmenus[v]));
@ -1368,7 +1383,7 @@ static void check_vitals_mapped(void)
/* Parse the rcfile, once it has been opened successfully at rcstream,
* and close it afterwards. If just_syntax is TRUE, allow the file to
* to contain only color syntax commands. */
* contain only color syntax commands. */
void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
{
char *buffer = NULL;
@ -1576,29 +1591,31 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
#endif
#ifdef ENABLE_COLOR
if (strcmp(option, "titlecolor") == 0)
color_combo[TITLE_BAR] = parse_interface_color(argument);
set_interface_color(TITLE_BAR, argument);
else if (strcmp(option, "numbercolor") == 0)
color_combo[LINE_NUMBER] = parse_interface_color(argument);
set_interface_color(LINE_NUMBER, argument);
else if (strcmp(option, "stripecolor") == 0)
color_combo[GUIDE_STRIPE] = parse_interface_color(argument);
set_interface_color(GUIDE_STRIPE, argument);
else if (strcmp(option, "scrollercolor") == 0)
color_combo[SCROLL_BAR] = parse_interface_color(argument);
set_interface_color(SCROLL_BAR, argument);
else if (strcmp(option, "selectedcolor") == 0)
color_combo[SELECTED_TEXT] = parse_interface_color(argument);
set_interface_color(SELECTED_TEXT, argument);
else if (strcmp(option, "spotlightcolor") == 0)
color_combo[SPOTLIGHTED] = parse_interface_color(argument);
set_interface_color(SPOTLIGHTED, argument);
else if (strcmp(option, "minicolor") == 0)
color_combo[MINI_INFOBAR] = parse_interface_color(argument);
set_interface_color(MINI_INFOBAR, argument);
else if (strcmp(option, "promptcolor") == 0)
color_combo[PROMPT_BAR] = parse_interface_color(argument);
set_interface_color(PROMPT_BAR, argument);
else if (strcmp(option, "statuscolor") == 0)
color_combo[STATUS_BAR] = parse_interface_color(argument);
set_interface_color(STATUS_BAR, argument);
else if (strcmp(option, "errorcolor") == 0)
color_combo[ERROR_MESSAGE] = parse_interface_color(argument);
set_interface_color(ERROR_MESSAGE, argument);
else if (strcmp(option, "keycolor") == 0)
color_combo[KEY_COMBO] = parse_interface_color(argument);
set_interface_color(KEY_COMBO, argument);
else if (strcmp(option, "functioncolor") == 0)
color_combo[FUNCTION_TAG] = parse_interface_color(argument);
set_interface_color(FUNCTION_TAG, argument);
else if (strcmp(option, "foldedcolor") == 0)
set_interface_color(FOLDED_LINE, argument);
else
#endif
#ifdef ENABLE_OPERATINGDIR
@ -1696,6 +1713,7 @@ void parse_one_nanorc(void)
jot_error(N_("Error reading %s: %s"), nanorc, strerror(errno));
}
/* Return TRUE when path-plus-name denotes a readable, normal file. */
bool have_nanorc(const char *path, const char *name)
{
if (path == NULL)

View File

@ -1,7 +1,7 @@
/**************************************************************************
* search.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2015-2020, 2022 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -162,7 +162,9 @@ void search_init(bool replacing, bool retain_answer)
break;
}
tidy_up_after_search();
if (!inhelp)
tidy_up_after_search();
free(thedefault);
}
@ -308,6 +310,8 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
}
}
UNFOLD_SEGMENT(line);
found_x = found - line->data;
nodelay(midwin, FALSE);
@ -381,7 +385,8 @@ void do_research(void)
go_looking();
tidy_up_after_search();
if (!inhelp)
tidy_up_after_search();
}
/* Search in the backward direction for the next occurrence. */
@ -678,11 +683,6 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
openfile->mark = was_mark;
#endif
/* If "automatic newline" is enabled, and text has been added to the
* magic line, make a new magic line. */
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
new_magicline();
return numreplaced;
}
@ -704,11 +704,17 @@ void ask_for_and_do_replacements(void)
size_t was_firstcolumn = openfile->firstcolumn;
linestruct *beginline = openfile->current;
size_t begin_x = openfile->current_x;
char *replacee = copy_of(last_search);
ssize_t numreplaced;
int response = do_prompt(MREPLACEWITH, "", &replace_history,
/* TRANSLATORS: This is a prompt. */
edit_refresh, _("Replace with"));
/* Set the string to be searched, as it might have changed at the prompt. */
free(last_search);
last_search = replacee;
#ifdef ENABLE_HISTORIES
/* When not "", add the replace string to the replace history list. */
if (response == 0)
@ -754,6 +760,7 @@ void goto_line_posx(ssize_t linenumber, size_t pos_x)
openfile->current_x = pos_x;
openfile->placewewant = xplustabs();
UNFOLD_SEGMENT(openfile->current);
refresh_needed = TRUE;
}
@ -808,16 +815,27 @@ void goto_line_and_column(ssize_t line, ssize_t column, bool retain_answer,
line = 1;
#ifdef ENABLE_COLOR
#ifdef ENABLE_FOLDING
linestruct *edit_bottom = openfile->edittop;
for (int i = 0; edit_bottom != openfile->filebot && i < editwinrows; ++i)
edit_bottom = get_next_visible_line(edit_bottom);
if (line > edit_bottom->lineno ||
(ISSET(SOFTWRAP) && line > openfile->current->lineno))
recook |= perturbed;
#else
if (line > openfile->edittop->lineno + editwinrows ||
(ISSET(SOFTWRAP) && line > openfile->current->lineno))
recook |= perturbed;
#endif
#endif /* ENABLE_FOLDING */
#endif /* ENABLE_COLOR */
/* Iterate to the requested line. */
for (openfile->current = openfile->filetop; line > 1 &&
openfile->current != openfile->filebot; line--)
openfile->current = openfile->current->next;
UNFOLD_SEGMENT(openfile->current);
/* Take a negative column number to mean: from the end of the line. */
if (column < 0)
column = breadth(openfile->current->data) + column + 2;
@ -857,7 +875,7 @@ void goto_line_and_column(ssize_t line, ssize_t column, bool retain_answer,
* line or chunk on the bottom line of the screen; otherwise, just
* center the target line. */
if (rows_from_tail < editwinrows / 2 && !ISSET(JUMPY_SCROLLING)) {
openfile->current_y = editwinrows - 1 - rows_from_tail;
openfile->cursor_row = editwinrows - 1 - rows_from_tail;
adjust_viewport(STATIONARY);
} else
adjust_viewport(CENTERING);
@ -872,23 +890,113 @@ void do_gotolinecolumn(void)
}
#ifndef NANO_TINY
/* Search forwards for a line ending with a bracket, including the current line.
* line is an in/out parameter. The passed value is the start line for searching.
* xpos is an out parameter. It is the position in the line where the bracket is
* found. bracket_half is the halfway mark in the matchbrackets array. This way in
* a loop the halfway value isn't recomputed. If end is true, search for an ending
* bracket, else search for a starting bracket. */
bool find_terminus_of_bracketed_region(linestruct **line, size_t *xpos, size_t bracket_half, bool reverse)
{
/* Search forwards for a line ending with a bracket, including the current line */
for (; (*line) != NULL; *line = (reverse ? (*line)->prev : (*line)->next)) {
char *found;
const char *bracket;
int len = strlen((*line)->data);
/* Find the last bracket on the search line */
found = mbrevstrpbrk((*line)->data, matchbrackets, (*line)->data + len);
if (found == NULL)
continue;
*xpos = found - (*line)->data;
bracket = mbstrchr(matchbrackets, found);
/* We're looking for closing braces, not opening */
if (bracket >= matchbrackets + bracket_half)
continue;
/* Check if this is the last character in the line */
char *next = (*line)->data + step_right((*line)->data, *xpos);
if (*next == '\0')
return TRUE;
}
*xpos = 0;
return FALSE;
}
/* Get the halfway point in matchbrackets, where open and close
* brackets meet. */
size_t get_matchbrackets_halfway(void)
{
size_t charcount = mbstrlen(matchbrackets) / 2;
size_t halfway = 0;
for (size_t i = 0; i < charcount; ++i)
halfway += char_length(matchbrackets + halfway);
return halfway;
}
/* Get a region surrounding the line in_region. A region here is defined
* as a block of text ending with a closing bracket at the end of a line,
* and starting with a matching opening bracket. Or a block of text starting
* with an opening bracket at the end of a line and ending with a matching
* closing bracket.
* in_region is a line within the region. If a region is found but does not
* contain in_region, it is ignored.
* top and bot are out parameters. Returns the top/bottom line of the region. */
bool find_bracketed_region(linestruct *in_region,
linestruct **top, linestruct **bot)
{
size_t bracket_half = get_matchbrackets_halfway();
size_t top_pos;
size_t bot_pos;
linestruct *was_top = *top;
linestruct *was_bot = *bot;
*bot = in_region;
for (; find_terminus_of_bracketed_region(top, &top_pos, bracket_half, TRUE)
; *top = (*top)->prev)
{
*bot= *top;
bot_pos = top_pos;
if (!find_matching_bracket_pos(bot, &bot_pos)) {
if ((*bot)->lineno < in_region->lineno)
continue;
int linedist = (*bot)->lineno - (*top)->lineno;
if (linedist >= 2) {
*top = (*top)->next;
*bot = (*bot)->prev;
return TRUE;
}
}
}
*top = was_top;
*bot = was_bot;
return FALSE;
}
/* Search, starting from the current position, for any of the two characters
* in bracket_pair. If reverse is TRUE, search backwards, otherwise forwards.
* Return TRUE when one of the brackets was found, and FALSE otherwise. */
bool find_a_bracket(bool reverse, const char *bracket_pair)
bool find_a_bracket(bool reverse, const char *bracket_pair,
linestruct **inout_line, size_t *xpos)
{
linestruct *line = openfile->current;
linestruct *line = *inout_line;
const char *pointer, *found;
if (reverse) {
/* First step away from the current bracket. */
if (openfile->current_x == 0) {
if (*xpos == 0) {
line = line->prev;
if (line == NULL)
return FALSE;
pointer = line->data + strlen(line->data);
} else
pointer = line->data + step_left(line->data, openfile->current_x);
pointer = line->data + step_left(line->data, *xpos);
/* Now seek for any of the two brackets we are interested in. */
while (!(found = mbrevstrpbrk(line->data, bracket_pair, pointer))) {
@ -898,7 +1006,7 @@ bool find_a_bracket(bool reverse, const char *bracket_pair)
pointer = line->data + strlen(line->data);
}
} else {
pointer = line->data + step_right(line->data, openfile->current_x);
pointer = line->data + step_right(line->data, *xpos);
while (!(found = mbstrpbrk(pointer, bracket_pair))) {
line = line->next;
@ -908,45 +1016,24 @@ bool find_a_bracket(bool reverse, const char *bracket_pair)
}
}
/* Set the current position to the found bracket. */
openfile->current = line;
openfile->current_x = found - line->data;
/* Set the found position to the found bracket. */
*inout_line = line;
*xpos = found - line->data;
return TRUE;
}
/* Search for a match to the bracket at the current cursor position, if
* there is one. */
void do_find_bracket(void)
/* Search for the given bracket's compliment within matchbrackets.
* ch must be a pointer to within matchbrackets.
* reverse is true if the found compliment came before ch in matchbrackets. */
const char *get_bracket_compliment(const char *ch, bool *reverse)
{
linestruct *was_current = openfile->current;
size_t was_current_x = openfile->current_x;
/* The current cursor position, in case we don't find a complement. */
const char *ch;
/* The location in matchbrackets of the bracket under the cursor. */
int ch_len;
/* The length of ch in bytes. */
const char *wanted_ch;
/* The location in matchbrackets of the complementing bracket. */
int wanted_ch_len;
/* The length of wanted_ch in bytes. */
char bracket_pair[MAXCHARLEN * 2 + 1];
/* The pair of characters in ch and wanted_ch. */
size_t halfway = 0;
/* The index in matchbrackets where the closing brackets start. */
size_t charcount = mbstrlen(matchbrackets) / 2;
/* Half the number of characters in matchbrackets. */
size_t balance = 1;
/* The initial bracket count. */
bool reverse;
/* The direction we search. */
ch = mbstrchr(matchbrackets, openfile->current->data + openfile->current_x);
if (ch == NULL) {
statusline(AHEM, _("Not a bracket"));
return;
}
const char *wanted_ch;
/* The location in matchbrackets of the complementing bracket. */
size_t halfway = 0;
/* The index in matchbrackets where the closing brackets start. */
/* Find the halfway point in matchbrackets, where the closing ones start. */
for (size_t i = 0; i < charcount; i++)
@ -954,19 +1041,35 @@ void do_find_bracket(void)
/* When on a closing bracket, we have to search backwards for a matching
* opening bracket; otherwise, forward for a matching closing bracket. */
reverse = (ch >= (matchbrackets + halfway));
*reverse = (ch >= (matchbrackets + halfway));
/* Step half the number of total characters either backwards or forwards
* through matchbrackets to find the wanted complementary bracket. */
wanted_ch = ch;
while (charcount-- > 0) {
if (reverse)
if (*reverse)
wanted_ch = matchbrackets + step_left(matchbrackets,
wanted_ch - matchbrackets);
else
wanted_ch += char_length(wanted_ch);
}
return wanted_ch;
}
/* Create a bracket pair string from the given bracket in ch, assigning
* the result to bracket_pair. Reverse is set to true if we need to
* search backward for a match. */
void create_bracket_pair(char *bracket_pair, const char *ch,
int ch_len, bool* reverse)
{
const char *wanted_ch;
/* The location in matchbrackets of the complementing bracket. */
int wanted_ch_len;
/* The length of wanted_ch in bytes. */
wanted_ch = get_bracket_compliment(ch, reverse);
ch_len = char_length(ch);
wanted_ch_len = char_length(wanted_ch);
@ -974,24 +1077,65 @@ void do_find_bracket(void)
strncpy(bracket_pair, ch, ch_len);
strncpy(bracket_pair + ch_len, wanted_ch, wanted_ch_len);
bracket_pair[ch_len + wanted_ch_len] = '\0';
}
while (find_a_bracket(reverse, bracket_pair)) {
/* Increment/decrement balance for an identical/other bracket. */
balance += (strncmp(openfile->current->data + openfile->current_x,
ch, ch_len) == 0) ? 1 : -1;
/* Get the bracket match position for the character currently under the cursor.
* If there is no bracket beneath the cursor, return NOT_A_BRACKET. If there is
* no match found, return NOT_FOUND_BRACKET. Otherwise returns FOUND_BRACKET
* and sets line and xpos to the found line and offset respectively. */
int find_matching_bracket_pos(linestruct **line, size_t *xpos)
{
const char *br_ch;
/* The location in matchbrackets of the bracket under the cursor. */
int br_ch_len;
/* The length of br_ch in bytes. */
char bracket_pair[MAXCHARLEN * 2 + 1];
/* The pair of characters in ch and wanted_ch. */
size_t balance = 1;
/* The initial bracket count. */
bool reversed;
/* The direction we search. */
/* When balance reached zero, we've found the complementary bracket. */
if (balance == 0) {
edit_redraw(was_current, FLOWING);
return;
}
br_ch = mbstrchr(matchbrackets, (*line)->data + (*xpos));
if (br_ch == NULL)
return NOT_A_BRACKET;
br_ch_len = char_length(br_ch);
create_bracket_pair(bracket_pair, br_ch, br_ch_len, &reversed);
while (find_a_bracket(reversed, bracket_pair, line, xpos)) {
balance += (strncmp((*line)->data + *xpos,
br_ch, br_ch_len) == 0) ? 1 : -1;
if (balance == 0)
return FOUND_BRACKET;
}
return NOT_FOUND_BRACKET;
}
/* Search for a match to the bracket at the current cursor position, if
* there is one. */
void do_find_bracket(void)
{
linestruct *was_current = openfile->current;
size_t was_current_x = openfile->current_x;
int res = find_matching_bracket_pos(&openfile->current,
&openfile->current_x);
if (res == FOUND_BRACKET) {
UNFOLD_SEGMENT(openfile->current);
edit_redraw(was_current, FLOWING);
return;
}
statusline(AHEM, _("No matching bracket"));
/* Restore the cursor position. */
openfile->current = was_current;
openfile->current_x = was_current_x;
statusline(AHEM, res == NOT_FOUND_BRACKET ?
_("No matching bracket") :
_("Not a bracket"));
}
/* Place an anchor at the current line when none exists, otherwise remove it. */
@ -1015,6 +1159,7 @@ void go_to_and_confirm(linestruct *line)
if (line != openfile->current) {
openfile->current = line;
openfile->current_x = 0;
UNFOLD_SEGMENT(openfile->current);
#ifdef ENABLE_COLOR
if (line->lineno > openfile->edittop->lineno + editwinrows ||
(ISSET(SOFTWRAP) && line->lineno > was_current->lineno))

View File

@ -1,7 +1,7 @@
/**************************************************************************
* text.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2014-2015 Mark Majeres *
* Copyright (C) 2016 Mike Scalora *
* Copyright (C) 2016 Sumedh Pendurkar *
@ -36,13 +36,6 @@
#define st_mtim st_mtimespec
#endif
#ifdef ENABLE_WORDCOMPLETION
static int pletion_x = 0;
/* The x position in pletion_line of the last found completion. */
static completionstruct *list_of_completions;
/* A linked list of the completions that have been attempted. */
#endif
#ifndef NANO_TINY
/* Toggle the mark. */
void do_mark(void)
@ -64,6 +57,12 @@ void do_mark(void)
* of spaces that a tab would normally take up at this position. */
void do_tab(void)
{
#ifndef NANO_TINY
/* When <Tab> is pressed while a region is marked, indent the region. */
if (openfile->mark && openfile->mark != openfile->current)
do_indent();
else
#endif
#ifdef ENABLE_COLOR
if (openfile->syntax && openfile->syntax->tabstring)
inject(openfile->syntax->tabstring, strlen(openfile->syntax->tabstring));
@ -96,6 +95,8 @@ void indent_a_line(linestruct *line, char *indentation)
if (indent_len == 0)
return;
UNFOLD_SEGMENT(line);
/* Add the fabricated indentation to the beginning of the line. */
line->data = nrealloc(line->data, length + indent_len + 1);
memmove(line->data + indent_len, line->data, length + 1);
@ -226,6 +227,8 @@ void unindent_a_line(linestruct *line, size_t indent_len)
if (indent_len == 0)
return;
UNFOLD_SEGMENT(line);
/* Remove the first tab's worth of whitespace from this line. */
memmove(line->data, line->data + indent_len, length - indent_len + 1);
@ -317,6 +320,8 @@ bool comment_line(undo_type action, linestruct *line, const char *comment_seq)
/* Length of postfix. */
size_t line_len = strlen(line->data);
UNFOLD_SEGMENT(line);
if (!ISSET(NO_NEWLINES) && line == openfile->filebot)
return FALSE;
@ -560,8 +565,8 @@ void do_undo(void)
* and the nonewlines flag isn't set, do not re-add a newline that
* wasn't actually deleted; just position the cursor. */
if ((u->xflags & WAS_BACKSPACE_AT_EOF) && !ISSET(NO_NEWLINES)) {
openfile->current = openfile->filebot;
openfile->current_x = 0;
goto_line_posx(openfile->filebot->lineno, 0);
focusing = FALSE;
break;
}
line->data[u->tail_x] = '\0';
@ -573,8 +578,6 @@ 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;
@ -625,12 +628,12 @@ void do_undo(void)
case COUPLE_BEGIN:
undidmsg = u->strdata;
goto_line_posx(u->head_lineno, u->head_x);
openfile->current_y = u->tail_lineno;
openfile->cursor_row = u->tail_lineno;
adjust_viewport(STATIONARY);
break;
case COUPLE_END:
/* Remember the row of the cursor for a possible redo. */
openfile->current_undo->head_lineno = openfile->current_y;
openfile->current_undo->head_lineno = openfile->cursor_row;
openfile->current_undo = openfile->current_undo->next;
do_undo();
do_undo();
@ -671,8 +674,8 @@ void do_undo(void)
#ifdef ENABLE_COLOR
if (u->type <= REPLACE)
check_the_multis(openfile->current);
else if (u->type == INSERT)
perturbed = TRUE;
else if (u->type == INSERT || u->type == COUPLE_BEGIN)
recook = TRUE;
#endif
/* When at the point where the buffer was last saved, unset "Modified". */
@ -752,8 +755,6 @@ 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;
@ -766,6 +767,7 @@ void do_redo(void)
do_redo();
u = openfile->current_undo;
goto_line_posx(u->head_lineno, u->head_x);
ensure_firstcolumn_is_aligned();
break;
case SPLIT_END:
redidmsg = _("addition");
@ -803,7 +805,7 @@ void do_redo(void)
case COUPLE_END:
redidmsg = u->strdata;
goto_line_posx(u->tail_lineno, u->tail_x);
openfile->current_y = u->head_lineno;
openfile->cursor_row = u->head_lineno;
adjust_viewport(STATIONARY);
break;
case INDENT:
@ -841,7 +843,7 @@ void do_redo(void)
#ifdef ENABLE_COLOR
if (u->type <= REPLACE)
check_the_multis(openfile->current);
else if (u->type == INSERT)
else if (u->type == INSERT || u->type == COUPLE_END)
recook = TRUE;
#endif
@ -859,6 +861,12 @@ void do_enter(void)
{
linestruct *newnode = make_new_node(openfile->current);
size_t extra = 0;
#ifdef ENABLE_FOLDING
if (openfile->current->folded) {
newnode->folded = TRUE;
openfile->current->folded = FALSE;
}
#endif
#ifndef NANO_TINY
linestruct *sampleline = openfile->current;
bool allblanks = FALSE;
@ -885,6 +893,13 @@ void do_enter(void)
strcpy(&newnode->data[extra], openfile->current->data +
openfile->current_x);
#ifndef NANO_TINY
/* Adjust the mark if it is on the current line after the cursor. */
if (openfile->mark == openfile->current &&
openfile->mark_x > openfile->current_x) {
openfile->mark = newnode;
openfile->mark_x += extra - openfile->current_x;
}
if (ISSET(AUTOINDENT)) {
/* Copy the whitespace from the sample line to the new one. */
strncpy(newnode->data, sampleline->data, extra);
@ -899,13 +914,6 @@ void do_enter(void)
#ifndef NANO_TINY
add_undo(ENTER, NULL);
/* Adjust the mark if it was on the current line after the cursor. */
if (openfile->mark == openfile->current &&
openfile->mark_x > openfile->current_x) {
openfile->mark = newnode;
openfile->mark_x += extra - openfile->current_x;
}
#endif
/* Insert the newly created line after the current one and renumber. */
@ -1037,8 +1045,6 @@ 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:
@ -1082,7 +1088,7 @@ void add_undo(undo_type action, const char *message)
u->xflags |= INCLUDED_LAST_LINE;
break;
case COUPLE_BEGIN:
u->tail_lineno = openfile->current_y;
u->tail_lineno = openfile->cursor_row;
/* Fall-through. */
case COUPLE_END:
u->strdata = copy_of(_(message));
@ -1313,18 +1319,18 @@ void do_wrap(void)
}
/* Join the next line to this one. */
do_delete();
expunge(DEL);
#ifdef ENABLE_JUSTIFY
/* If the leading part of the current line equals the leading part of
* what was the next line, then strip this second leading part. */
if (strncmp(line->data, line->data + openfile->current_x, lead_len) == 0)
for (size_t i = lead_len; i > 0; i--)
do_delete();
expunge(DEL);
#endif
/* Remove any extra blanks. */
while (is_blank_char(&line->data[openfile->current_x]))
do_delete();
expunge(DEL);
}
/* Go to the wrap location. */
@ -1338,7 +1344,7 @@ void do_wrap(void)
while ((rear_x != typed_x || cursor_x >= wrap_loc) &&
is_blank_char(line->data + rear_x)) {
openfile->current_x = rear_x;
do_delete();
expunge(DEL);
rear_x = step_left(line->data, rear_x);
}
}
@ -1346,6 +1352,12 @@ void do_wrap(void)
/* Now split the line. */
do_enter();
#ifndef NANO_TINY
/* When wrapping a partially visible line, adjust start-of-screen. */
if (openfile->edittop == line && openfile->firstcolumn > 0 && cursor_x >= wrap_loc)
go_forward_chunks(1, &openfile->edittop, &openfile->firstcolumn);
#endif
#ifdef ENABLE_JUSTIFY
/* If the original line has quoting, copy it to the spillage line. */
if (quot_len > 0) {
@ -1582,9 +1594,9 @@ void concat_paragraph(linestruct *line, size_t count)
line->data[line_len] = '\0';
}
line->data = nrealloc(line->data,
line_len + next_line_len - next_lead_len + 1);
line->data = nrealloc(line->data, line_len + next_line_len - next_lead_len + 1);
strcat(line->data, next_line->data + next_lead_len);
UNFOLD_SEGMENT(line);
#ifndef NANO_TINY
line->has_anchor |= next_line->has_anchor;
#endif
@ -1694,6 +1706,12 @@ void rewrap_paragraph(linestruct **line, char *lead_string, size_t lead_len)
*line = (*line)->next;
}
#ifdef ENABLE_COLOR
/* If the new paragraph exceeds the viewport, recalculate the multidata. */
if ((*line)->lineno >= editwinrows)
recook = TRUE;
#endif
/* When possible, go to the line after the rewrapped paragraph. */
if ((*line)->next != NULL)
*line = (*line)->next;
@ -1768,6 +1786,7 @@ void justify_text(bool whole_buffer)
/* The length of that later lead. */
ssize_t was_the_linenumber = openfile->current->lineno;
/* The line to return to after a full justification. */
bool marked_backward = (openfile->mark && !mark_is_before_cursor());
/* TRANSLATORS: This one goes with Undid/Redid messages. */
add_undo(COUPLE_BEGIN, N_("justification"));
@ -1871,7 +1890,8 @@ void justify_text(bool whole_buffer)
#endif
refresh_needed = TRUE;
return;
}
} else
openfile->current_x = 0;
/* Set the starting point of the paragraph. */
startline = openfile->current;
@ -1943,6 +1963,9 @@ void justify_text(bool whole_buffer)
free(secondary_lead);
free(primary_lead);
/* Keep as much of the marked region onscreen as possible. */
focusing = FALSE;
} else
#endif
{
@ -1976,7 +1999,7 @@ void justify_text(bool whole_buffer)
update_undo(PASTE);
/* After justifying a backward-marked text, swap mark and cursor. */
if (openfile->mark && !mark_is_before_cursor()) {
if (marked_backward) {
linestruct *bottom = openfile->current;
size_t bottom_x = openfile->current_x;
@ -2021,6 +2044,9 @@ void do_full_justify(void)
{
justify_text(WHOLE_BUFFER);
ran_a_tool = TRUE;
#ifdef ENABLE_COLOR
recook = TRUE;
#endif
}
#endif /* ENABLE_JUSTIFY */
@ -2586,7 +2612,7 @@ void do_linter(void)
if (in_restricted_mode())
return;
if (!openfile->syntax || !openfile->syntax->linter) {
if (!openfile->syntax || !openfile->syntax->linter || !*openfile->syntax->linter) {
statusline(AHEM, _("No linter is defined for this type of file"));
return;
}
@ -2742,6 +2768,13 @@ void do_linter(void)
if (!WIFEXITED(lint_status) || WEXITSTATUS(lint_status) > 2) {
statusline(ALERT, _("Error invoking '%s'"), openfile->syntax->linter);
for (curlint = lints; curlint != NULL;) {
tmplint = curlint;
curlint = curlint->next;
free(tmplint->msg);
free(tmplint->filename);
free(tmplint);
}
return;
}
@ -2751,6 +2784,7 @@ void do_linter(void)
return;
}
/* When the help lines are off and there is room, force them on. */
if (helpless && LINES > 5) {
UNSET(NO_HELP);
window_init();
@ -2852,12 +2886,13 @@ void do_linter(void)
/* Place the cursor to indicate the affected line. */
place_the_cursor();
UNFOLD_SEGMENT(openfile->current);
wnoutrefresh(midwin);
kbinput = get_kbinput(footwin, VISIBLE);
#ifndef NANO_TINY
if (kbinput == KEY_WINCH)
if (kbinput == THE_WINDOW_RESIZED)
continue;
#endif
function = func_from_key(kbinput);
@ -2927,7 +2962,7 @@ void do_formatter(void)
if (in_restricted_mode())
return;
if (!openfile->syntax || !openfile->syntax->formatter) {
if (!openfile->syntax || !openfile->syntax->formatter || !*openfile->syntax->formatter) {
statusline(AHEM, _("No formatter is defined for this type of file"));
return;
}
@ -2993,7 +3028,7 @@ void count_lines_words_and_characters(void)
* incrementing the word count for each successful step. */
while (openfile->current->lineno < botline->lineno ||
(openfile->current == botline && openfile->current_x < bot_x)) {
if (do_next_word(FALSE))
if (do_next_word(FALSE, ALLOW_FOLDED))
words++;
}
@ -3018,7 +3053,7 @@ void do_verbatim_input(void)
#ifndef NANO_TINY
/* When barless and with cursor on bottom row, make room for the feedback. */
if (ISSET(ZERO) && openfile->current_y == editwinrows - 1 && LINES > 1) {
if (ISSET(ZERO) && openfile->cursor_row == editwinrows - 1 && LINES > 1) {
edit_scroll(FORWARD);
edit_refresh();
}
@ -3073,21 +3108,24 @@ char *copy_completion(char *text)
return word;
}
/* Look at the fragment the user has typed, then search all buffers for
* the first word that starts with this fragment, and tentatively complete the
* fragment. If the user types 'Complete' again, search and paste the next
* possible completion. */
/* Look at the fragment the user has typed, then search all buffers
* for the first word that starts with this fragment, and tentatively
* complete the fragment. If the user hits 'Complete' again, search
* and paste the next possible completion. */
void complete_a_word(void)
{
static openfilestruct *scouring = NULL;
/* The buffer that is being searched for possible completions. */
char *shard, *completion = NULL;
size_t start_of_shard, shard_length = 0;
size_t i = 0, j = 0;
completionstruct *some_word;
static completionstruct *list_of_completions;
/* A linked list of the completions that have been attempted. */
static int pletion_x = 0;
/* The x position in `pletion_line` of the last found completion. */
#ifdef ENABLE_WRAPPING
bool was_set_wrapping = ISSET(BREAK_LONG_LINES);
#endif
size_t start_of_shard;
size_t shard_length = 0;
char *shard;
/* If this is a fresh completion attempt... */
if (pletion_line == NULL) {
@ -3143,6 +3181,9 @@ void complete_a_word(void)
while (pletion_line != NULL) {
ssize_t threshold = strlen(pletion_line->data) - shard_length - 1;
/* The point where we can stop searching for shard. */
completionstruct *some_word;
char *completion;
size_t i, j;
/* Traverse the whole line, looking for shard. */
for (i = pletion_x; (ssize_t)i < threshold; i++) {

View File

@ -1,7 +1,7 @@
/**************************************************************************
* utils.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2023 Free Software Foundation, Inc. *
* Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc. *
* Copyright (C) 2016, 2017, 2019 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
@ -126,29 +126,30 @@ bool parse_num(const char *string, ssize_t *result)
return TRUE;
}
/* Read two numbers, separated by a comma, from str, and store them in
* *line and *column. Return FALSE on error, and TRUE otherwise. */
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column)
/* Read one number (or two numbers separated by comma, period, or colon)
* from the given string and store the number(s) in *line (and *column).
* Return FALSE on a failed parsing, and TRUE otherwise. */
bool parse_line_column(const char *string, ssize_t *line, ssize_t *column)
{
const char *comma;
char *firstpart;
bool retval;
while (*str == ' ')
str++;
while (*string == ' ')
string++;
comma = strpbrk(str, ",.:");
comma = strpbrk(string, ",.:");
if (comma == NULL)
return parse_num(str, line);
return parse_num(string, line);
retval = parse_num(comma + 1, column);
if (comma == str)
if (comma == string)
return retval;
firstpart = copy_of(str);
firstpart[comma - str] = '\0';
firstpart = copy_of(string);
firstpart[comma - string] = '\0';
retval = parse_num(firstpart, line) && retval;
@ -436,6 +437,8 @@ void remove_magicline(void)
{
if (openfile->filebot->data[0] == '\0' &&
openfile->filebot != openfile->filetop) {
if (openfile->current == openfile->filebot)
openfile->current = openfile->current->prev;
openfile->filebot = openfile->filebot->prev;
delete_node(openfile->filebot->next);
openfile->filebot->next = NULL;

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,17 @@
## Syntax highlighting for assembler.
## Original author: Mike Frysinger
syntax asm "\.(S|s|asm)$"
magic "assembler source"
comment "//"
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 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 "^[[:blank:]]*[.0-9A-Za-z_]*:"
color brightcyan "^[[:blank:]]*#[[:blank:]]*(define|undef|include|ifn?def|endif|elif|else|if|warning|error)"
color brightcyan "^[[:blank:]]*#[[:blank:]]*(define|undef|include|ifn?def|endif|elif|else|if|warning|error)\>"
# Strings and names of included files.
color brightyellow ""([^"\]|\\.)*"|<[^= ]*>"

View File

@ -7,7 +7,7 @@ syntax autoconf "\.(ac|m4)$"
comment "#"
# Keywords:
color yellow "\<(if|test|then|elif|else|fi|for|in|do|done)\>"
color yellow "\<(if|test|then|elif|else|fi|case|esac|ifelse|for|in|do|done)\>"
color yellow "=|!=|&&|\|\|"
# Macros:

View File

@ -1,5 +1,7 @@
## Syntax highlighting for AWK scripts.
## Original author: Donnie Berkholz
syntax awk "\.awk$"
header "^#!.*awk"
magic "awk script"
@ -13,8 +15,8 @@ color red "\<(FILENAME|FNR|FS|IGNORECASE|LINT|NF|NR|OFMT|OFS|ORS)\>"
color red "\<(PROCINFO|RS|RT|RSTART|RLENGTH|SUBSEP|TEXTDOMAIN)\>"
# Function declarations and special patterns.
color brightgreen "\<(function|extension|BEGIN|END)\>"
# Operators.
color green "\{|\}|\(|\)|\;|\[|\]|\\|<|>|!|=|&|\+|-|\*|%|/|\?:|\^|\|"
# Operators and brackets/braces/slashes/parentheses.
color green "[][!%&()*+/:;<=>?\^{|}~-]"
# Flow control.
color brightyellow "\<(for|if|while|do|else|in|delete|exit)\>"
color brightyellow "\<(break|continue|return)\>"
@ -30,6 +32,8 @@ color magenta "\<(bindtextdomain|dcgettext|dcngettext)\>"
# Strings.
color brightyellow ""([^"\]|\\.)*""
# Escape sequences.
color brick "\\([abfnrtv\/"]|[0-7]{1,3}|x[[:xdigit:]]{1,2}|u[[:xdigit:]]{1,8})"
# Comments.
color brightblue "(^|[[:blank:]])#.*"

View File

@ -36,7 +36,7 @@ color brightcyan start="^[[:blank:]]*#[[:blank:]]*(if(n?def)?|elif|warning|error
color brightcyan "^[[:blank:]]*#[[:blank:]]*((define|else|endif|include(_next)?|line|undef)\>|$)"
# Comments.
color brightblue "//.*"
color brightblue "//[^"]*$|(^|[[:blank:]])//.*"
color brightblue start="/\*" end="\*/"
# Reminders.

View File

@ -1,5 +1,7 @@
## Syntax highlighting for CMake files.
## Original author: Felipe Bugno
syntax cmake "(CMakeLists\.txt|\.cmake)$"
comment "#"

View File

@ -1,5 +1,7 @@
## Syntax highlighting for CSS files.
## Original author: Simon Rupf
syntax css "\.css$"
comment "/*|*/"

View File

@ -8,8 +8,8 @@ comment "#"
color ,red " + +"
# Nano's release motto, then name plus version.
color italic,lime "\<[Nn]ano [1-7]\.[0-9][-.[:alnum:]]* "[^"]+""
color brightred "\<(GNU )?[Nn]ano [1-7]\.[0-9][-.[:alnum:]]*\>"
color italic,lime "\<[Nn]ano [1-8]\.[0-9][-.[:alnum:]]* "[^"]+""
color brightred "\<(GNU )?[Nn]ano [1-8]\.[0-9][-.[:alnum:]]*\>"
# Dates
color latte "\<[12][0-9]{3}\.(0[1-9]|1[012])\.(0[1-9]|[12][0-9]|3[01])\>"

View File

@ -1,5 +1,7 @@
## Syntax highlighting for Emacs Lisp.
## Original author: Mark Oteiza
syntax elisp "\.el$"
magic "Lisp/Scheme program"
comment ";"

View File

@ -1,5 +1,7 @@
## Syntax highlighting for Fortran 90/95.
## Original author: Pascal Gentil
syntax fortran "\.(f|for|f90|f95)$"
comment "!"
@ -10,7 +12,7 @@ icolor green "\<(append|asis|assign|assignment|associated|character|common)\>"
icolor green "\<(complex|data|default|delim|dimension|double precision)\>"
icolor green "\<(elemental|epsilon|external|file|fmt|form|format|huge)\>"
icolor green "\<(implicit|include|index|inquire|integer|intent|interface)\>"
icolor green "\<(intrinsic|iostat|kind|logical|module|none|null|only)>"
icolor green "\<(intrinsic|iostat|kind|logical|module|none|null|only)\>"
icolor green "\<(operator|optional|pack|parameter|pointer|position|private)\>"
icolor green "\<(program|public|real|recl|recursive|selected_int_kind)\>"
icolor green "\<(selected_real_kind|subroutine|status)\>"

View File

@ -1,5 +1,7 @@
## Syntax highlighting for POV-Ray files.
## Original author: Donnie Berkholz
syntax pov "\.(pov|POV|povray|POVRAY)$"
comment "//"

View File

@ -1,5 +1,7 @@
## Syntax highlighting for RPM spec files.
## Original author: Asterios Dramis
syntax spec "\.spec(\.[^/]+)?$"
comment "#"
@ -12,7 +14,9 @@ color brightblue "\<(AutoReq|AutoProv|AutoReqProv)[[:space:]]*:"
color brightblue "\<(License|Copyright|Distribution|Vendor|Packager)[[:space:]]*:"
color brightblue "\<((Source|Patch)[0-9]*|Nosource|Nopatch)[[:space:]]*:"
# Architectures.
color brightred "\<(i386|i486|i586|i686|athlon|ia64|alpha|alphaev5|alphaev56|alphapca56|alphaev6|alphaev67|sparc|sparcv9|sparc64armv3l|armv4b|armv4lm|ips|mipsel|ppc|ppciseries|ppcpseries|ppc64|m68k|m68kmint|Sgi|rs6000|i370|s390x?|noarch)\>"
color brightred "\<((a|loong)arch64|alpha(ev(56?|67?)|pca56)?|amd64|armv(3l|4b|4l|5t(ej?)?l|6h?l|7(hn?)?l|8h?l)|athlon|em64t|geode|i370|i(3|4|5|6)86|ia32e|ia64|m68k(mint)?|mips(64)?(el|r6|r6el)?)\>"
color brightred "\<(pentium(3|4)|ppc(32dy4|8260|8560)?|ppc64(le|p7)?|ppc(64)?(i|p)series|riscv64|rs6000|s390x?|sgi|sh(3|4|4a)?|sparc(64v?|v8|v9v?)?|x86_64(_v2|_v3|_v4)?|xtensa)\>"
# Architecture and OS conditionals.
color brightred "%(ifarch|elifarch|ifnarch|ifos|elifos|ifnos)\>"
# %* strings.

View File

@ -1,6 +1,8 @@
## Syntax highlighting for groff.
syntax groff "\.(m[ems]|rof|tmac)$|/tmac\.[^/]+$"
## Original author: Robert D. Goulding
syntax groff "\.(me|mm|mom|ms|roff|tmac)$|/tmac\.[^/]+$"
comment ".\""
# The setting of a string or register
@ -23,4 +25,4 @@ color green start="\\(\\)?\*\[" end="]"
color brightred "\\\(.."
color brightred start="\\\[" end="]"
# Macro arguments
color brightcyan "\\\\\$[1-9]"
color brightcyan "\\\\\$[0-9]"

View File

@ -1,5 +1,7 @@
## Syntax highlighting for Guile Scheme.
## Original author: Mark Oteiza
syntax guile "\.scm$"
header "^#!.*guile"
comment ";"

View File

@ -1,6 +1,7 @@
## Syntax highlighting for Javascript.
syntax javascript "\.js$"
syntax javascript "\.m?js$"
magic "JavaScript source"
comment "//"
# Declarational stuff.

View File

@ -1,7 +1,9 @@
## Syntax highlighting for Makefiles.
syntax makefile "(/((GNU)?m|M)akefile[^/]*$|\.(make|mk)$)"
syntax makefile "(^|/)((GNU)?m|M)akefile[^/]*$|\.(make|mk)$"
magic "makefile script"
tabgives " "
comment "#"
# Assignments.
@ -15,7 +17,7 @@ color magenta "^((override +)?(un)?define|endef|(un)?export|private|vpath)\>"
color blue "\$+[{(][a-zA-Z0-9_-]+[})]"
# Targets.
color brightblue "^[^ ]+:"
color brightblue "^[^ ].*:"
# Comments.
color green "(^|[[:blank:]]+)#.*"

View File

@ -1,20 +1,26 @@
## Syntax highlighting for man pages.
## Original author: Mike Frysinger
syntax man "\.[1-9]x?$"
magic "troff or preprocessor input"
comment ".\""
# Section headers, title line, and indented paragraphs.
# Section headers, title line, and paragraphs.
color green "^\.(SH|SS|TH) .*"
color brightgreen "^\.((SH|SS|TH) |[HIT]P)"
# Type faces, and normal paragraphs.
color brightred "^\.(B[IR]?|I[BR]?|R[BI]|S[BM]) .*"
color brightblue "^\.((B[IR]?|I[BR]?|R[BI]|S[BM]) |[LP]?P$)"
color brightgreen "^\.((SH|SS|TH) |[HIT]P|TQ|LP$|P?P$)"
# Type faces, and synopses.
color brightred "^\.(B[IR]?|I[BR]?|RB|RI|SB|SM|SY|OP) .*"
color brightblue "^\.((B[IR]?|I[BR]?|RB|RI|SB|SM|SY|OP) |YS$)"
# Inline type faces.
color magenta "\\f[BIPR]"
# Some escapes:
color purple "\\([%&:e~]|\(e[mn])"
# Hyphenation control.
color yellow "^\.(hc|hla|hlm|hw|hy)"
# Relative margins, hyperlinks, and various other stuff.
color yellow "^\.(RS|RE|UR|UE|PD|DT)"
color yellow "^\.(ad|bp|br|ce|de|ds|el|ie|if|fi|ft|hy|ig|in|na|ne|nf|nh|ps|so|sp|ti|tr)"
color yellow "^\.(RS|RE|UR|UE|MT|ME|EX|EE|PD|DT)"
color yellow "^\.(ad|bp|br|ce|de|ds|el|ie|if|fi|ft|ig|in|na|ne|nf|nh|ps|so|sp|ti|tr)"
# Comments.
color cyan "(^\.)?\\".*"

View File

@ -10,7 +10,7 @@ comment "<!--|-->"
color magenta "^[ ]*>.*"
# List-item markers:
color brightmagenta "^( | )* ? ? ?(\*|\+|-|[1-9]+\.)( +| )"
color brightmagenta "^( | )* ? ? ?(\*|\+|-|[0-9]+\.)( +| )"
# Emphasis and strong:
color green "\*[^* ][^*]*\*|_[^_ ][^_]*_"

View File

@ -7,14 +7,14 @@ comment "#"
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|rosy|beet|plum|sea|sky|slate|teal|sage|brown|ocher|sand|tawny|brick|crimson|grey|gray|#[[:xdigit:]]{3})?(,(((light)?(white|black|red|blue|green|yellow|magenta|cyan))|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte|rosy|beet|plum|sea|sky|slate|teal|sage|brown|ocher|sand|tawny|brick|crimson|grey|gray|#[[:xdigit:]]{3}))?\>"
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|rosy|beet|plum|sea|sky|slate|teal|sage|brown|ocher|sand|tawny|brick|crimson|grey|gray|#[[:xdigit:]]{3})?(,((light)?(white|black|red|blue|green|yellow|magenta|cyan)|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte|rosy|beet|plum|sea|sky|slate|teal|sage|brown|ocher|sand|tawny|brick|crimson|grey|gray|#[[:xdigit:]]{3}))?\>"
# The arguments of two special commands
color bold,purple "^[[:blank:]]*include[[:blank:]][^"]*([[:blank:]]|$)"
color bold,purple "^[[:blank:]]*include[[:blank:]]+[^[:blank:]"]+"
color lime "^[[:blank:]]*extendsyntax[[:blank:]]+[[:alpha:]]+[[:blank:]]+(i?color|header|magic|comment|formatter|linter|tabgives)[[:blank:]]+.*"
# The arguments of commands
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|tabstospaces|trimblanks|unix|wordbounds|zap|zero)\>"
color brightgreen "^[[:blank:]]*(set|unset)[[:blank:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|boldtext|bookstyle|breaklonglines|casesensitive|colonparsing|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|tabstospaces|trimblanks|unix|wordbounds|zap|zero)\>"
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|execute|browser|whereisfile|gotodir|spell|linter|all)\>"
@ -29,7 +29,7 @@ color brightmagenta "[[:blank:]](start=)?".+""
color crimson "\{(help|cancel|exit|savefile|writeout|discardbuffer|insert|where(is|was)|find(previous|next|bracket)|replace)\}"
color crimson "\{(cut|copy|paste|zap|chopword(left|right)|cutrestoffile|execute|mark|speller|linter|formatter|(full)?justify)\}"
color crimson "\{(location|gotoline|(begin|end)para|comment|complete|(un)?indent|wordcount|(record|run)macro|anchor|undo|redo)\}"
color crimson "\{(left|right|up|down|home|end|(scroll|page)(up|down)|center|(prev|next)(word|block|anchor|buf))\}"
color crimson "\{(left|right|up|down|home|end|(scroll|page)(up|down)|(top|bottom)row|center|cycle|(prev|next)(word|block|anchor|buf))\}"
color crimson "\{(tab|enter|delete|backspace|verbatim|refresh|suspend|casesens|regexp|backwards|older|newer|(dos|mac)format)\}"
color crimson "\{(append|prepend|backup|flip(goto|replace|execute|pipe|convert|newbuffer)|browser|gotodir|(first|last)(file|line))\}"
color crimson "\{(nohelp|constantshow|softwrap|linenumbers|whitespacedisplay|nosyntax|zero)\}"

View File

@ -1,5 +1,7 @@
## Syntax highlighting for C/C++/Obj-C files.
## Original author: Dave Geering
syntax m "\.m$"
magic "Objective-C source"
comment "//"

View File

@ -1,6 +1,8 @@
## Syntax highlighting for patch and diff files.
syntax patch "\.(patch|diff|debdiff)$"
## Original author: Mike Frysinger
syntax patch "\.(patch|diff|debdiff|rej)$"
magic "diff output"
# There is no official support for comments in patch files.
comment ""

View File

@ -1,5 +1,7 @@
## Syntax highlighting for PHP.
## Original author: Mike Frysinger
syntax php "\.(php[23457s~]?|phtml|ctp)$"
magic "PHP script"
comment "//"

View File

@ -16,16 +16,19 @@ color cyan "\<(POT-Creation-Date|PO-Revision-Date|MIME-Version|Content-Type|Cont
# Encodings and numbers.
color yellow "\<(UTF|ISO|Windows|Mac|IBM)-[0-9]+"
color yellow "\<((pre|rc)?[0-9]+|[0-9]bit)\>"
# Msgids.
# Main keywords.
color brightblue "^(msgid|msgid_plural|msgstr)\>"
# Tags.
# Flags.
color red " fuzzy(,|$)"
color yellow " (no-)?[-[:alpha:]]+-format(,|$)"
color yellow " (no-)?([a-z-]+|c\+\+)-format(,|$)"
# Format specifiers.
color brightmagenta "%([1-9]\$)?[#0 +'I-]?(\*([1-9]\$)?|[1-9](\.[0-9]?)?)?[hlLjzt]?[diouxXeEfFgGaAcspnm%]"
color brightmagenta "%([1-9]\$)?[#0 +'I-]?(\*([1-9]\$)?|[0-9]\.?|[0-9]?\.[0-9])?(hh|ll|[hlLjzt])?([diouxXeEfFgGaAcspnmr]|<PRI[diouxX](32|64)>)|%%"
color rosy "%\([[:alpha:]][[:alnum:]_]*\)([0-9]\.?|[0-9]?\.[0-9])?[#0 +-]?[diouxXeEfFgGcrs]"
# Quotes and escaped characters.
color yellow """
color cyan "\\([abcefnrtv"\]|x[[:xdigit:]]{2}|[0-7]{3})"
# Context.
color slate "^msgctxt.*"
# Reminders.
color brightwhite,yellow "\<(FIXME|TODO|XXX)\>"
# Obsolete strings.

View File

@ -1,5 +1,7 @@
## Syntax highlighting for Ruby.
## Original author: John M. Gabriele
syntax ruby "\.rb$"
header "^#!.*ruby"
magic "Ruby script"

View File

@ -1,7 +1,9 @@
## Syntax highlighting for Bourne shell scripts.
syntax sh "(\.sh|(\.|/)(a|ba|c|da|k|mk|pdk|tc|z)sh(rc|_profile)?|/(etc/|\.)profile)$"
header "^#!.*/((env[[:blank:]]+)?((a|ba|c|da|k|mk|pdk|tc|z)?sh)|busybox[[:blank:]]+sh|openrc-run|runscript)\>"
## Original author: Mike Frysinger
syntax sh "(\.sh|(^|/|\.)(a|ba|c|da|k|mk|pdk|tc|z)sh(rc|_profile)?|(/etc/|(^|/)\.)profile)$"
header "^#!.*/(((env|busybox)[[:blank:]]+)?(a|ba|c|da|k|mk|pdk|tc|z)?sh|openrc-run|runscript)\>"
header "-\*-.*shell-script.*-\*-"
magic "(POSIX|Bourne-Again) shell script.*text"
comment "#"

Some files were not shown because too many files have changed in this diff Show More