Compare commits

...

114 Commits

Author SHA1 Message Date
Benno Schulenberg
06c3e1acde po: update translations and regenerate POT file and PO files 2018-05-15 09:14:23 +02:00
Benno Schulenberg
09d8ee82b7 bump version numbers and add a news item for the 2.9.7 release 2018-05-15 08:48:00 +02:00
Benno Schulenberg
dac3b25d16 docs: note a small difference with Pico in the default hard-wrapping 2018-05-14 12:10:38 +02:00
Benno Schulenberg
ca538e6f08 scrolling: only do a scroll when the edit window has more than one row
If the edit window consists of a single row, then the do_up() call has
already brought the desired line into view -- which means that trying
to scroll then (when already on the first line of the file) would fail.

This fixes https://savannah.gnu.org/bugs/?53891.
2018-05-13 19:31:57 +02:00
Benno Schulenberg
4b26308b6a tweaks: put Yes/No/All in a consistent order (for the translators)
So that it matches the order of the preceding Yy/Nn/Aa.
2018-05-13 09:57:49 +02:00
Benno Schulenberg
f5eeb92f40 tweaks: sort an option better, and reschedule a removal 2018-05-13 09:47:40 +02:00
Benno Schulenberg
ae1ba5e259 tweaks: put check for -h and -l options in their alphabetical positions
And put the Pico-compatibility flags last, as normally they are never
given.
2018-05-12 19:56:37 +02:00
Benno Schulenberg
cecf453b14 tweaks: use symbolic names instead of puzzling TRUE and FALSE 2018-05-10 18:19:12 +02:00
Benno Schulenberg
c3a02f8094 tweaks: rename two variables, to be more descriptive 2018-05-10 18:11:35 +02:00
Benno Schulenberg
87283711ee tweaks: improve a couple of comments 2018-05-10 18:10:23 +02:00
Benno Schulenberg
123f77ff1a docs: say thanks to three recent translators, and re-sort two others 2018-05-10 15:17:04 +02:00
Benno Schulenberg
10c49edd3b prompt: when asking for Yes/No/All, recognize also UTF-8 letters
Letters in other scripts than English often consist of multiple bytes.
When in a UTF-8 locale, correctly gather these bytes from the input and
put them together as the single letter that they are, before comparing
this letter against the translated "Yy", "Nn" and "Aa" strings.
2018-05-10 12:29:08 +02:00
Benno Schulenberg
2d5c917b1a signals: exclude the crash handler from the tiny version
The tiny version contains much less code, so is less likely
to crash.  And the users most likely use it for very simple
and short editing jobs, making the chance of a crash still
smaller.  So the handler would just be bloat.
2018-05-10 12:21:53 +02:00
Benno Schulenberg
95002da66c tweaks: normalize indentation and whitespace after previous changes 2018-05-10 11:33:24 +02:00
Mark-Weston
858663444e new feature: an option to make the 'nextword' function stop at word ends
When 'afterends' is set and Ctrl+Right or Shift+Ctrl+Right is pressed,
nano will stop at the ends of words instead of their beginnings.

Signed-off-by: Mark-Weston <markweston@cock.li>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2018-05-10 11:32:01 +02:00
Benno Schulenberg
4046dfca63 docs: break down some old improvements further per version 2018-05-09 11:55:16 +02:00
Benno Schulenberg
c0b15c2982 signals: don't trap segfault/abort when envvar NANO_NOCATCH is defined
When the user wants to get a backtrace, the crash handler shouldn't
kick in.
2018-05-09 11:53:34 +02:00
Devin Hussey
e889c28a95 signals: upon a crash, save changed buffers and reset terminal state
Upon a segmentation fault or an abort signal, instead of crashing,
losing all changes, and leaving the terminal in curses mode, nano
now calls die(), to save any changed buffers and to restore the
terminal to a usable state.

For the remote chance that nano segfaults in die(), the handler for
SIGSEGV and for SIGABRT is reset to its default value as soon as the
signal fires, to prevent a crash-handler loop.

Since a core dump is usually more helpful for debugging, the crash
handler is not included in a debug build.

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

Signed-off-by: Devin Hussey <husseydevin@gmail.com>
2018-05-06 16:36:25 +02:00
Benno Schulenberg
0da554e6d7 startup: suggest using ^D to finish reading from standard input
Also, add a period after the "Read nn lines" message, and
don't let the next shell prompt overwrite this message.

This addresses https://savannah.gnu.org/bugs/?53779.
2018-05-01 11:15:19 +02:00
Benno Schulenberg
f1530c7ba0 docs: add notes about deprecated options and function names
Also remove two notes that are obsolete by now.
2018-04-30 15:28:47 +02:00
Benno Schulenberg
0e46c0f4a5 main: clear a spurious error number, to avoid irrelevant messages later
This addresses https://savannah.gnu.org/bugs/?53777.
2018-04-29 12:08:42 +02:00
Benno Schulenberg
6a064503e5 docs: slightly improve the description of the file browser in the manual 2018-04-28 12:34:39 +02:00
Benno Schulenberg
4d92dffb3a bindings: rename constupdate to constantshow, cuttoend to cutfromcursor
This makes the names of these bindable functions equal to the names of
their corresponding options -- like for all the other toggles that have
a corresponding option.
2018-04-28 12:01:23 +02:00
Benno Schulenberg
4c1c425bbb bindings: add the 'linenumbers' bindable function
This makes the line-numbers toggle rebindable, like all the others.
2018-04-28 11:44:53 +02:00
Benno Schulenberg
21a54a3cf6 syntax: po: highlight also other escaped characters, not just \n 2018-04-27 11:17:12 +02:00
Benno Schulenberg
a0147c5a72 bump version numbers and add a news item for the 2.9.6 release 2018-04-27 10:56:10 +02:00
Benno Schulenberg
553940760e tweaks: set the correct flags just once for each spell-fixing session 2018-04-25 17:27:15 +02:00
Benno Schulenberg
faa0eb991e speller: don't add an extra newline when saving the text to a tempfile
Set the NO_NEWLINES flag to achieve this.  And move the saving and
restoring of the global flags to the main speller routine, so the
flags aren't saved and restored for each internal spell fix.

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

Acked-by: David Lawrence Ramsey <pooka109@gmail.com>
2018-04-25 17:26:14 +02:00
Benno Schulenberg
f54cd02652 tweaks: adjust the translator hint about Yes/No/All
There is no longer any need to burden the translators with also
providing the English letters.
2018-04-25 17:14:33 +02:00
Benno Schulenberg
6dd308d0fb prompt: recognize Yes/No/All in English when the locale gives no match 2018-04-25 17:03:13 +02:00
Benno Schulenberg
4872f42cd2 tweaks: rename a function, to be more distinct from its caller 2018-04-25 12:21:40 +02:00
Benno Schulenberg
62007c84c6 tweaks: invert two conditions and reshuffle, to reduce duplication 2018-04-24 13:27:57 +02:00
Benno Schulenberg
d0f37205af search: always go forward by default, also when coming from Goto-Line
This fixes https://savannah.gnu.org/bugs/?53735.
2018-04-24 13:13:38 +02:00
Benno Schulenberg
f05874ea23 gnulib: update to its current upstream state 2018-04-24 10:02:04 +02:00
Benno Schulenberg
0d9080a22c scrolling: don't redraw entire edit window when cursor goes offscreen
When the cursor is on the top or bottom line of the edit window, and
an <Up> or <Down> pushes the cursor offscreen, then use edit_scroll()
to bring it back into view, instead of using edit_redraw(), because
the latter would redraw *every row* on the screen, which is a waste
of time.

This addresses https://savannah.gnu.org/bugs/?53562.
Reported-by: Devin Hussey <husseydevin@gmail.com>
2018-04-24 09:59:39 +02:00
Benno Schulenberg
1ae90e205a command-execution: do not crash when opening the pipe would fail
This fixes https://savannah.gnu.org/bugs/?53723.
2018-04-23 18:04:25 +02:00
Benno Schulenberg
d53086d38d completion: correctly do a signed comparison, to avoid a segfault
Bug existed since commit 30fc197b (a month ago) which changed the
type of 'i' from int to size_t, causing the comparison to do the
wrong thing when 'threshold' is negative.

This fixes https://savannah.gnu.org/bugs/?53722.
Reported-by: Devin Hussey <husseydevin@gmail.com>
2018-04-23 17:09:54 +02:00
Benno Schulenberg
0b6bb37c56 tweaks: improve some comments, and exit with nonzero status upon error 2018-04-23 14:04:08 +02:00
Benno Schulenberg
c43a6fdcc1 tweaks: rename a variable, to match another and to be more visible 2018-04-23 13:04:31 +02:00
Benno Schulenberg
0c613cb1ac tweaks: rename a variable, to be more clear and to match another 2018-04-23 12:57:58 +02:00
Benno Schulenberg
1e5064ef84 tweaks: fix a typo, remove a blank line, and improve some comments 2018-04-23 12:19:25 +02:00
Benno Schulenberg
5b40bad629 files: prevent a hang when a call to sigaction() would fail
Don't try to re-enter curses mode when the terminal is not in
the correct state yet.

This fixes https://savannah.gnu.org/bugs/?53720.
2018-04-23 11:58:18 +02:00
Benno Schulenberg
45f8fc77e0 tweaks: rename a variable, to be a bit more fitting 2018-04-22 12:05:19 +02:00
Benno Schulenberg
94347f0811 memory: use a reallocation to reduce the amount of leakage 2018-04-22 12:00:26 +02:00
Benno Schulenberg
1a4a3de68b formatting, linting: redetermine the argument list for every run
The formatter or linter might have changed in the meantime -- when
the filename was changed to have a different extension, for example.

This fixes https://savannah.gnu.org/bugs/?53716.
2018-04-22 11:44:07 +02:00
Benno Schulenberg
bf8bd02558 build: do not prefix an alternative rcfilename with a dot
When the user configures nano with --enable-altrcname=name,
the specified name should not be prefixed with a dot.

This fixes https://savannah.gnu.org/bugs/?53694.
Reported-by: Cody A. Taylor <codemister99@yahoo.com>
2018-04-21 10:03:30 +02:00
Benno Schulenberg
544d426d86 tweaks: group some more of the empty functions together 2018-04-17 10:34:57 +02:00
Benno Schulenberg
30a984661b syntax: po: highlight also other escaped characters, not just \n
Especially color \a and \t, to make it easier to distinguish them
from contiguous text.
2018-04-17 09:56:19 +02:00
Benno Schulenberg
7ab8a4d835 tweaks: improve the ordering of a couple of functions 2018-04-13 21:09:44 +02:00
Benno Schulenberg
0353a24400 tweaks: rearrange a few if statements more symmetrically 2018-04-13 20:43:08 +02:00
Benno Schulenberg
d4304ca88c search: use a better value to mean "nothing was typed"
When the keyboard buffer is empty, return a value that is not equivalent
to <Ctrl+Space>, so that typing a bunch of these while searching is going
on will not result in some of them getting executed afterward.
2018-04-13 20:13:05 +02:00
Benno Schulenberg
02d8da3bdd tweaks: rename a function, to be more fitting and descriptive
It is not an abort but simply a bit of cleaning up.
2018-04-13 10:32:29 +02:00
Benno Schulenberg
7a09b655c1 tweaks: rename a variable, for clarity 2018-04-13 10:22:39 +02:00
Benno Schulenberg
c8b26baee8 tweaks: elide a function that is called just once
Also adjust and correct a comment.
2018-04-13 10:17:08 +02:00
Liu Hao
bb394990cd replacing: always clear the backwards flag for ^\, just like for ^W
This makes it easier to predict in which direction the replacements
will go when hitting ^\ or M-R.

Signed-off-by: Liu Hao <lh_mouse@126.com>
2018-04-12 20:32:15 +02:00
Benno Schulenberg
7c5d099c6f tweaks: frob a couple of comments 2018-04-01 21:07:18 +02:00
Benno Schulenberg
152cc24d1f tweaks: reshuffle two declarations 2018-04-01 20:08:57 +02:00
Benno Schulenberg
8965103a4d tweaks: remove the group handling for undoing/redoing (un)indents
Indenting/unindenting always happens in a single contiguous block.
Lines that cannot or should not be indented or unindented do not
need to remembered separately as it follows from their content.
2018-04-01 11:41:26 +02:00
Benno Schulenberg
d0d293b8af tweaks: correct or improve a couple of comments 2018-04-01 11:24:44 +02:00
Benno Schulenberg
839743fd24 tweaks: move a function to its proper location 2018-04-01 10:54:14 +02:00
Benno Schulenberg
0b30835dd0 tweaks: use meaningful names instead of puzzling values
Suggested-by: Brand Huntsman <alpha@qzx.com>
2018-04-01 09:49:58 +02:00
Benno Schulenberg
a865c25eea build: fix compilation when configured with --disable-help
This fixes https://savannah.gnu.org/bugs/?53532.
2018-03-31 16:52:22 +02:00
Benno Schulenberg
cf1129a8b4 syntax: sh: colorize options only when they are preceded by whitespace
To prevent any filenames containing hyphens getting partially colored.

Reported-by: Brand Huntsman <alpha@qzx.com>
2018-03-30 10:46:56 +02:00
Benno Schulenberg
0cd833e64b tweaks: move a function to its proper location
Put it after the function that it calls, and before the functions
it is called from.
2018-03-30 10:34:40 +02:00
Benno Schulenberg
cbf226476d rcfile: skip color commands where some color name is invalid
That is, do not fall back to the default background color when the
name for the background color is invalid, but reject the entire
color command, just like for an invalid foreground color.
2018-03-30 10:30:55 +02:00
Benno Schulenberg
9fcfee18e8 po: update translations and regenerate POT file and PO files 2018-03-29 10:17:00 +02:00
Benno Schulenberg
27eccbec23 bump version numbers and add a news item for the 2.9.5 release 2018-03-29 09:59:13 +02:00
Benno Schulenberg
0bce5ba4d9 syntax: sh: color options distinctively, and color also long options
Also add some comments, and accept hyphens in function names.
2018-03-29 09:51:39 +02:00
Benno Schulenberg
f9415e347a docs: clarify how the Linux console is deficient: in the arrow keys 2018-03-28 19:34:26 +02:00
Benno Schulenberg
f3c4dadcf6 build: fix compilation with --enable-{tiny,help,multibuffer} 2018-03-28 16:37:47 +02:00
Benno Schulenberg
20d1823d90 syntax: sh: uncolor "tar" when it's part of a filename 2018-03-28 14:04:00 +02:00
Benno Schulenberg
e01bcddf16 docs: document the newly added color name "normal" 2018-03-28 14:03:52 +02:00
Benno Schulenberg
570fb6c606 small addition: understand color name "normal" to mean the default color
This allows a syntax to remove the color from things that were colored
overeagerly by earlier regexes.
2018-03-28 14:03:22 +02:00
Benno Schulenberg
1de3667555 syntax: sh: color also the 'cut', 'head', 'tail', and 'sort' commands 2018-03-27 14:09:38 +02:00
Benno Schulenberg
5726514869 linting: drop messages for other files when configured for one buffer
This fixes https://savannah.gnu.org/bugs/?53445.
2018-03-26 08:56:03 +02:00
Benno Schulenberg
88234c90bc tweaks: adjust the indentation after the previous changes 2018-03-26 08:53:06 +02:00
Benno Schulenberg
02719ec4bf tweaks: fuse two ifs into one 2018-03-26 08:52:51 +02:00
Benno Schulenberg
415bf82690 tweaks: move an 'if' and then remove an unneeded label 2018-03-26 08:52:04 +02:00
Benno Schulenberg
9bce8bfeb3 build: fix compilation when configured with --disable-multibuffer 2018-03-23 19:14:56 +01:00
Benno Schulenberg
2c024a74a9 tweaks: adjust or correct some comments, and rename a function
Also, reshuffle a condition so it takes up less space.
2018-03-23 17:54:06 +01:00
Benno Schulenberg
ab8698df47 tweaks: condense some code, to remove a bit of duplication 2018-03-23 17:14:39 +01:00
Benno Schulenberg
206d89b739 tweaks: revert commit c88a2fd9 -- the extra variable is needed
This variable will be modified by go_forward_chunks(), but the value
of openfile->current itself should be maintained.
2018-03-23 11:31:08 +01:00
Benno Schulenberg
eff2e0e291 help: describe the Scroll-Up and Scroll-Down commands more precisely
An "if possible" would have been nice, but there is no room for that.
2018-03-23 11:10:19 +01:00
Benno Schulenberg
c5e20164c3 tweaks: rewrap and amend some lines in the NEWS file 2018-03-23 11:09:59 +01:00
Benno Schulenberg
0f1f53a441 tweaks: drop a handful of unhelpful asserts 2018-03-23 11:09:56 +01:00
Benno Schulenberg
bf1a080923 build: exclude more things when configured with --disable-multibuffer
This will make the tiny version slightly smaller.
2018-03-23 11:09:37 +01:00
Benno Schulenberg
b7f8d4819b tweaks: frob some comments plus miscellaneous other stuff 2018-03-22 19:54:20 +01:00
Benno Schulenberg
30fc197b66 tweaks: adjust a couple of types, to reduce the number of warnings
This avoids eleven warnings of the kind "comparison between signed
and unsigned integer expressions [-Wsign-compare]".
2018-03-22 19:33:22 +01:00
Benno Schulenberg
c88a2fd9ca tweaks: elide an unneeded and shadowing variable 2018-03-22 15:20:05 +01:00
Benno Schulenberg
b9de5525c4 tweaks: elide a parameter, as it's always the inverse of another 2018-03-22 12:52:28 +01:00
Benno Schulenberg
f4d1ef1c4e tweaks: remove unneeded settings and unsettings of MULTIBUFFER
In the preceding commit, open_buffer() was changed so that it gets
told whether to load into a new buffer or not, so it is no longer
needed to convey this information through a flag.
2018-03-22 12:50:48 +01:00
Benno Schulenberg
dd157f1494 tweaks: change a parameter of open_buffer() and invert its logic 2018-03-22 12:35:50 +01:00
Benno Schulenberg
624918800b tweaks: bundle some settings for a new buffer 2018-03-22 12:27:04 +01:00
Benno Schulenberg
8b8c6bb818 tweaks: factor out the check for 'viewok' into its own function
And also prevent a theoretical crash for restricted prompt functions.
2018-03-20 20:10:08 +01:00
Kamil Dudka
b830a7dd38 input: do not crash if sctofunc() returns NULL
This fixes a regression introduced by commit 54103d8e: a crash that
can be triggered by running 'nano --restrict' and pressing <Insert>.

This addresses https://bugzilla.redhat.com/1558532.
2018-03-20 19:36:55 +01:00
Benno Schulenberg
3e5b0ea5fd files: prevent an infinite loop when reading from standard input fails 2018-03-20 11:25:16 +01:00
Benno Schulenberg
a1132c81a1 files: prevent the undo of reading a file into a new buffer
When the file has just been read, it is in the state that it has
on disk, so there is nothing to undo.

This fixes https://savannah.gnu.org/bugs/?53387.
2018-03-20 11:14:55 +01:00
Liu Hao
0496aed4ab build: fix compilation error when configured with --disable-justify
Signed-off-by: Liu Hao <lh_mouse@126.com>
2018-03-19 13:39:15 +01:00
Benno Schulenberg
373e3b880f scrolling: first move the cursor before pushing current chunk offscreen
When the cursor is on the first or last row of the edit window, and
thus Scroll-Down or Scroll-Up would push it offscreen, first move
the cursor away from the edge row and then scroll.

This fixes https://savannah.gnu.org/bugs/?53376.
2018-03-18 20:06:29 +01:00
David Lawrence Ramsey
7b1f3f4fe7 tweaks: correct several parameter types
This avoids a bunch of warnings when compiled with -pedantic:

	ISO C forbids comparison of ‘void *’ with function pointer
2018-03-18 20:01:25 +01:00
Benno Schulenberg
9517972b58 build: fix compilation again when configured with --enable-tiny 2018-03-18 16:33:21 +01:00
Benno Schulenberg
95989e7dfe selecting: don't cancel a softmark when just scrolling the screen
As, since commit 0e30177d, the scrollup and scrolldown commands
no longer intend to move the cursor, they should not be seen as
movement functions.

Also, it is not guaranteed that functions are ordered in the same
way in the binary as in the source code, so an ordered comparison
of function pointers will not always work.

This fixes https://savannah.gnu.org/bugs/?53333.
2018-03-18 13:55:29 +01:00
Benno Schulenberg
dcda98fb73 tweaks: remove an inconsistent space from two pointer declarations
Reported-by: Brand Huntsman <alpha@qzx.com>
2018-03-17 15:53:22 +01:00
Benno Schulenberg
336fa40055 docs: clarify what the scrollup and scrolldown bindable functions do 2018-03-17 14:27:23 +01:00
Benno Schulenberg
93318b972d tweaks: elide two parameters and thus a pair of wrapper functions
When just scrolling and the cursor does not need to change position
(that is: it is not on the first or last row of the edit window),
then edit_scroll() has handled everything and there is no need to
additionally redraw anything or update 'placewewant'.
2018-03-17 14:07:42 +01:00
Benno Schulenberg
8656f160d7 tweaks: reshuffle some movement code, to reduce the number of conditions
Also, rename a parameter and invert its logic.
2018-03-17 14:02:55 +01:00
Benno Schulenberg
0e30177db7 scrolling: let Scroll-Up/Down keep the cursor in the same text position
Instead of keeping the cursor in the same spot on the screen,
let the cursor move with the text (whenever possible).

This makes these functions behave the same as in Vim and Emacs.
2018-03-17 14:00:00 +01:00
Benno Schulenberg
3089a98169 tweaks: fix a typo and adjust some wording and formatting in the FAQ 2018-03-12 11:43:43 +01:00
Benno Schulenberg
1b704e7c8c tweaks: reduce the font size of the questions in the FAQ
Make them smaller to make them sound less like shouting.
2018-03-12 11:25:03 +01:00
Benno Schulenberg
efb9192ee5 docs: mention in the FAQ that <Shift+Insert> pastes from the clipboard
This kind of addresses https://savannah.gnu.org/bugs/?53310.
2018-03-12 11:21:26 +01:00
Benno Schulenberg
f0734dae3e cut: avoid calling renumber() on what might be NULL
This fixes https://savannah.gnu.org/bugs/?53317.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2018-03-12 10:46:02 +01:00
Benno Schulenberg
e8505b2d3e memory: plug a leak, by actually freeing a discarded undo struct
This fixes https://savannah.gnu.org/bugs/?53269.
Reported-by: Ashish Kunwar <dorkerdevil280@gmail.com>

The leak was mistakenly introduced by commit dc3618a1
-- probably as a leftover of testing things.
2018-03-11 20:16:09 +01:00
Benno Schulenberg
1ebb1da382 tweaks: elide a parameter that is always 1
And adjust the comments accordingly.
2018-03-10 12:43:33 +01:00
Benno Schulenberg
1fb3218a14 help: do not reserve space for line numbers, as they are absent
Help texts are shown without any line numbers, so the full width
of the screen should be used to display the text.

This fixes https://savannah.gnu.org/bugs/?53308.
2018-03-09 12:03:48 +01:00
66 changed files with 21495 additions and 20940 deletions

141
ChangeLog
View File

@@ -1,3 +1,144 @@
Changes between v2.9.6 and v2.9.7:
----------------------------------
Benno Schulenberg (21):
bindings: add the 'linenumbers' bindable function
bindings: rename constupdate to constantshow, cuttoend to cutfromcursor
bump version numbers and add a news item for the 2.9.7 release
docs: add notes about deprecated options and function names
docs: break down some old improvements further per version
docs: note a small difference with Pico in the default hard-wrapping
docs: say thanks to three recent translators, and re-sort two others
docs: slightly improve the description of the file browser in the manual
main: clear a spurious error number, to avoid irrelevant messages later
prompt: when asking for Yes/No/All, recognize also UTF-8 letters
scrolling: only do a scroll when the edit window has more than one row
signals: don't trap segfault/abort when envvar NANO_NOCATCH is defined
signals: exclude the crash handler from the tiny version
startup: suggest using ^D to finish reading from standard input
tweaks: improve a couple of comments
tweaks: normalize indentation and whitespace after previous changes
tweaks: put check for -h and -l options in their alphabetical positions
tweaks: put Yes/No/All in a consistent order (for the translators)
tweaks: rename two variables, to be more descriptive
tweaks: sort an option better, and reschedule a removal
tweaks: use symbolic names instead of puzzling TRUE and FALSE
Devin Hussey (1):
signals: upon a crash, save changed buffers and reset terminal state
Mark-Weston (1):
new feature: an option to make the 'nextword' function stop at word ends
Changes between v2.9.5 and v2.9.6:
----------------------------------
Benno Schulenberg (39):
build: do not prefix an alternative rcfilename with a dot
build: fix compilation when configured with --disable-help
bump version numbers and add a news item for the 2.9.6 release
command-execution: do not crash when opening the pipe would fail
completion: correctly do a signed comparison, to avoid a segfault
files: prevent a hang when a call to sigaction() would fail
formatting, linting: redetermine the argument list for every run
gnulib: update to its current upstream state
memory: use a reallocation to reduce the amount of leakage
prompt: recognize Yes/No/All in English when the locale gives no match
rcfile: skip color commands where some color name is invalid
scrolling: don't redraw entire edit window when cursor goes offscreen
search: always go forward by default, also when coming from Goto-Line
search: use a better value to mean "nothing was typed"
speller: don't add an extra newline when saving the text to a tempfile
syntax: po: highlight also other escaped characters, not just \n
syntax: sh: colorize options only when they are preceded by whitespace
tweaks: adjust the translator hint about Yes/No/All
tweaks: correct or improve a couple of comments
tweaks: elide a function that is called just once
tweaks: fix a typo, remove a blank line, and improve some comments
tweaks: frob a couple of comments
tweaks: group some more of the empty functions together
tweaks: improve some comments, and exit with nonzero status upon error
tweaks: improve the ordering of a couple of functions
tweaks: invert two conditions and reshuffle, to reduce duplication
tweaks: move a function to its proper location
tweaks: move a function to its proper location
tweaks: rearrange a few if statements more symmetrically
tweaks: remove the group handling for undoing/redoing (un)indents
tweaks: rename a function, to be more distinct from its caller
tweaks: rename a function, to be more fitting and descriptive
tweaks: rename a variable, for clarity
tweaks: rename a variable, to be a bit more fitting
tweaks: rename a variable, to be more clear and to match another
tweaks: rename a variable, to match another and to be more visible
tweaks: reshuffle two declarations
tweaks: set the correct flags just once for each spell-fixing session
tweaks: use meaningful names instead of puzzling values
Liu Hao (1):
replacing: always clear the backwards flag for ^\, just like for ^W
Changes between v2.9.4 and v2.9.5:
----------------------------------
Benno Schulenberg (45):
build: exclude more things when configured with --disable-multibuffer
build: fix compilation again when configured with --enable-tiny
build: fix compilation when configured with --disable-multibuffer
build: fix compilation with --enable-{tiny,help,multibuffer}
bump version numbers and add a news item for the 2.9.5 release
cut: avoid calling renumber() on what might be NULL
docs: clarify how the Linux console is deficient: in the arrow keys
docs: clarify what the scrollup and scrolldown bindable functions do
docs: document the newly added color name "normal"
docs: mention in the FAQ that <Shift+Insert> pastes from the clipboard
files: prevent an infinite loop when reading from standard input fails
files: prevent the undo of reading a file into a new buffer
help: describe the Scroll-Up and Scroll-Down commands more precisely
help: do not reserve space for line numbers, as they are absent
linting: drop messages for other files when configured for one buffer
memory: plug a leak, by actually freeing a discarded undo struct
scrolling: first move the cursor before pushing current chunk offscreen
scrolling: let Scroll-Up/Down keep the cursor in the same text position
selecting: don't cancel a softmark when just scrolling the screen
small addition: understand color name "normal" to mean the default color
syntax: sh: color also the 'cut', 'head', 'tail', and 'sort' commands
syntax: sh: color options distinctively, and color also long options
syntax: sh: uncolor "tar" when it's part of a filename
tweaks: adjust a couple of types, to reduce the number of warnings
tweaks: adjust or correct some comments, and rename a function
tweaks: adjust the indentation after the previous changes
tweaks: bundle some settings for a new buffer
tweaks: change a parameter of open_buffer() and invert its logic
tweaks: condense some code, to remove a bit of duplication
tweaks: drop a handful of unhelpful asserts
tweaks: elide an unneeded and shadowing variable
tweaks: elide a parameter, as it's always the inverse of another
tweaks: elide a parameter that is always 1
tweaks: elide two parameters and thus a pair of wrapper functions
tweaks: factor out the check for 'viewok' into its own function
tweaks: fix a typo and adjust some wording and formatting in the FAQ
tweaks: frob some comments plus miscellaneous other stuff
tweaks: fuse two ifs into one
tweaks: move an 'if' and then remove an unneeded label
tweaks: reduce the font size of the questions in the FAQ
tweaks: remove an inconsistent space from two pointer declarations
tweaks: remove unneeded settings and unsettings of MULTIBUFFER
tweaks: reshuffle some movement code, to reduce the number of conditions
tweaks: revert commit c88a2fd9 -- the extra variable is needed
tweaks: rewrap and amend some lines in the NEWS file
David Lawrence Ramsey (1):
tweaks: correct several parameter types
Kamil Dudka (1):
input: do not crash if sctofunc() returns NULL
Liu Hao (1):
build: fix compilation error when configured with --disable-justify
Changes between v2.9.3 and v2.9.4:
----------------------------------

View File

@@ -2,6 +2,9 @@ Improvements in GNU nano
========================
Since 2.9.0:
- Option 'set afterends' for making Ctrl+Right stop at word ends.
- A crash handler that saves changed buffers in case of a crash.
- Addition of the color name "normal", meaning the default color.
- A key can be bound to a string -- any mix of text and commands.
- Error messages are shown by default in bright white on red.
- <Tab> and <Shift+Tab> can be used to indent/unindent a marked region.
@@ -33,24 +36,25 @@ Since 2.6.0:
- The option 'wordchars' for specifying extra word characters.
- Hi-bit control characters are shown in a more readable manner.
- The ability to use negative numbers at the Go To Line prompt.
Noteworthy changes since 2.2
----------------------------
- The ability to comment/uncomment lines with a single keystroke (M-3).
- The ability to refresh the file list in the browser (^L).
- The ability to abort re-searches (^C after an M-W).
- Better feedback at startup when opening large or multiple files.
Since 2.5.0:
- The option 'justifytrim' for snipping whitespace from justified lines.
- The ability to discard a buffer (^O ^Q) when --tempfile is used.
- Replacing things in a marked region now takes place in situ, in context,
instead of changing the view to only the marked text.
- On some terminals Ctrl+Left / Ctrl+Right now work for PrevWord/NextWord.
- On most terminals Ctrl+Left / Ctrl+Right now work for PrevWord/NextWord.
- When in the middle of a word, PrevWord now jumps to the start of this
word (like Pico does) instead of to the start of the preceding word.
Since 2.4.0:
- Replacing things in a marked region now takes place in situ, in context,
instead of changing the view to only the marked text.
- Invalid byte sequences are properly displayed and not mistakenly found.
- Resizing the window does not exit from help viewer nor file browser.
- Improved arrangement of the shortcuts in the two help lines.
- Several small bug fixes in the syntax highlighting.
Since 2.3.0:
- System syntaxes can be improved upon with the 'extendsyntax' command.
- The ability to delete whole words with 'cutwordleft' and 'cutwordright'.
- The ability to save a file without prompting for its name ('savefile').

103
NEWS
View File

@@ -1,3 +1,36 @@
2018.05.15 - GNU nano 2.9.7 "Hvide Sande" adds the option '--afterends'
for making Ctrl+Right (the nextword function) stop at word
ends instead of beginnings, accepts multibyte letters for
the Yes/No/All answers, does emergency saves of changed
buffers in the unlikely event that nano crashes, adds the
until-now missing bindable function 'linenumbers', and
renames the toggles 'constupdate' to 'constantshow' and
'cuttoend' to 'cutfromcursor', for consistency with the
corresponding options -- adjust your nanorc files soon.
2018.04.27 - GNU nano 2.9.6 "Gomance" fixes a crash in word completion,
makes --enable-altrcname work again, improves the fluidity
of scrolling when using the touchpad, tweaks the syntaxes
for shell scripts and PO files, makes a replacing session
go always forward by default, no longer inserts a newline
after an external spell check of a selected region, always
accepts the English Y and N (and A) at a yes-no prompt in
any locale, and solves a few hypothetical bugs.
2018.03.29 - GNU nano 2.9.5 "Kiša pada" changes the way the Scroll-Up
and Scroll-Down commands work (M-- and M-+): instead of
keeping the cursor in the same screen position they now
keep the cursor in the same text position (if possible).
This version further adds a new color name, "normal",
which gives the default foreground or background color,
which is useful when you want to undo some overzealous
painting by earlier syntax regexes. Bug fixes include:
a segfault when trying to insert a file in restricted
mode, the reading in of a new file being "undoable", a
slight miswrapping of help texts when --linenumbers was
used, and the shell syntax coloring the word "tar" in
file names.
2018.03.08 - GNU nano 2.9.4 "Isabel" allows binding a key to a string
(any piece of text and/or commands), permits customizing
the color of error messages with 'set errorcolor', colors
@@ -192,7 +225,7 @@
option 'set numbercolor'. This release furthermore fixes
some bugs with scrolling in softwrap mode, is more strict
in the parsing of key rebindings, and marks a new buffer
as modified when the output of a command (^R ^X) has been
as modified when the output of a command (^R^X) has been
read into it. Come and check it out!
2016.09.01 - GNU nano 2.7.0 "Suni" adds a new feature: allowing text to
@@ -526,7 +559,7 @@
history. On the features front, nano will now attempt to
retain the proper ownership and permissions when trying
to create a .save file due to receiving a signal. Nano
can also now unbind keys from one or more menus via the
can now also unbind keys from one or more menus via the
'unbind' keyword. Finally, passing --fill or --nowrap on
the command line will now override any related .nanorc
entries. Speak now or forever hold your bugs!
@@ -601,9 +634,9 @@
This release includes a new check for external
modifications when saving a file, some code and
documentation cleanups, and more bug fixes for
the new undo code (but we continue to welcome your bug
reports via the Savannah bug page at
http://savannah.gnu.org/bugs/?func=additem&group=nano.
the new undo code (but we continue to welcome
your bug reports via the Savannah bug page at
http://savannah.gnu.org/bugs/?func=additem&group=nano).
Come get some.
2008.10.03 - GNU nano 2.1.6 was for new features before it was against
@@ -1228,18 +1261,18 @@
with it.
2002.01.05 - GNU nano 1.1.5 is out. The main new feature in this
release is the changed behavior of the keypad. Nano now
does the Right Thing and used keypad() by default. If
you wish to use the keypad arrow keys in certain
terminals, you may use the -K or --keypad flag to use
release is the changed behavior of the keypad. Nano
now does the Right Thing and uses keypad() by default.
If you wish to use the keypad arrow keys in certain
terminals, you may use the -K or --keypad flag to get
the old behavior. Users of other OSes should see better
handling of their non-keypad keys in this release.
Other changes include more Hurd fixes, fixes parsing
the .nanorc, display fixes for the color syntax
highlighting, gettext stabilization and many translation
updates. This is almost like a stable release, much
like in the 0.9.x series when every other release was
the most stable one :) Have fun!
Other changes include more Hurd fixes, fixes parsing the
.nanorc, display fixes for the color syntax highlighting,
gettext stabilization and many translation updates.
This is almost like a stable release, much like in the
0.9.x series when every other release was the most stable
one :) Have fun!
2001.12.11 - GNU nano 1.1.4 is released. This release contains
rudimentary color syntax support (but it's still
@@ -1252,7 +1285,7 @@
2001.10.26 - GNU nano 1.1.3 is released. As far as new features go,
the help system is now available for all functions in
the editor. Also, nano will also now print a message on
the editor. Also, nano will now also print a message on
the status bar when it automatically converts a file
from Mac or DOS format, and trying to load a file that
has already been loaded in multibuffer mode will now
@@ -1382,11 +1415,10 @@
code freeze for nano 1.0. Don't expect (or request) any
new features between now and nano 1.0, only bugfixes,
optimizations and doc/translation updates. For fixes, a
nasty segfault when trying to insert one's home
directory (~), some checks for the NumLock key making
the keypad go awry, window size sanity checks, many
autoconf fixes, and support for the KDE Konsole keypad
layout. Have fun.
nasty segfault when trying to insert one's home directory
(~), some checks for the NumLock key making the keypad go
awry, window size sanity checks, many autoconf fixes, and
support for the KDE Konsole keypad layout. Have fun.
2001.01.07 - Nano 0.9.25 is the "Just one more feature I swear!"
release. It includes one new feature that Pico has had
@@ -1397,13 +1429,13 @@
for crashes when tab completion in certain instances.
Have fun and Happy New Year!
2000.12.18 - Nano 0.9.24 is released. This version contains the last of
the security fixes for writing files, as well as for a
nasty segfault when nano is unable to open a file for
reading, among other fixes. Nano also now cowardly
2000.12.18 - Nano 0.9.24 is released. This version contains the last
of the security fixes for writing files, as well as for
a nasty segfault when nano is unable to open a file for
reading, among other fixes. Nano now also cowardly
refuses to open device files, to stop silly things like
trying to open /dev/zero. New features include being
Able to use Meta-Meta-<key> as Control-<key>, better
able to use Meta-Meta-<key> as Control-<key>, better
HURD support, and some new flags have been added for
Pico compatibility. Upgrading to this version is highly
recommended.
@@ -1495,15 +1527,14 @@
of the curses library used. Yay.
2000.07.27 - Nano 0.9.14 is officially the "13 is so unlucky it should
be skipped as a version number" release. One typo
caused unending problems (calling nano with either -t or
-k caused both flags to be used). The -k code is also
now closer in functionality to Pico's -k mode; please
note that this code is not finished yet. Working on
this code has made me realize that there is not enough
abstraction in the code, and I will be working on that
for the next release. Until then, have fun with this
version.
be skipped as a version number" release. One typo caused
unending problems (calling nano with either -t or -k
caused both flags to be used). The -k code is now also
closer in functionality to Pico's -k mode; please note
that this code is not finished yet. Working on this code
has made me realize that there is not enough abstraction
in the code, and I will be working on that for the next
release. Until then, have fun with this version.
2000.07.23 - Nano 0.9.13 has a few new bits and bobs, most notably the
-k option from Pico (cut to end of line). The majority
@@ -1584,7 +1615,7 @@
concerned with being on the bleeding edge.
2000.04.25 - Nano 0.9.4 fixes some problems in 0.9.3 with the last
line code and related segfaults. It also now has much
line code and related segfaults. It now also has much
better handling for 8-bit characters. The --enable-tiny
code also produces a smaller executable.

7
THANKS
View File

@@ -4,7 +4,7 @@ If we missed you here, let us know!
Translations:
============
Sharuzzaman Ahmat Raslan <sharuzzaman@excite.com> Malay
Pedro Albuquerque <palbuquerque73@gmail.com> Portuguese
Josef Andersson <josef.andersson@fripost.org> Swedish
Laurentiu Buzdugan <buzdugan@voyager.net> Romanian
Mario Blättermann <mario.blaettermann@gmail.com> German
@@ -44,16 +44,18 @@ João Victor Duarte Martins <jvdm@sdf.lonestar.org> Brazilian Portuguese
Pavel Maryanov <acid@jack.kiev.ua> Russian
Daniele Medri <madrid@linux.it> Italian
Gergely Nagy <algernon@debian.org> Hungarian
Claudio Neves <cneves@nextis.com> Brazilian Portuguese
Kalle Olavi Niemitalo <kon@iki.fi> Finnish
Мирослав Николић <miroslavnikolic@rocketmail.com> Serbian
Claudio Neves <cneves@nextis.com> Brazilian Portuguese
Lauri Nurmi <lanurmi@iki.fi> Finnish
Daniel Nylander <po@danielnylander.se> Swedish
Mikel Olasagasti <hey_neken@mundurat.net> Basque
Yi-Jyun Pan <pan93412@gmail.com> Chinese (traditional)
Michael Piefel <piefel@informatik.hu-berlin.de> German
Sergey Poznyakoff <gray@gnu.org> Polish
Božidar Putanec <bozidarp@yahoo.com> Croatian
Trần Ngọc Quân <vnwildman@gmail.com> Vietnamese
Sharuzzaman Ahmat Raslan <sharuzzaman@excite.com> Malay
Sergey A. Ribalchenko <fisher@obu.ck.ua> Ukrainian and Russian
Michel Robitaille <robitail@IRO.UMontreal.CA> French
Christian Rose <menthos@menthos.com> Swedish
@@ -76,6 +78,7 @@ Miquel Vidal <miquel@sindominio.net> Catalan
Phan Vinh Thinh <teppi82@gmail.com> Vietnamese
Pauli Virtanen <pauli.virtanen@saunalahti.fi> Finnish
Aron Xu <happyaron.xu@gmail.com> Chinese (simplified)
Boyuan Yang <073plan@gmail.com> Chinese (simplified)
Peio Ziarsolo <peio@sindominio.net> Basque
Anton Zinoviev <zinoviev@debian.org> Bulgarian

View File

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

View File

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

View File

@@ -7,8 +7,8 @@
<body text="#330000" bgcolor="#ffffff" link="#0000ef" vlink="#51188e" alink="#ff0000">
<h1>The GNU nano editor FAQ</h1>
<h2>Table of Contents</h2>
<h2><a href="#1">1. General</a></h2>
<h3>Table of Contents</h3>
<h3><a href="#1">1. General</a></h3>
<blockquote><p>
<a href="#1.1">1.1. What is GNU nano?</a><br>
<a href="#1.2">1.2. What is the history behind nano?</a><br>
@@ -16,14 +16,14 @@
<a href="#1.4">1.4. What is the current version of nano?</a><br>
<a href="#1.5">1.5. I want to read the manpage without having to download the program!</a>
</p></blockquote>
<h2><a href="#2">2. Where to get GNU nano.</a></h2>
<h3><a href="#2">2. Where to get GNU nano.</a></h3>
<blockquote><p>
<a href="#2.1">2.1. FTP and WWW sites that carry nano.</a><br>
<a href="#2.2">2.2. RedHat and derivatives (.rpm) packages.</a><br>
<a href="#2.3">2.3. Debian (.deb) packages.</a><br>
<a href="#2.4">2.4. By GIT (for the brave).</a>
</p></blockquote>
<h2><a href="#3">3. Installation and Configuration</a></h2>
<h3><a href="#3">3. Installation and Configuration</a></h3>
<blockquote><p>
<a href="#3.1">3.1. How do I install the RPM or DEB package?</a><br>
<a href="#3.2">3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</a><br>
@@ -35,36 +35,37 @@
<a href="#3.9a">3.9a. How do I make a .nanorc file that nano will read when I start it?</a><br>
<a href="#3.9b">3.9b. How about in Win32?</a>
</p></blockquote>
<h2><a href="#4">4. Running</a></h2>
<h3><a href="#4">4. Running</a></h3>
<blockquote><p>
<a href="#4.1">4.1. How do I open a file with a name beginning with '+' from the command line?</a><br>
<a href="#4.2">4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</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.4">4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</a><br>
<a href="#4.5">4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</a><br>
<a href="#4.6">4.6. nano crashes when I type &lt;insert keystroke here&gt;!</a><br>
<a href="#4.6">4.6. nano crashes when I type &lt;insert keystrokes here&gt;!</a><br>
<a href="#4.7">4.7. nano crashes when I resize my window. How can I fix that?</a><br>
<a href="#4.8a">4.8a. When I paste text into a document, each line gets indented further than the last. Why does nano do this, and how can I avoid it?</a><br>
<a href="#4.8b">4.8b. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?<a><br>
<a href="#4.8a">4.8a. With what keystroke can I paste text from the clipboard into nano?</a><br>
<a href="#4.8b">4.8b. 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.8c">4.8c. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?<a><br>
<a href="#4.9">4.9. I've compiled nano with color support, but I don't see any color when I run it!</a><br>
<a href="#4.10">4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</a><br>
<a href="#4.11">4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and nano's mouse support is turned on?</a><br>
<a href="#4.12">4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</a>
</p></blockquote>
<h2><a href="#5">5. Internationalization</a></h2>
<h3><a href="#5">5. Internationalization</a></h3>
<blockquote><p>
<a href="#5.1">5.1. There's no translation for my language!</a><br>
<a href="#5.2">5.2. I don't like the translation for &lt;x&gt; in my language. How can I fix it?</a><br>
<a href="#5.3">5.3. What is the status of Unicode support?</a>
</p></blockquote>
<h2><a href="#6">6. Advocacy and Licensing</a></h2>
<h3><a href="#6">6. Advocacy and Licensing</a></h3>
<blockquote><p>
<a href="#6.1">6.1. Why should I use nano instead of Pico?</a><br>
<a href="#6.2">6.2. Why should I use Pico instead of nano?</a><br>
<a href="#6.3">6.3. What is so bad about the older Pine license?</a><br>
<a href="#6.4">6.4. Okay, well, what mail program should I use then?</a>
</p></blockquote>
<h2><a href="#7">7. Miscellaneous</a></h2>
<h3><a href="#7">7. Miscellaneous</a></h3>
<blockquote><p>
<a href="#7.1">7.1. Where can I ask questions or send suggestions?</a><br>
<a href="#7.2">7.2. How do I submit a bug report or patch?</a><br>
@@ -75,9 +76,9 @@
<hr width="100%">
<h1><a name="1"></a>1. General</h1>
<h2><a name="1.1"></a>1.1. What is GNU nano?</h2>
<h3><a name="1.1"></a>1.1. What is GNU nano?</h3>
<blockquote><p>GNU nano is 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 aims to &quot;emulate Pico as closely as possible and then include extra functionality&quot;.</p></blockquote>
<h2><a name="1.2"></a>1.2. What is the history behind nano?</h2>
<h3><a name="1.2"></a>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>
@@ -87,30 +88,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>
<h2><a name="1.3"></a>1.3. Why the name change from TIP?</h2>
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
<blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program &quot;establishes a full duplex terminal connection to a remote host&quot;, and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote>
<h2><a name="1.4"></a>1.4. What is the current version of nano?</h2>
<blockquote><p>The current version of nano <i>should</i> be <b>2.9.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>
<h2><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h2>
<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>2.9.7</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
<h3><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h3>
<blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/latest/nano.1.html">here</a>.</p></blockquote>
<hr width="100%">
<h1><a name="2"></a>2. Where to get GNU nano.</h1>
<h2><a name="2.1"></a>2.1. Web sites that carry nano.</h2>
<h3><a name="2.1"></a>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/">https://nano-editor.org/dist/</a></li>
<li><a href="https://ftp.gnu.org/gnu/nano/">https://ftp.gnu.org/gnu/nano/</a></li>
</ul>
</blockquote>
<h2><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h2>
<h3><a name="2.2"></a>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>
<h2><a name="2.3"></a>2.3. Deb packages (Debian and derivatives):</h2>
<h3><a name="2.3"></a>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="http://packages.debian.org/stable/editors/nano">stable</a></li>
@@ -119,14 +120,14 @@
</ul>
<p>You can also have a look at the <a href="ftp://ftp.debian.org/debian/pool/main/n/nano/">Package Pool</a> to see all the available binary and source packages.</p>
</blockquote>
<h2><a name="2.4"></a>2.4. By GIT (for the brave).</h2>
<h3><a name="2.4"></a>2.4. By GIT (for the brave).</h3>
<blockquote><p>For the 'bleeding edge' current version of nano, you can use GIT to download the current source code. <b>Note:</b> 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.GIT">the nano GIT document</a> for info on anonymous GIT access to the nano source.</p></blockquote>
<hr width="100%">
<h1><a name="3"></a>3. Installation and Configuration</h1>
<h2><a name="3.1"></a>3.1. How do I install the RPM or DEB package?</h2>
<h3><a name="3.1"></a>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.z-1.i386.rpm</b> if you have a RedHat-ish system or <b>dpkg -i nano_x.y.z-1.deb</b> if you have a Debian-ish system, where <b>x.y.z</b> is the release of nano. There are other programs to install packages, and if you wish to use those, knock yourself out.</p></blockquote>
<h2><a name="3.2"></a>3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h2>
<h3><a name="3.2"></a>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><b>tar -xvf nano-x.y.z.tar.gz</b></p>
<p>Then you need to run <b>configure</b> with any options you might want (if any).</p>
@@ -135,13 +136,13 @@
<b>./configure</b><br>
<b>make</b><br>
<b>make install</b> (as root, of course)</p></blockquote>
<h2><a name="3.3"></a>3.3. Why does everything go into /usr/local?</h2>
<h3><a name="3.3"></a>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><b>./configure --prefix=/usr</b></p>
<p>to put nano into /usr/bin when you run <b>make install</b>.</p></blockquote>
<h2><a name="3.5"></a>3.5. nano should automatically run strip on the binary when installing it!</h2>
<h3><a name="3.5"></a>3.5. nano should automatically run strip on the binary when installing it!</h3>
<blockquote><p>Actually, it does, but you have to use <b>make install-strip</b>. The default make install does not, and will not, run strip automatically.</p></blockquote>
<h2><a name="3.6"></a>3.6. How can I make the executable smaller? This is too bloated!</h2>
<h3><a name="3.6"></a>3.6. 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
@@ -164,49 +165,51 @@
<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 marker code that you use with Control-^ to select text). Also, if you know you aren't going to be using other languages, you can use <b>--disable-nls</b> to disable internationalization and save a few K to a few dozen K depending on whether you have locale support on your system. And finally, there's always good old <b>strip</b> to strip all debugging code and code that exists in libraries on your system.</p>
<p>With <b>--disable-wrapping-as-root</b> you can disable any hard-wrapping by default when the user is root, useful to prevent accidentally changing long lines in system configuration files.</p>
</blockquote>
<h2><a name="3.7"></a>3.7. Tell me more about this multibuffer stuff!</h2>
<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>--multibuffer</b> or <b>-F</b> flag when you invoke nano.</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 file buffer open, the ^X shortcut will say &quot;Close&quot;, instead of the normal &quot;Exit&quot; when only one buffer is open.</p></blockquote>
<h2><a name="3.8"></a>3.8. Tell me more about this verbatim input stuff!</h2>
<h3><a name="3.7"></a>3.7. 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.8"></a>3.8. 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 you've enabled Unicode support (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 statubar will change to &quot;Unicode Input: ......&quot; when you do this.</p></blockquote>
<h2><a name="3.9a"></a>3.9a. How do I make a .nanorc file that will be read when I start nano?</h2>
<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.9a"></a>3.9a. How do I make a .nanorc file that will be read when I start nano?</h3>
<blockquote><p>It's not hard at all! But, your nano must <b>not</b> have been compiled with <b>--disable-nanorc</b>. Then simply copy the <b>sample.nanorc</b> that came with the nano source or your nano package (most likely in /usr/doc/nano) to .nanorc in your home directory. If you didn't get one, the syntax of the file is simple. Flags are turned on and off by using the words <b>set</b> and <b>unset</b> plus the long option name for the feature. For example, &quot;set nowrap&quot; or &quot;set smarthome&quot;.</p></blockquote>
<h2><a name="3.9b"></a>3.9b. How about in Win32?</h2>
<h3><a name="3.9b"></a>3.9b. How about in Win32?</h3>
<blockquote><p>If you're using the official nano .zip file and have extracted all the files, you should take the file nano.rc and place it somewhere on your Win32 system (for example, if you have write permission to do so, at the top of C:\). Then you must create an Environment variable called HOME which points to the directory where you put nano.rc. In Windows XP, you can get to Environment variables by right-clicking "My Computer" either on the desktop or in the Start Menu, and selecting Properties. This should bring up the System Properties panel. Then click the Advanced Tab, and there should be a button called Environment Variables. Click that to bring up the Environment Variables section. Now, under User Variables you should be able to click the New button, and make a new Variables Name called HOME, with the Variable Value of whatever path you copied nano.rc into (just the directory name; don't add nano.rc onto the end).</p>
<p>We're still working on documentation for enabling syntax highlighting on Win32; please bear with us.</p>
<p>Note that the nano.rc file must remain Unix-formatted in order for nano to understand it. In other words, you should probably use only nano to edit its config file. Other programs like Wordpad and Notepad will convert the file to DOS format when saving, and the latter does not even properly read Unix-formatted files to begin with.</p></blockquote>
<hr width="100%">
<h1><a name="4"></a>4. Running</h1>
<h2><a name="4.1"></a>4.1. How do I open a file with a name beginning with '+' from the command line?</h2>
<h3><a name="4.1"></a>4.1. How do I open a file with a name beginning with '+' from the command line?</h3>
<blockquote><p>If a command-line option that begins with '+' is followed by another option, the former is always treated as a starting line and column number, and the latter is always treated as a filename. If a command-line option that begins with '+' isn't followed by another option, it's always treated as a filename. Examples:</p>
<p>To open '+filename.txt' starting on line 1: <b>nano +filename.txt</b><br>
To open '+filename.txt' starting on line 10: <b>nano +10 +filename.txt</b><br>
To open '+filename.txt' starting on line 1, column 20: <b>nano +,20 +filename.txt</b><br>
To open '+filename.txt' starting on line 10, column 20: <b>nano +10,20 +filename.txt</b><br>
To open '+filename.txt' starting on line 1 and 'filename.txt' starting on line 40 (if nano has been compiled with multibuffer support): <b>nano +1 +filename.txt +40 filename.txt</b></p></blockquote>
<h2><a name="4.2"></a>4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</h2>
<h3><a name="4.2"></a>4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</h3>
<blockquote><p>Try setting your $TERM variable to 'vt100'. nano doesn't yet support every term entry under the sun.</p>
<p>Bourne shell users (bash and sh): <b>export TERM=vt100</b><br>
C Shell users (tcsh and csh): <b>setenv TERM vt100</b></p></blockquote>
<h2><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?</h2>
<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>--rebindkeypad</b> option on the command line, or add the line <b>set rebindkeypad</b> to your .nanorc. However, nano's mouse support won't work properly if you do any of these things.</p></blockquote>
<h2><a name="4.4"></a>4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</h2>
<h3><a name="4.4"></a>4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</h3>
<blockquote><p>This was a bug in how nano handled consecutive escape sequences. It should be fixed since version 2.6.0.</p></blockquote>
<h2><a name="4.5"></a>4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</h2>
<h3><a name="4.5"></a>4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</h3>
<blockquote><p>It depends on the terminal type you're using. On some terminals, such as the FreeBSD console, xterm, konsole, and gnome-terminal, Shift-F1 to Shift-F4 will generate F13 to F16. On other terminals, such as the Linux console, rxvt, and Eterm, Shift-F3 to Shift-F6 will generate F13 to F16.</p></blockquote>
<h2><a name="4.6"></a>4.6. nano crashes when I type &lt;insert keystroke here&gt;!</h2>
<h3><a name="4.6"></a>4.6. nano crashes when I type &lt;insert keystrokes here&gt;!</h3>
<blockquote><p>If you aren't trying some bizarre keystroke combination with some bizarre $TERM entry, chances are you have found a bug. You are welcome to submit it to the <a href="mailto:nano-devel@gnu.org">nano-devel</a> list or in the <a href="https://savannah.gnu.org/bugs/?group=nano">bug tracker</a> on Savannah.</p></blockquote>
<h2><a name="4.7"></a>4.7. nano crashes when I resize my window. How can I fix that?</h2>
<h3><a name="4.7"></a>4.7. nano crashes when I resize my window. How can I fix that?</h3>
<blockquote><p>Older versions of nano had this problem. Please upgrade to version 2.7.0 or newer.</p></blockquote>
<h2><a name="4.8a"></a>4.8a. When I paste text into a document, each line gets indented further than the last. Why does nano do this, and how can I avoid it?</h2>
<blockquote><p>You have the autoindent feature turned on. Hit Meta-I to turn it off, paste your text, and then hit Meta-I again to turn it back on.</p></blockquote>
<h2><a name="4.8b"></a>4.8b. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</h2>
<h3><a name="4.8a"></a>4.8a. 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.8b"></a>4.8b. 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></blockquote>
<h3><a name="4.8c"></a>4.8c. 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></blockquote>
<h2><a name="4.9"></a>4.9. I've compiled nano with color support, but I don't see any color when I run it!</h2>
<h3><a name="4.9"></a>4.9. 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.9a">3.9a</a>.</p></blockquote>
<h2><a name="4.10"></a>4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</h2>
<h3><a name="4.10"></a>4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</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><b>export EDITOR=/usr/local/bin/nano</b></p>
<p>or, if you use tcsh, put this in your <b>.cshrc</b> file:</p>
@@ -219,53 +222,53 @@
<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><b>my_hdr X-Composer: nano x.y.z</b></p>
<p>Again, replace x.y.z with the version of nano you use.</p></blockquote>
<h2><a name="4.11"></a>4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and nano's mouse support is turned on?</h2>
<h3><a name="4.11"></a>4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and 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>
<h2><a name="4.12"></a>4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</h2>
<h3><a name="4.12"></a>4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</h3>
<blockquote><p>In nano 2.3.0, cursor-position history was introduced, and both history files now reside in a .nano subdirectory in your home directory. A newer nano will move an existing search-history file to this new location so it can continue to be used. This means that if you then try and use an earlier version of nano, it will be unable to see your current search history. To fix this, run the following command:</p>
<p><b>ln -sf ~/.nano/search_history ~/.nano_history</b></p>
<p>The "migration service" (moving the search-history file to its new location) has been deleted from nano in late 2017, since version 2.9.0. The search-history and position-history files will now be looked for first in ~/.nano/ and, when not found there, then in ~/.local/share/nano/.</p></blockquote>
<hr width="100%">
<h1><a name="5"></a>5. Internationalization</h1>
<h2><a name="5.1"></a>5.1. There's no translation for my language!</h2>
<h3><a name="5.1"></a>5.1. There's no translation for my language!</h3>
<blockquote><p>In June 2001, GNU nano entered the <a href="http://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="http://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="http://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="http://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>
<h2><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?</h2>
<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>
<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>
<h2><a name="5.3"></a>5.3. What is the status of Unicode support?</h2>
<h3><a name="5.3"></a>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>
<h2><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h2>
<h3><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h3>
<blockquote><p>There are many reasons to use nano instead of Pico. A more complete list can be found at the <a href="https://nano-editor.org/">nano homepage</a>.</p></blockquote>
<h2><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h2>
<h3><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h3>
<blockquote><p>Again, check out the <a href="https://nano-editor.org/">nano homepage</a> for a good summary of reasons. It really is a matter of personal preference as to which editor you should use. If you're the type of person who likes using the original version of a program, then Pico is the editor for you. If you don't mind sacrificing mailer integration with Pine, and are looking for a few more features, as well as a 'better' license in terms of adding your own changes, nano is the way to go.</p>
<p>Note that the last of these no longer applies to the new version of Pine, <a href="http://www.washington.edu/alpine/">Alpine</a>, which is under the Apache License, version 2.0.</p></blockquote>
<h2><a name="6.3"></a>6.3. What is so bad about the older Pine license?</h2>
<h3><a name="6.3"></a>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="http://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>
<h2><a name="6.4"></a>6.4. Okay, well, what mail program should I use then?</h2>
<h3><a name="6.4"></a>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>
<h2><a name="7.1"></a>7.1. Where can I ask questions or send suggestions?</h2>
<h3><a name="7.1"></a>7.1. Where can I ask questions or send suggestions?</h3>
<blockquote><p>There are three mailing lists for nano hosted at <a href="http://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="http://mail.gnu.org/mailman/listinfo/info-nano/">http://mail.gnu.org/mailman/listinfo/info-nano/</a><br>
help-nano - <a href="http://mail.gnu.org/mailman/listinfo/help-nano/">http://mail.gnu.org/mailman/listinfo/help-nano/</a><br>
nano-devel - <a href="http://mail.gnu.org/mailman/listinfo/nano-devel/">http://mail.gnu.org/mailman/listinfo/nano-devel/</a></p></blockquote>
<h2><a name="7.2"></a>7.3. How do I submit a bug report or patch?</h2>
<h3><a name="7.2"></a>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>
<h2><a name="7.3"></a>7.3. I want to send the development team a big load of cash (or just a thank you).</h2>
<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>
<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>
<h2><a name="7.4"></a>7.4. How do I join the development team?</h2>
<h3><a name="7.4"></a>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>
<h2><a name="7.5"></a>7.5. Can I have write access to the git tree?</h2>
<h3><a name="7.5"></a>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

@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH NANO 1 "version 2.9.4" "March 2018"
.TH NANO 1 "version 2.9.7" "May 2018"
.SH NAME
nano \- Nano's ANOther editor, an enhanced free Pico clone
@@ -250,6 +250,9 @@ Disable the hard-wrapping of long lines. This option conflicts with
.BR \-x ", " \-\-nohelp
Don't show the two help lines at the bottom of the screen.
.TP
.BR \-y ", " \-\-afterends
Make Ctrl+Right stop at word ends instead of beginnings.
.TP
.BR \-z ", " \-\-suspend
Enable the suspend ability.
.TP
@@ -303,12 +306,16 @@ cannot be undone any more. The workaround is, of course, to exit without
saving.
.sp
The recording and playback of keyboard macros works correctly only on a
terminal emulator, not on a Linux console (VT), because the latter is a
deficient terminal.
terminal emulator, not on a Linux console (VT), because the latter does
not by default distinguish modified from unmodified arrow keys.
.sp
Please report any other bugs that you encounter via:
.br
\fIhttps://savannah.gnu.org/bugs/?group=nano\fR.
.sp
When nano crashes, it will save any modified buffers to emergency .save files.
If you are able to reproduce the crash and you want to get a backtrace, define
the environment variable \fBNANO_NOCATCH\fR.
.SH HOMEPAGE
\fIhttps://nano-editor.org/\fR

View File

@@ -8,8 +8,8 @@
@smallbook
@set EDITION 0.5
@set VERSION 2.9.4
@set UPDATED March 2018
@set VERSION 2.9.7
@set UPDATED May 2018
@dircategory Editors
@direntry
@@ -23,7 +23,7 @@
@titlepage
@title GNU @command{nano}
@subtitle a small and friendly text editor
@subtitle version 2.9.4
@subtitle version 2.9.7
@author Chris Allegretta
@page
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
@node Top
@top
This manual documents the GNU @command{nano} editor, version 2.9.4.
This manual documents the GNU @command{nano} editor, version 2.9.7.
@menu
* Introduction::
@@ -392,6 +392,10 @@ is located at the very bottom of the editor.
Note: When accessing the help system, Expert Mode is temporarily
disabled to display the help-system navigation keys.
@item -y
@itemx --afterends
Make Ctrl+Right stop at word ends instead of beginnings.
@item -z
@itemx --suspend
Enable the ability to suspend @command{nano} using the system's suspend
@@ -569,8 +573,8 @@ cannot be undone any more. The workaround is, of course, to exit without
saving.
The recording and playback of keyboard macros works correctly only on a
terminal emulator, not on a Linux console (VT), because the latter is a
deficient terminal.
terminal emulator, not on a Linux console (VT), because the latter does
not by default distinguish modified from unmodified arrow keys.
@node Built-in Help
@chapter Built-in Help
@@ -689,6 +693,9 @@ The supported settings in a nanorc file are:
@table @code
@item set afterends
Make Ctrl+Right stop at word ends instead of beginnings.
@item set allow_insecure_backup
When backing up files, allow the backup to succeed even if its
permissions can't be (re)set due to special OS considerations.
@@ -755,7 +762,8 @@ Use this color combination for the concise function descriptions
in the two help lines at the bottom of the screen.
Valid names for foreground and background color are:
@code{white}, @code{black}, @code{blue}, @code{green},
@code{red}, @code{cyan}, @code{yellow}, and @code{magenta}.
@code{red}, @code{cyan}, @code{yellow}, @code{magenta}, and @code{normal}
--- where @code{normal} means the default foreground or background color.
The name of the foreground color may be prefixed with @code{bright}.
And either @var{fgcolor} or ,@var{bgcolor} may be left out.
@@ -908,6 +916,7 @@ Use this color combination for the title bar.
@item set trimblanks
Remove trailing whitespace from wrapped lines when automatic
hard-wrapping occurs or when text is justified.
(The old form of this option, @code{set justifytrim}, is deprecated.)
@item set unix
Save a file by default in Unix format. This overrides nano's
@@ -1188,10 +1197,12 @@ Goes one line up (in the editor or browser).
Goes one line down (in the editor or browser).
@item scrollup
Scrolls up one line of text from the current position.
Scrolls the viewport up one row (meaning that the text slides down)
while keeping the cursor in the same text position, if possible.
@item scrolldown
Scrolls down one line of text from the current position.
Scrolls the viewport down one row (meaning that the text slides up)
while keeping the cursor in the same text position, if possible.
@item prevword
Moves the cursor to the beginning of the previous word.
@@ -1344,8 +1355,9 @@ Goes to the last file when using the file browser (reading or writing files).
@item nohelp
Toggles the presence of the two-line list of key bindings at the bottom of the screen.
@item constupdate
@item constantshow
Toggles the constant display of the current line, column, and character positions.
(The form @code{constupdate} is deprecated.)
@item morespace
Toggles the presence of the blank line that 'separates' the title bar from the file text.
@@ -1356,6 +1368,9 @@ Toggles smooth scrolling (when moving around with the arrow keys).
@item softwrap
Toggles the displaying of overlong lines on multiple screen lines.
@item linenumbers
Toggles the display of line numbers in front of the text.
@item whitespacedisplay
Toggles the showing of whitespace.
@@ -1368,9 +1383,10 @@ Toggles the smartness of the Home key.
@item autoindent
Toggles whether new lines will contain the same amount of whitespace as the preceding line.
@item cuttoend
@item cutfromcursor
Toggles whether cutting text will cut the whole line or just from the current cursor
position to the end of the line.
(The form @code{cuttoend} is deprecated.)
@item nowrap
Toggles whether long lines will be hard-wrapped to the next line.
@@ -1435,7 +1451,7 @@ The interactive spell checker Yes/no menu.
The linter menu.
@item browser
The file browser for inserting or writing a file.
The file browser, for choosing a file to read from or write to.
@item whereisfile
The 'search for a file' menu in the file browser.
@@ -1454,14 +1470,15 @@ it means all menus where the specified @code{key} exists.
@node The File Browser
@chapter The File Browser
When reading or writing files, pressing @kbd{^T} will invoke the file browser.
When in the Read-File (@kbd{^R}) or Write-Out menu (@kbd{^O}),
pressing @kbd{^T} will invoke the file browser.
Here, one can navigate directories in a graphical manner in order to
find the desired file.
Basic movement in the file browser is accomplished with the arrow keys,
page up, and page down. More advanced movement is accomplished by
searching via @kbd{^W} (or @kbd{w'} and changing directories via
@kbd{^_} (or @kbd{g}). The behavior of the @kbd{Enter} key (or @kbd{s})
Basic movement in the file browser is accomplished with the arrow and
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
@@ -1502,6 +1519,11 @@ The output of the "Display Cursor Position" command (@kbd{^C}) displays
not only the current line and character position of the cursor,
but also (between the two) the current column position.
@item Hard-Wrapping
By default, @command{nano} hard-wraps lines at screen width minus eight
columns, whereas Pico does it at screen width minus six columns. You can
make @command{nano} do the same as Pico by using @option{--fill=-6}.
@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

View File

@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH NANORC 5 "version 2.9.4" "March 2018"
.TH NANORC 5 "version 2.9.7" "May 2018"
.SH NAME
nanorc \- GNU nano's configuration file
@@ -53,6 +53,9 @@ match \fB"\fP, \fB'\fP, \fB)\fP, \fB>\fP, \fB]\fP, and \fB}\fP.
The supported commands and arguments are:
.TP 3
.B set afterends
Make Ctrl+Right stop at word ends instead of beginnings.
.TP
.B set allow_insecure_backup
When backing up files, allow the backup to succeed even if its permissions
can't be (re)set due to special OS considerations. You should
@@ -264,13 +267,16 @@ Save automatically on exit, don't prompt.
.B set titlecolor \fIfgcolor\fR,\fIbgcolor\fR
Specify the color combination to use for the title bar.
Valid names for the foreground and background colors are:
.BR white ", " black ", " blue ", " green ", " red ", " cyan ", " yellow ", and " magenta .
.BR white ", " black ", " blue ", " green ", " red ", "
.BR cyan ", " yellow ", " magenta ", and " normal
-- where \fBnormal\fR means the default foreground or background color.
The name of the foreground color may be prefixed with \fBbright\fR.
And either "\fIfgcolor\fR" or ",\fIbgcolor\fR" may be left out.
.TP
.B set trimblanks
Remove trailing whitespace from wrapped lines when automatic
hard-wrapping occurs or when text is justified.
(The old form of this option, '\fBset justifytrim\fR', is deprecated.)
.TP
.B set unix
Save a file by default in Unix format. This overrides nano's
@@ -543,10 +549,12 @@ Goes one line up (in the editor or browser).
Goes one line down (in the editor or browser).
.TP
.B scrollup
Scrolls up one line of text from the current position.
Scrolls the viewport up one row (meaning that the text slides down)
while keeping the cursor in the same text position, if possible.
.TP
.B scrolldown
Scrolls down one line of text from the current position.
Scrolls the viewport down one row (meaning that the text slides up)
while keeping the cursor in the same text position, if possible.
.TP
.B prevword
Moves the cursor to the beginning of the previous word.
@@ -699,8 +707,9 @@ Goes to the last file when using the file browser (reading or writing files).
.B nohelp
Toggles the presence of the two-line list of key bindings at the bottom of the screen.
.TP
.B constupdate
.B constantshow
Toggles the constant display of the current line, column, and character positions.
(The form 'constupdate' is deprecated.)
.TP
.B morespace
Toggles the presence of the blank line that 'separates' the title bar from the file text.
@@ -711,6 +720,9 @@ Toggles smooth scrolling (when moving around with the arrow keys).
.B softwrap
Toggles the displaying of overlong lines on multiple screen lines.
.TP
.B linenumbers
Toggles the display of line numbers in front of the text.
.TP
.B whitespacedisplay
Toggles the showing of whitespace.
.TP
@@ -723,9 +735,10 @@ Toggles the smartness of the Home key.
.B autoindent
Toggles whether new lines will contain the same amount of whitespace as the preceding line.
.TP
.B cuttoend
.B cutfromcursor
Toggles whether cutting text will cut the whole line or just from the current cursor
position to the end of the line.
(The form 'cuttoend' is deprecated.)
.TP
.B nowrap
Toggles whether long lines will be hard-wrapped to the next line.

View File

@@ -16,7 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH RNANO 1 "version 2.9.4" "March 2018"
.TH RNANO 1 "version 2.9.7" "May 2018"
.SH NAME
rnano \- a restricted nano

View File

@@ -15,6 +15,10 @@
## its end. For example, for the "brackets" option, ""')>]}" will match
## ", ', ), >, ], and }.
## Make the 'nextword' function (Ctrl+Right) stop at word ends
## instead of at beginnings.
# set afterends
## When soft line wrapping is enabled, make it wrap lines at blanks
## (tabs and spaces) instead of always at the edge of the screen.
# set atblanks
@@ -43,7 +47,6 @@
## Constantly display the cursor position in the status bar. Note that
## this overrides "quickblank".
# set constantshow
## (The old form, 'const', is deprecated.)
## Use cut-from-cursor-to-end-of-line by default.
# set cutfromcursor
@@ -107,7 +110,6 @@
## Remember the cursor position in each file for the next editing session.
# set positionlog
## (The old form, 'poslog', is deprecated.)
## Preserve the XON and XOFF keys (^Q and ^S).
# set preserve
@@ -174,6 +176,7 @@
## Snip whitespace at the end of lines when justifying or hard-wrapping.
# set trimblanks
## (The old form, 'justifytrim', is deprecated.)
## Disallow file modification. Why would you want this in an rcfile? ;)
# set view

1082
po/bg.po

File diff suppressed because it is too large Load Diff

1069
po/ca.po

File diff suppressed because it is too large Load Diff

1087
po/cs.po

File diff suppressed because it is too large Load Diff

1127
po/da.po

File diff suppressed because it is too large Load Diff

1065
po/de.po

File diff suppressed because it is too large Load Diff

1069
po/eo.po

File diff suppressed because it is too large Load Diff

1065
po/es.po

File diff suppressed because it is too large Load Diff

1106
po/eu.po

File diff suppressed because it is too large Load Diff

1215
po/fi.po

File diff suppressed because it is too large Load Diff

1082
po/fr.po

File diff suppressed because it is too large Load Diff

1057
po/ga.po

File diff suppressed because it is too large Load Diff

1085
po/gl.po

File diff suppressed because it is too large Load Diff

1822
po/hr.po

File diff suppressed because it is too large Load Diff

1101
po/hu.po

File diff suppressed because it is too large Load Diff

1050
po/id.po

File diff suppressed because it is too large Load Diff

1062
po/it.po

File diff suppressed because it is too large Load Diff

1065
po/ja.po

File diff suppressed because it is too large Load Diff

1082
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1081
po/nb.po

File diff suppressed because it is too large Load Diff

1069
po/nl.po

File diff suppressed because it is too large Load Diff

1077
po/nn.po

File diff suppressed because it is too large Load Diff

1452
po/pl.po

File diff suppressed because it is too large Load Diff

1063
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1093
po/ro.po

File diff suppressed because it is too large Load Diff

1087
po/ru.po

File diff suppressed because it is too large Load Diff

1087
po/sl.po

File diff suppressed because it is too large Load Diff

1231
po/sr.po

File diff suppressed because it is too large Load Diff

1057
po/sv.po

File diff suppressed because it is too large Load Diff

1065
po/tr.po

File diff suppressed because it is too large Load Diff

1063
po/uk.po

File diff suppressed because it is too large Load Diff

1063
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

@@ -32,9 +32,9 @@ static char **filelist = NULL;
/* The list of files to display in the file browser. */
static size_t filelist_len = 0;
/* The number of files in the list. */
static int width = 0;
static size_t width = 0;
/* The number of files that we can display per screen row. */
static int longest = 0;
static size_t longest = 0;
/* The number of columns in the longest filename in the list. */
static size_t selected = 0;
/* The currently selected filename in the list; zero-based. */
@@ -168,12 +168,12 @@ char *do_browser(char *path)
} else if (func == do_search_forward) {
do_filesearch();
} else if (func == do_research) {
do_fileresearch(TRUE);
do_fileresearch(FORWARD);
#ifndef NANO_TINY
} else if (func == do_findprevious) {
do_fileresearch(FALSE);
do_fileresearch(BACKWARD);
} else if (func == do_findnext) {
do_fileresearch(TRUE);
do_fileresearch(FORWARD);
#endif
} else if (func == do_left) {
if (selected > 0)
@@ -187,10 +187,10 @@ char *do_browser(char *path)
selected += width - 1 - (selected % width);
if (selected >= filelist_len)
selected = filelist_len - 1;
} else if (func == do_up_void) {
} else if (func == do_up) {
if (selected >= width)
selected -= width;
} else if (func == do_down_void) {
} else if (func == do_down) {
if (selected + width <= filelist_len - 1)
selected += width;
} else if (func == do_prev_block) {
@@ -258,9 +258,9 @@ char *do_browser(char *path)
/* In case the specified directory cannot be entered, select it
* (if it is in the current list) so it will be highlighted. */
for (i = 0; i < filelist_len; i++)
if (strcmp(filelist[i], path) == 0)
selected = i;
for (size_t j = 0; j < filelist_len; j++)
if (strcmp(filelist[j], path) == 0)
selected = j;
/* Try opening and reading the specified directory. */
goto read_directory_contents;
@@ -304,7 +304,7 @@ char *do_browser(char *path)
path = mallocstrcpy(path, filelist[selected]);
goto read_directory_contents;
#ifdef ENABLE_NANORC
} else if (func == (void *)implant) {
} else if (func == (functionptrtype)implant) {
implant(first_sc_for(MBROWSER, func)->expansion);
#endif
} else if (func == do_exit) {
@@ -361,7 +361,7 @@ char *do_browse_from(const char *inpath)
path = free_and_assign(path, strip_last_component(path));
if (stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
char * currentdir = charalloc(PATH_MAX + 1);
char *currentdir = charalloc(PATH_MAX + 1);
free(path);
path = getcwd(currentdir, PATH_MAX + 1);
@@ -525,7 +525,7 @@ void browser_refresh(void)
/* The length of the filename in columns. */
size_t infolen;
/* The length of the file information in columns. */
int infomaxlen = 7;
size_t infomaxlen = 7;
/* The maximum length of the file information in columns:
* normally seven, but will be twelve for "(parent dir)". */
bool dots = (COLS >= 15 && namelen >= longest - infomaxlen);
@@ -659,42 +659,40 @@ void browser_select_dirname(const char *needle)
}
}
/* Set up the system variables for a filename search. Return -1 or -2 if
* the search should be canceled (due to Cancel or a blank search string),
* return 0 when we have a string, and return a positive value when some
* function was run. */
/* Prepare the prompt and ask the user what to search for. Return -2
* for a blank answer, -1 for Cancel, 0 when we have a string, and a
* positive value when some function was run. */
int filesearch_init(void)
{
int input;
char *buf;
char *thedefault;
int response;
/* If something was searched for before, show it between square brackets. */
if (*last_search != '\0') {
char *disp = display_string(last_search, 0, COLS / 3, FALSE);
buf = charalloc(strlen(disp) + 7);
thedefault = charalloc(strlen(disp) + 7);
/* We use (COLS / 3) here because we need to see more on the line. */
sprintf(buf, " [%s%s]", disp,
sprintf(thedefault, " [%s%s]", disp,
(strlenpt(last_search) > COLS / 3) ? "..." : "");
free(disp);
} else
buf = mallocstrcpy(NULL, "");
thedefault = mallocstrcpy(NULL, "");
/* This is now one simple call. It just does a lot. */
input = do_prompt(FALSE, FALSE, MWHEREISFILE, NULL, &search_history,
browser_refresh, "%s%s", _("Search"), buf);
/* Release buf now that we don't need it anymore. */
free(buf);
/* Now ask what to search for. */
response = do_prompt(FALSE, FALSE, MWHEREISFILE, NULL, &search_history,
browser_refresh, "%s%s", _("Search"), thedefault);
free(thedefault);
/* If only Enter was pressed but we have a previous string, it's okay. */
if (input == -2 && *last_search != '\0')
if (response == -2 && *last_search != '\0')
return 0;
/* Otherwise negative inputs are a bailout. */
if (input < 0)
/* Otherwise negative responses are a bailout. */
if (response < 0)
statusbar(_("Cancelled"));
return input;
return response;
}
/* Look for the given needle in the list of files. If forwards is TRUE,

View File

@@ -60,9 +60,9 @@ void set_colorpairs(void)
colortype *combo = color_combo[i];
if (combo != NULL) {
if (combo->fg == -1 && !using_defaults)
if (combo->fg == USE_THE_DEFAULT && !using_defaults)
combo->fg = COLOR_WHITE;
if (combo->bg == -1 && !using_defaults)
if (combo->bg == USE_THE_DEFAULT && !using_defaults)
combo->bg = COLOR_BLACK;
init_pair(i + 1, combo->fg, combo->bg);
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BANDAID |
@@ -125,10 +125,10 @@ void color_init(void)
foreground = ink->fg;
background = ink->bg;
if (foreground == -1 && !using_defaults)
if (foreground == USE_THE_DEFAULT && !using_defaults)
foreground = COLOR_WHITE;
if (background == -1 && !using_defaults)
if (background == USE_THE_DEFAULT && !using_defaults)
background = COLOR_BLACK;
init_pair(ink->pairnum, foreground, background);

View File

@@ -66,16 +66,19 @@ void make_new_buffer(void)
if (openfile == NULL) {
/* Make the first open file the only element in the list. */
#ifdef ENABLE_MULTIBUFFER
newnode->prev = newnode;
newnode->next = newnode;
#endif
firstfile = newnode;
} else {
/* Add the new open file after the current one in the list. */
#ifdef ENABLE_MULTIBUFFER
newnode->prev = openfile;
newnode->next = openfile->next;
openfile->next->prev = newnode;
openfile->next = newnode;
#endif
/* There is more than one file open: show "Close" in help lines. */
exitfunc->desc = close_tag;
more_than_one = !inhelp || more_than_one;
@@ -406,13 +409,11 @@ void stat_with_alloc(const char *filename, struct stat **pstat)
}
#endif /* !NANO_TINY */
/* This does one of three things. If the filename is "", just create a new
* empty buffer. Otherwise, read the given file into the existing buffer,
* or into a new buffer when MULTIBUFFER is set or there is no buffer yet. */
bool open_buffer(const char *filename, bool undoable)
/* This does one of three things. If the filename is "", it just creates
* a new empty buffer. When the filename is not empty, it reads that file
* into a new buffer when requested, otherwise into the existing buffer. */
bool open_buffer(const char *filename, bool new_buffer)
{
bool new_buffer = (openfile == NULL || ISSET(MULTIBUFFER));
/* Whether we load into the current buffer or a new one. */
char *realname;
/* The filename after tilde expansion. */
FILE *f;
@@ -475,24 +476,20 @@ bool open_buffer(const char *filename, bool undoable)
rc = (filename[0] != '\0' && !ISSET(NOREAD_MODE)) ?
open_file(realname, new_buffer, inhelp, &f) : -2;
/* If we have a file, and we're loading into a new buffer, update
* the filename. */
if (rc != -1 && new_buffer)
openfile->filename = mallocstrcpy(openfile->filename, realname);
/* If we have a non-new file, read it in. Then, if the buffer has
* no stat, update the stat, if applicable. */
if (rc > 0) {
read_file(f, rc, realname, undoable, new_buffer);
read_file(f, rc, realname, !new_buffer);
#ifndef NANO_TINY
if (openfile->current_stat == NULL)
stat_with_alloc(realname, &openfile->current_stat);
#endif
}
/* If we have a file, and we're loading into a new buffer, move back
* to the beginning of the first line of the buffer. */
/* If we have a file, and we've loaded it into a new buffer, set
* the filename and put the cursor at the start of the buffer. */
if (rc != -1 && new_buffer) {
openfile->filename = mallocstrcpy(openfile->filename, realname);
openfile->current = openfile->fileage;
openfile->current_x = 0;
openfile->placewewant = 0;
@@ -528,7 +525,7 @@ void replace_buffer(const char *filename)
initialize_buffer_text();
/* Insert the processed file into its place. */
read_file(f, descriptor, filename, FALSE, TRUE);
read_file(f, descriptor, filename, FALSE);
/* Put current at a place that is certain to exist. */
openfile->current = openfile->fileage;
@@ -559,7 +556,7 @@ void replace_marked_buffer(const char *filename, filestruct *top, size_t top_x,
* where the marked text was. */
extract_buffer(&trash_top, &trash_bot, top, top_x, bot, bot_x);
free_filestruct(trash_top);
read_file(f, descriptor, filename, FALSE, TRUE);
read_file(f, descriptor, filename, FALSE);
/* Restore the magicline behavior now that we're done fiddling. */
if (!old_no_newlines)
@@ -716,13 +713,10 @@ char *encode_data(char *buf, size_t buf_len)
return mallocstrcpy(NULL, buf);
}
/* Read an open file into the current buffer. f should be set to the
* open file, and filename should be set to the name of the file.
* undoable means do we want to create undo records to try and undo
* this. Will also attempt to check file writability if fd > 0 and
* checkwritable == TRUE. */
void read_file(FILE *f, int fd, const char *filename, bool undoable,
bool checkwritable)
/* Read the given open file f into the current buffer. filename should be
* set to the name of the file. undoable means that undo records should be
* created and that the file does not need to be checked for writability. */
void read_file(FILE *f, int fd, const char *filename, bool undoable)
{
ssize_t was_lineno = openfile->current->lineno;
/* The line number where we start the insertion. */
@@ -838,7 +832,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable,
if (ferror(f))
nperror(filename);
fclose(f);
if (fd > 0 && checkwritable) {
if (fd > 0 && !undoable) {
close(fd);
writable = is_file_writable(filename);
}
@@ -1125,7 +1119,7 @@ void do_insertfile(void)
#ifdef ENABLE_MULTIBUFFER
/* When in multibuffer mode, first open a blank buffer. */
if (ISSET(MULTIBUFFER))
open_buffer("", FALSE);
open_buffer("", TRUE);
#endif
/* If the command is not empty, execute it and read its output
* into the buffer, and add the command to the history list. */
@@ -1152,8 +1146,8 @@ void do_insertfile(void)
/* Make sure the specified path is tilde-expanded. */
answer = free_and_assign(answer, real_dir_from_tilde(answer));
/* Read the specified file into the current buffer. */
open_buffer(answer, TRUE);
/* Read the file into a new buffer or into current buffer. */
open_buffer(answer, ISSET(MULTIBUFFER));
}
#ifdef ENABLE_MULTIBUFFER
@@ -2429,8 +2423,8 @@ char **username_tab_completion(const char *buf, size_t *num_matches,
/* We consider the first buf_len characters of buf for filename tab
* completion. */
char **cwd_tab_completion(const char *buf, bool allow_files, size_t
*num_matches, size_t buf_len)
char **cwd_tab_completion(const char *buf, bool allow_files,
size_t *num_matches, size_t buf_len)
{
char *dirname = mallocstrcpy(NULL, buf);
char *slash, *filename;
@@ -2609,7 +2603,8 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
if (!*lastwastab)
*lastwastab = TRUE;
else if (num_matches > 1) {
int longest_name = 0, ncols, editline = 0;
size_t longest_name = 0, ncols;
int editline = 0;
/* Sort the list of available choices. */
qsort(matches, num_matches, sizeof(char *), diralphasort);

View File

@@ -46,11 +46,6 @@ bool focusing = TRUE;
bool as_an_at = TRUE;
/* Whether a 0x0A byte should be shown as a ^@ instead of a ^J. */
int margin = 0;
/* The amount of space reserved at the left for line numbers. */
int editwincols = -1;
/* The number of usable columns in the edit window: COLS - margin. */
bool suppress_cursorpos = FALSE;
/* Should we skip constant position display for current keystroke? */
@@ -98,18 +93,22 @@ char *present_path = NULL;
unsigned flags[4] = {0, 0, 0, 0};
/* Our flag containing the states of all global options. */
WINDOW *topwin = NULL;
/* The top portion of the window, where we display the version
* number of nano, the name of the current file, and whether the
* current file has been modified. */
/* The top portion of the screen, showing the version number of nano,
* the name of the file, and whether the buffer was modified. */
WINDOW *edit = NULL;
/* The middle portion of the window, i.e. the edit window, where
* we display the current file we're editing. */
/* The middle portion of the screen: the edit window, showing the
* contents of the current buffer, the file we are editing. */
WINDOW *bottomwin = NULL;
/* The bottom portion of the window, where we display statusbar
/* The bottom portion of the screen, where we display statusbar
* messages, the statusbar prompt, and a list of shortcuts. */
int editwinrows = 0;
/* How many rows does the edit window take up? */
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. */
filestruct *cutbuffer = NULL;
/* The buffer where we store cut text. */
@@ -266,7 +265,7 @@ size_t length_of_list(int menu)
#define BLANKAFTER TRUE /* A blank line after this one. */
#define TOGETHER FALSE
/* Just throw this here. */
/* Empty functions, for the most part corresponding to toggles. */
void case_sens_void(void)
{
}
@@ -291,6 +290,9 @@ void goto_dir_void(void)
}
#endif
#ifndef NANO_TINY
void do_toggle_void(void)
{
}
void dos_format_void(void)
{
}
@@ -318,6 +320,9 @@ void flip_newbuffer(void)
void discard_buffer(void)
{
}
void do_cancel(void)
{
}
/* Add a function to the function list. */
void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *help,
@@ -392,7 +397,6 @@ const sc *first_sc_for(int menu, void (*func)(void))
#ifdef DEBUG
fprintf(stderr, "Whoops, returning null given func %ld in menu %x\n", (long)func, menu);
#endif
/* Otherwise... */
return NULL;
}
@@ -576,10 +580,12 @@ void shortcut_init(void)
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
#ifdef ENABLE_HELP
const char *scrollup_gist =
N_("Scroll up one line without scrolling the cursor");
N_("Scroll up one line without moving the cursor textually");
const char *scrolldown_gist =
N_("Scroll down one line without scrolling the cursor");
N_("Scroll down one line without moving the cursor textually");
#endif
#ifdef ENABLE_MULTIBUFFER
const char *prevfile_gist = N_("Switch to the previous file buffer");
@@ -855,11 +861,11 @@ void shortcut_init(void)
add_to_funcs(do_end, MMAIN,
N_("End"), WITHORSANS(end_gist), BLANKAFTER, VIEW);
add_to_funcs(do_up_void, MMAIN|MHELP|MBROWSER,
add_to_funcs(do_up, MMAIN|MHELP|MBROWSER,
prevline_tag, WITHORSANS(prevline_gist), TOGETHER, VIEW);
add_to_funcs(do_down_void, MMAIN|MHELP|MBROWSER,
add_to_funcs(do_down, MMAIN|MHELP|MBROWSER,
nextline_tag, WITHORSANS(nextline_gist), TOGETHER, VIEW);
#ifndef NANO_TINY
#ifdef ENABLE_HELP
add_to_funcs(do_scroll_up, MMAIN,
N_("Scroll Up"), WITHORSANS(scrollup_gist), TOGETHER, VIEW);
add_to_funcs(do_scroll_down, MMAIN,
@@ -1013,8 +1019,7 @@ void shortcut_init(void)
N_("Backup File"), WITHORSANS(backup_gist), BLANKAFTER, NOVIEW);
}
/* If we're using restricted mode, file insertion is disabled, and
* thus command execution and the multibuffer toggle have no place. */
/* Command execution is only available when not in restricted mode. */
if (!ISSET(RESTRICTED)) {
add_to_funcs(flip_execute, MINSERTFILE,
N_("Execute Command"), WITHORSANS(execute_gist), TOGETHER, NOVIEW);
@@ -1024,12 +1029,14 @@ void shortcut_init(void)
}
#endif /* !NANO_TINY */
#ifdef ENABLE_MULTIBUFFER
/* Multiple buffers are only available when not in restricted mode. */
if (!ISSET(RESTRICTED))
add_to_funcs(flip_newbuffer, MINSERTFILE|MEXTCMD,
N_("New Buffer"), WITHORSANS(newbuffer_gist), TOGETHER, NOVIEW);
#endif
#ifdef ENABLE_BROWSER
/* The file browser is only available when not in restricted mode. */
if (!ISSET(RESTRICTED))
add_to_funcs(to_files_void, MWRITEFILE|MINSERTFILE,
N_("To Files"), WITHORSANS(tofiles_gist), TOGETHER, VIEW);
@@ -1181,19 +1188,19 @@ void shortcut_init(void)
add_to_sclist((MMOST & ~MBROWSER), "Home", KEY_HOME, do_home, 0);
add_to_sclist((MMOST & ~MBROWSER), "^E", 0, do_end, 0);
add_to_sclist((MMOST & ~MBROWSER), "End", KEY_END, do_end, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", 0, do_up_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", 0, do_down_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", 0, do_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", 0, do_down, 0);
#ifdef ENABLE_UTF8
if (using_utf8()) {
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xb2", KEY_UP, do_up_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xbc", KEY_DOWN, do_down_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xb2", KEY_UP, do_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xbc", KEY_DOWN, do_down, 0);
add_to_sclist(MMAIN|MBROWSER, "^\xE2\x96\xb2", CONTROL_UP, do_prev_block, 0);
add_to_sclist(MMAIN|MBROWSER, "^\xE2\x96\xbc", CONTROL_DOWN, do_next_block, 0);
} else
#endif
{
add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", KEY_UP, do_up_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", KEY_DOWN, do_down_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", KEY_UP, do_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", KEY_DOWN, do_down, 0);
add_to_sclist(MMAIN|MBROWSER, "^Up", CONTROL_UP, do_prev_block, 0);
add_to_sclist(MMAIN|MBROWSER, "^Down", CONTROL_DOWN, do_next_block, 0);
}
@@ -1205,7 +1212,7 @@ void shortcut_init(void)
add_to_sclist(MMAIN, "M-)", 0, do_para_end_void, 0);
add_to_sclist(MMAIN, "M-0", 0, do_para_end_void, 0);
#endif
#ifndef NANO_TINY
#ifdef ENABLE_HELP
add_to_sclist(MMAIN, "M--", 0, do_scroll_up, 0);
add_to_sclist(MMAIN, "M-_", 0, do_scroll_up, 0);
add_to_sclist(MMAIN, "M-+", 0, do_scroll_down, 0);
@@ -1311,8 +1318,8 @@ void shortcut_init(void)
#ifndef NANO_TINY
add_to_sclist(MWRITEFILE, "M-D", 0, dos_format_void, 0);
add_to_sclist(MWRITEFILE, "M-M", 0, mac_format_void, 0);
/* In restricted mode, don't allow Appending, Prepending, nor making
* backups, nor executing a command, nor opening a new buffer. */
/* Only when not in restricted mode, allow Appending, Prepending,
* making backups, and executing a command. */
if (!ISSET(RESTRICTED)) {
add_to_sclist(MWRITEFILE, "M-A", 0, append_void, 0);
add_to_sclist(MWRITEFILE, "M-P", 0, prepend_void, 0);
@@ -1321,11 +1328,12 @@ void shortcut_init(void)
}
#endif
#ifdef ENABLE_MULTIBUFFER
/* Only when not in restricted mode, allow multiple buffers. */
if (!ISSET(RESTRICTED))
add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", 0, flip_newbuffer, 0);
#endif
#ifdef ENABLE_BROWSER
/* In restricted mode, don't allow entering the file browser. */
/* Only when not in restricted mode, allow entering the file browser. */
if (!ISSET(RESTRICTED))
add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files_void, 0);
#endif
@@ -1385,8 +1393,7 @@ const subnfunc *sctofunc(const sc *s)
}
#ifndef NANO_TINY
/* Now let's come up with a single (hopefully) function to get a string
* for each flag. */
/* Return the textual description that corresponds to the given flag. */
const char *flagtostr(int flag)
{
switch (flag) {
@@ -1524,10 +1531,6 @@ sc *strtosc(const char *input)
s->func = do_indent;
else if (!strcasecmp(input, "unindent"))
s->func = do_unindent;
else if (!strcasecmp(input, "scrollup"))
s->func = do_scroll_up;
else if (!strcasecmp(input, "scrolldown"))
s->func = do_scroll_down;
else if (!strcasecmp(input, "cutwordleft"))
s->func = do_cut_prev_word;
else if (!strcasecmp(input, "cutwordright"))
@@ -1553,10 +1556,16 @@ sc *strtosc(const char *input)
s->func = do_right;
else if (!strcasecmp(input, "up") ||
!strcasecmp(input, "prevline"))
s->func = do_up_void;
s->func = do_up;
else if (!strcasecmp(input, "down") ||
!strcasecmp(input, "nextline"))
s->func = do_down_void;
s->func = do_down;
#ifdef ENABLE_HELP
else if (!strcasecmp(input, "scrollup"))
s->func = do_scroll_up;
else if (!strcasecmp(input, "scrolldown"))
s->func = do_scroll_down;
#endif
else if (!strcasecmp(input, "prevword"))
s->func = do_prev_word_void;
else if (!strcasecmp(input, "nextword"))
@@ -1650,7 +1659,8 @@ sc *strtosc(const char *input)
s->func = do_toggle_void;
if (!strcasecmp(input, "nohelp"))
s->toggle = NO_HELP;
else if (!strcasecmp(input, "constupdate"))
else if (!strcasecmp(input, "constantshow") ||
!strcasecmp(input, "constupdate")) /* Deprecated. Remove end of 2018. */
s->toggle = CONSTANT_SHOW;
else if (!strcasecmp(input, "morespace"))
s->toggle = MORE_SPACE;
@@ -1658,6 +1668,10 @@ sc *strtosc(const char *input)
s->toggle = SMOOTH_SCROLL;
else if (!strcasecmp(input, "softwrap"))
s->toggle = SOFTWRAP;
#ifdef ENABLE_LINENUMBERS
else if (!strcasecmp(input, "linenumbers"))
s->toggle = LINE_NUMBERS;
#endif
else if (!strcasecmp(input, "whitespacedisplay"))
s->toggle = WHITESPACE_DISPLAY;
#ifdef ENABLE_COLOR
@@ -1668,7 +1682,8 @@ sc *strtosc(const char *input)
s->toggle = SMART_HOME;
else if (!strcasecmp(input, "autoindent"))
s->toggle = AUTOINDENT;
else if (!strcasecmp(input, "cuttoend"))
else if (!strcasecmp(input, "cutfromcursor") ||
!strcasecmp(input, "cuttoend")) /* Deprecated. Remove end of 2018. */
s->toggle = CUT_FROM_CURSOR;
#ifdef ENABLE_WRAPPING
else if (!strcasecmp(input, "nowrap"))
@@ -1777,12 +1792,14 @@ void thanks_for_all_the_fish(void)
free(alt_speller);
#endif
free_filestruct(cutbuffer);
#ifdef ENABLE_MULTIBUFFER
/* Free the memory associated with each open file buffer. */
while (openfile != openfile->next) {
openfile = openfile->next;
delete_opennode(openfile->prev);
}
delete_opennode(openfile);
#endif
#ifdef ENABLE_COLOR
free(syntaxstr);
while (syntaxes != NULL) {

View File

@@ -46,7 +46,7 @@ char *tempfilename = NULL;
* read that file into a new buffer. */
void wrap_the_help_text(bool redisplaying)
{
int sum = 0;
size_t sum = 0;
const char *ptr = start_of_body;
FILE *tempfile = fopen(tempfilename, "w+b");
@@ -75,7 +75,7 @@ void wrap_the_help_text(bool redisplaying)
if (redisplaying)
close_buffer();
open_buffer(tempfilename, FALSE);
open_buffer(tempfilename, TRUE);
remove_magicline();
prepare_for_display();
@@ -142,10 +142,10 @@ void do_help(void)
UNSET(WHITESPACE_DISPLAY);
UNSET(NOREAD_MODE);
SET(MULTIBUFFER);
#ifdef ENABLE_LINENUMBERS
UNSET(LINE_NUMBERS);
editwincols = COLS;
margin = 0;
#endif
tabsize = 8;
@@ -191,12 +191,12 @@ void do_help(void)
if (func == total_refresh) {
total_redraw();
} else if (func == do_up_void) {
do_up(TRUE);
} else if (func == do_down_void) {
} else if (func == do_up) {
do_scroll_up();
} else if (func == do_down) {
if (openfile->edittop->lineno + editwinrows - 1 <
openfile->filebot->lineno)
do_down(TRUE);
do_scroll_down();
} else if (func == do_page_up) {
do_page_up();
} else if (func == do_page_down) {
@@ -216,7 +216,7 @@ void do_help(void)
} else if (func == do_findnext) {
do_findnext();
#ifdef ENABLE_NANORC
} else if (func == (void *)implant) {
} else if (func == (functionptrtype)implant) {
implant(first_sc_for(MHELP, func)->expansion);
#endif
} else if (kbinput == KEY_WINCH) {
@@ -253,6 +253,7 @@ void do_help(void)
#ifdef ENABLE_LINENUMBERS
margin = was_margin;
editwincols = COLS - margin;
#endif
tabsize = was_tabsize;
#ifdef ENABLE_COLOR

View File

@@ -227,7 +227,7 @@ char *get_history_completion(filestruct **h, char *s, size_t len)
* match, or len is 0. Return s. */
return (char *)s;
}
#endif /* ENSABLE_TABCOMP */
#endif /* ENABLE_TABCOMP */
void history_error(const char *msg, ...)
{

View File

@@ -314,15 +314,17 @@ void do_prev_word(bool allow_punct, bool update_screen)
edit_redraw(was_current, FLOWING);
}
/* Move to the next word. If allow_punct is TRUE, treat punctuation
* as part of a word. When requested, update the screen afterwards.
/* Move to the next word. If after_ends is TRUE, stop at the ends of words
* instead of their beginnings. If allow_punct is TRUE, treat punctuation
* as part of a word. When requested, update the screen afterwards.
* Return TRUE if we started on a word, and FALSE otherwise. */
bool do_next_word(bool allow_punct, bool update_screen)
bool do_next_word(bool after_ends, bool allow_punct, bool update_screen)
{
filestruct *was_current = openfile->current;
bool started_on_word = is_word_mbchar(openfile->current->data +
openfile->current_x, allow_punct);
bool seen_space = !started_on_word;
bool seen_word = started_on_word;
/* Move forward until we reach the start of a word. */
while (TRUE) {
@@ -340,13 +342,26 @@ bool do_next_word(bool allow_punct, bool update_screen)
openfile->current_x);
}
/* If this is not a word character, then it's a separator; else
* if we've already seen a separator, then it's a word start. */
if (!is_word_mbchar(openfile->current->data + openfile->current_x,
#ifndef NANO_TINY
if (after_ends) {
/* If this is a word character, continue; else it's a separator,
* and if we've already seen a word, then it's a word end. */
if (is_word_mbchar(openfile->current->data + openfile->current_x,
allow_punct))
seen_space = TRUE;
else if (seen_space)
break;
seen_word = TRUE;
else if (seen_word)
break;
} else
#endif
{
/* If this is not a word character, then it's a separator; else
* if we've already seen a separator, then it's a word start. */
if (!is_word_mbchar(openfile->current->data + openfile->current_x,
allow_punct))
seen_space = TRUE;
else if (seen_space)
break;
}
}
if (update_screen)
@@ -363,11 +378,12 @@ void do_prev_word_void(void)
do_prev_word(ISSET(WORD_BOUNDS), TRUE);
}
/* Move to the next word in the file, treating punctuation as part of a word
* if the WORD_BOUNDS flag is set, and update the screen afterwards. */
/* Move to the next word in the file. If the AFTER_ENDS flag is set, stop
* at word ends instead of beginnings. If the WORD_BOUNDS flag is set, treat
* punctuation as part of a word. Update the screen afterwards. */
void do_next_word_void(void)
{
do_next_word(ISSET(WORD_BOUNDS), TRUE);
do_next_word(ISSET(AFTER_ENDS), ISSET(WORD_BOUNDS), TRUE);
}
/* Move to the beginning of the current line (or softwrapped chunk).
@@ -481,18 +497,12 @@ void do_end(void)
update_line(openfile->current, openfile->current_x);
}
/* Move the cursor to the preceding line or chunk. If scroll_only is TRUE,
* also scroll the screen one row, so the cursor stays in the same spot. */
void do_up(bool scroll_only)
/* Move the cursor to the preceding line or chunk. */
void do_up(void)
{
filestruct *was_current = openfile->current;
size_t leftedge, target_column;
/* When just scrolling and the top of the file is onscreen, get out. */
if (scroll_only && openfile->edittop == openfile->fileage &&
openfile->firstcolumn == 0)
return;
get_edge_and_target(&leftedge, &target_column);
/* If we can't move up one line or chunk, we're at top of file. */
@@ -501,18 +511,17 @@ void do_up(bool scroll_only)
set_proper_index_and_pww(&leftedge, target_column, FALSE);
if (scroll_only)
edit_scroll(BACKWARD, 1);
edit_redraw(was_current, FLOWING);
if (openfile->current_y == 0 && ISSET(SMOOTH_SCROLL))
edit_scroll(BACKWARD);
else
edit_redraw(was_current, FLOWING);
/* <Up> should not change placewewant, so restore it. */
openfile->placewewant = leftedge + target_column;
}
/* Move the cursor to next line or chunk. If scroll_only is TRUE, also
* scroll the screen one row, so the cursor stays in the same spot. */
void do_down(bool scroll_only)
/* Move the cursor to next line or chunk. */
void do_down(void)
{
filestruct *was_current = openfile->current;
size_t leftedge, target_column;
@@ -525,38 +534,43 @@ void do_down(bool scroll_only)
set_proper_index_and_pww(&leftedge, target_column, TRUE);
if (scroll_only)
edit_scroll(FORWARD, 1);
edit_redraw(was_current, FLOWING);
if (openfile->current_y == editwinrows - 1 && ISSET(SMOOTH_SCROLL))
edit_scroll(FORWARD);
else
edit_redraw(was_current, FLOWING);
/* <Down> should not change placewewant, so restore it. */
openfile->placewewant = leftedge + target_column;
}
/* Move up one line or chunk. */
void do_up_void(void)
{
do_up(FALSE);
}
/* Move down one line or chunk. */
void do_down_void(void)
{
do_down(FALSE);
}
#ifndef NANO_TINY
#ifdef ENABLE_HELP
/* Scroll up one line or chunk without scrolling the cursor. */
void do_scroll_up(void)
{
do_up(TRUE);
/* When the top of the file is onscreen, we can't scroll. */
if (openfile->edittop->prev == NULL && openfile->firstcolumn == 0)
return;
if (openfile->current_y == editwinrows - 1)
do_up();
if (editwinrows > 1)
edit_scroll(BACKWARD);
}
/* Scroll down one line or chunk without scrolling the cursor. */
void do_scroll_down(void)
{
do_down(TRUE);
if (openfile->current_y == 0)
do_down();
if (openfile->edittop->next != NULL
#ifndef NANO_TINY
|| chunk_for(openfile->firstcolumn, openfile->edittop) <
number_of_chunks_in(openfile->edittop)
#endif
)
edit_scroll(FORWARD);
}
#endif

View File

@@ -42,6 +42,12 @@
#include <sys/vt.h>
#endif
#ifdef ENABLE_MULTIBUFFER
#define read_them_all TRUE
#else
#define read_them_all FALSE
#endif
#ifdef ENABLE_MOUSE
static int oldinterval = -1;
/* Used to store the user's original mouse click interval. */
@@ -63,8 +69,7 @@ static struct sigaction act;
static bool input_was_aborted = FALSE;
/* Whether reading from standard input was aborted via ^C. */
/* Create a new linestruct node. Note that we do not set prevnode->next
* to the new line. */
/* Create a new linestruct node. Note that we do not set prevnode->next. */
filestruct *make_new_node(filestruct *prevnode)
{
filestruct *newnode = nmalloc(sizeof(filestruct));
@@ -199,12 +204,7 @@ void renumber(filestruct *line)
partition *partition_filestruct(filestruct *top, size_t top_x,
filestruct *bot, size_t bot_x)
{
partition *p;
assert(top != NULL && bot != NULL && openfile->fileage != NULL && openfile->filebot != NULL);
/* Initialize the partition. */
p = (partition *)nmalloc(sizeof(partition));
partition *p = nmalloc(sizeof(partition));
/* If the top and bottom of the partition are different from the top
* and bottom of the buffer, save the latter and then set them
@@ -247,8 +247,6 @@ partition *partition_filestruct(filestruct *top, size_t top_x,
* to (filebot, $) again. */
void unpartition_filestruct(partition **p)
{
assert(p != NULL && openfile->fileage != NULL && openfile->filebot != NULL);
/* Reattach the line above the top of the partition, and restore the
* text before top_x from top_data. Free top_data when we're done
* with it. */
@@ -299,8 +297,6 @@ void extract_buffer(filestruct **file_top, filestruct **file_bot,
bool same_line = FALSE;
#endif
assert(file_top != NULL && file_bot != NULL && top != NULL && bot != NULL);
/* If (top, top_x)-(bot, bot_x) doesn't cover any text, get out. */
if (top == bot && top_x == bot_x)
return;
@@ -357,8 +353,8 @@ void extract_buffer(filestruct **file_top, filestruct **file_bot,
delete_node(openfile->fileage);
/* Renumber, starting with the line after the original file_bot. */
renumber(file_bot_save->next);
/* Renumber, starting at the last line of the original buffer. */
renumber(file_bot_save);
}
/* Since the text has now been saved, remove it from the buffer. */
@@ -412,8 +408,6 @@ void ingraft_buffer(filestruct *somebuffer)
bool right_side_up = FALSE, single_line = FALSE;
#endif
assert(somebuffer != NULL);
#ifndef NANO_TINY
/* Keep track of whether the mark begins inside the partition and
* will need adjustment. */
@@ -507,17 +501,17 @@ openfilestruct *make_new_opennode(void)
return (openfilestruct *)nmalloc(sizeof(openfilestruct));
}
#ifdef ENABLE_MULTIBUFFER
/* Unlink a node from the rest of the circular list, and delete it. */
void unlink_opennode(openfilestruct *fileptr)
{
assert(fileptr != fileptr->prev && fileptr != fileptr->next);
#ifdef ENABLE_MULTIBUFFER
if (fileptr == firstfile)
firstfile = firstfile->next;
fileptr->prev->next = fileptr->next;
fileptr->next->prev = fileptr->prev;
#endif
delete_opennode(fileptr);
}
@@ -534,6 +528,7 @@ void delete_opennode(openfilestruct *fileptr)
#endif
free(fileptr);
}
#endif
/* Display a warning about a key disabled in view mode. */
void print_view_warning(void)
@@ -556,14 +551,15 @@ void say_there_is_no_help(void)
}
#endif
/* Make nano exit gracefully. */
/* Exit normally: restore the terminal state and save history files. */
void finish(void)
{
/* Blank the statusbar and (if applicable) the shortcut list,
* and move the cursor to the last line of the screen. */
/* Blank the statusbar and (if applicable) the shortcut list. */
blank_statusbar();
blank_bottombars();
wrefresh(bottomwin);
/* Switch on the cursor and exit from curses mode. */
curs_set(1);
endwin();
@@ -587,73 +583,61 @@ void finish(void)
exit(0);
}
/* Make nano die gracefully. */
/* Die gracefully -- by restoring the terminal state and saving any buffers
* that were modified. */
void die(const char *msg, ...)
{
va_list ap;
openfilestruct *firstone = openfile;
/* Switch on the cursor and leave curses mode. */
curs_set(1);
endwin();
/* Restore the old terminal settings. */
tcsetattr(0, TCSANOW, &oldterm);
/* Display the dying message. */
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end(ap);
while (openfile) {
#ifndef NANO_TINY
/* If the current buffer has a lockfile, remove it. */
if (openfile && ISSET(LOCKING) && openfile->lock_filename)
delete_lockfile(openfile->lock_filename);
/* If the current buffer has a lockfile, remove it. */
if (ISSET(LOCKING) && openfile->lock_filename)
delete_lockfile(openfile->lock_filename);
#endif
/* If the current buffer was modified, ensure it is unpartitioned,
* then save it. When in restricted mode, we don't save anything,
* because it would write files not mentioned on the command line. */
if (openfile->modified && !ISSET(RESTRICTED)) {
if (filepart != NULL)
unpartition_filestruct(&filepart);
/* If the current file buffer was modified, save it. */
if (openfile && openfile->modified) {
/* If the buffer is partitioned, unpartition it first. */
if (filepart != NULL)
unpartition_filestruct(&filepart);
die_save_file(openfile->filename, openfile->current_stat);
}
#ifdef ENABLE_MULTIBUFFER
/* Save all of the other modified file buffers, if any. */
if (openfile != NULL) {
openfilestruct *firstone = openfile;
while (openfile->next != firstone) {
openfile = openfile->next;
#ifndef NANO_TINY
if (ISSET(LOCKING) && openfile->lock_filename)
delete_lockfile(openfile->lock_filename);
#endif
if (openfile->modified)
die_save_file(openfile->filename, openfile->current_stat);
emergency_save(openfile->filename, openfile->current_stat);
}
}
filepart = NULL;
#ifdef ENABLE_MULTIBUFFER
openfile = openfile->next;
#endif
if (openfile == firstone)
break;
}
/* Abandon the building. */
exit(1);
}
/* Save the current file under the name specified in die_filename, which
* is modified to be unique if necessary. */
void die_save_file(const char *die_filename, struct stat *die_stat)
/* Save the current buffer under the given name.
* If necessary, the name is modified to be unique. */
void emergency_save(const char *die_filename, struct stat *die_stat)
{
char *targetname;
bool failed = TRUE;
/* If we're using restricted mode, don't write any emergency backup
* files, since that would allow reading from or writing to files
* not specified on the command line. */
if (ISSET(RESTRICTED))
return;
/* If we can't save, we have really bad problems, but we might as
* well try. */
/* If the buffer has no name, simply call it "nano". */
if (*die_filename == '\0')
die_filename = "nano";
@@ -672,9 +656,8 @@ void die_save_file(const char *die_filename, struct stat *die_stat)
_("Too many backup files?"));
#ifndef NANO_TINY
/* Try and chmod/chown the save file to the values of the original file,
* but don't worry if it fails because we're supposed to be bailing as
* fast as possible. */
/* 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 (die_stat) {
IGNORE_CALL_RESULT(chmod(targetname, die_stat->st_mode));
IGNORE_CALL_RESULT(chown(targetname, die_stat->st_uid,
@@ -907,6 +890,9 @@ void usage(void)
print_opt("-w", "--nowrap", N_("Don't hard-wrap long lines"));
#endif
print_opt("-x", "--nohelp", N_("Don't show the two help lines"));
#ifndef NANO_TINY
print_opt("-y", "--afterends", N_("Make Ctrl+Right stop at word ends"));
#endif
if (!ISSET(RESTRICTED))
print_opt("-z", "--suspend", N_("Enable suspension"));
#ifndef NANO_TINY
@@ -1106,12 +1092,6 @@ void close_and_go(void)
finish();
}
/* Another placeholder for function mapping. */
void do_cancel(void)
{
;
}
/* Make a note that reading from stdin was concluded with ^C. */
RETSIGTYPE make_a_note(int signal)
{
@@ -1124,7 +1104,7 @@ bool scoop_stdin(void)
struct sigaction oldaction, newaction;
/* Original and temporary handlers for SIGINT. */
bool setup_failed = FALSE;
/* Whether setting up the SIGINT handler failed. */
/* Whether setting up the temporary SIGINT handler failed. */
FILE *stream;
int thetty;
@@ -1132,7 +1112,7 @@ bool scoop_stdin(void)
endwin();
tcsetattr(0, TCSANOW, &oldterm);
fprintf(stderr, _("Reading from stdin, ^C to abort\n"));
fprintf(stderr, _("Reading from standard input; type ^D or ^D^D to finish.\n"));
#ifndef NANO_TINY
/* Enable interpretation of the special control keys so that
@@ -1143,12 +1123,12 @@ bool scoop_stdin(void)
/* Set things up so that SIGINT will cancel the reading. */
if (sigaction(SIGINT, NULL, &newaction) == -1) {
setup_failed = TRUE;
nperror("sigaction");
perror("sigaction");
} else {
newaction.sa_handler = make_a_note;
if (sigaction(SIGINT, &newaction, &oldaction) == -1) {
setup_failed = TRUE;
nperror("sigaction");
perror("sigaction");
}
}
@@ -1164,9 +1144,10 @@ bool scoop_stdin(void)
}
/* Read the input into a new buffer. */
open_buffer("", FALSE);
read_file(stream, 0, "stdin", TRUE, FALSE);
open_buffer("", TRUE);
read_file(stream, 0, "stdin", TRUE);
openfile->edittop = openfile->fileage;
fprintf(stderr, ".\n");
/* Reconnect the tty as the input source. */
thetty = open("/dev/tty", O_RDONLY);
@@ -1181,7 +1162,7 @@ bool scoop_stdin(void)
/* If it was changed, restore the handler for SIGINT. */
if (!setup_failed && sigaction(SIGINT, &oldaction, NULL) == -1)
nperror("sigaction");
perror("sigaction");
terminal_init();
doupdate();
@@ -1235,6 +1216,18 @@ void signal_init(void)
sigaction(SIGTSTP, &act, NULL);
#endif
}
#if !defined(NANO_TINY) && !defined(DEBUG)
if (getenv("NANO_NOCATCH") == NULL) {
/* Trap SIGSEGV and SIGABRT to save any changed buffers and reset
* the terminal to a usable state. Reset these handlers to their
* defaults as soon as their signal fires. */
act.sa_handler = handle_crash;
act.sa_flags |= SA_RESETHAND;
sigaction(SIGSEGV, &act, NULL);
sigaction(SIGABRT, &act, NULL);
}
#endif
}
/* Handler for SIGHUP (hangup) and SIGTERM (terminate). */
@@ -1243,6 +1236,14 @@ RETSIGTYPE handle_hupterm(int signal)
die(_("Received SIGHUP or SIGTERM\n"));
}
#if !defined(NANO_TINY) && !defined(DEBUG)
/* Handler for SIGSEGV (segfault) and SIGABRT (abort). */
RETSIGTYPE handle_crash(int signal)
{
die(_("Sorry! Nano crashed! Code: %d. Please report a bug.\n"), signal);
}
#endif
/* Handler for SIGTSTP (suspend). */
RETSIGTYPE do_suspend(int signal)
{
@@ -1420,12 +1421,6 @@ void do_toggle(int flag)
statusline(HUSH, "%s %s", _(flagtostr(flag)),
enabled ? _("enabled") : _("disabled"));
}
/* Bleh. */
void do_toggle_void(void)
{
;
}
#endif /* !NANO_TINY */
/* Disable extended input and output processing in our terminal
@@ -1518,7 +1513,6 @@ void terminal_init(void)
if (!newterm_set) {
#endif
raw();
nonl();
noecho();
@@ -1621,6 +1615,29 @@ int do_mouse(void)
}
#endif /* ENABLE_MOUSE */
/* Return TRUE when the given function is a cursor-moving command. */
bool wanted_to_move(void (*func)(void))
{
return func == do_left || func == do_right ||
func == do_up || func == do_down ||
func == do_home || func == do_end ||
func == do_prev_word_void || func == do_next_word_void ||
#ifdef ENABLE_JUSTIFY
func == do_para_begin_void || func == do_para_end_void ||
#endif
func == do_prev_block || func == do_next_block ||
func == do_page_up || func == do_page_down ||
func == to_first_line || func == to_last_line;
}
/* Return TRUE when the given shortcut is valid in view mode. */
bool okay_for_view(const sc *shortcut)
{
const subnfunc *func = sctofunc(shortcut);
return (func != NULL && func->viewok);
}
/* Read in a keystroke. Act on the keystroke if it is a shortcut or a toggle;
* otherwise, insert it into the edit buffer. If allow_funcs is FALSE, don't
* do anything with the keystroke -- just return it. */
@@ -1712,7 +1729,7 @@ int do_input(bool allow_funcs)
if (shortcut == NULL)
pletion_line = NULL;
else {
if (ISSET(VIEW_MODE) && !sctofunc(shortcut)->viewok) {
if (ISSET(VIEW_MODE) && !okay_for_view(shortcut)) {
print_view_warning();
return ERR;
}
@@ -1732,7 +1749,7 @@ int do_input(bool allow_funcs)
pletion_line = NULL;
#endif
#ifdef ENABLE_NANORC
if (shortcut->func == (void *)implant) {
if (shortcut->func == (functionptrtype)implant) {
implant(shortcut->expansion);
return 42;
}
@@ -1770,8 +1787,7 @@ int do_input(bool allow_funcs)
if (!shift_held && openfile->kind_of_mark == SOFTMARK &&
(openfile->current != was_current ||
openfile->current_x != was_x ||
(shortcut->func >= to_first_line &&
shortcut->func <= do_right))) {
wanted_to_move(shortcut->func))) {
openfile->mark = NULL;
refresh_needed = TRUE;
} else if (openfile->current != was_current)
@@ -1787,7 +1803,7 @@ int do_input(bool allow_funcs)
wrap_reset();
#endif
#ifdef ENABLE_COLOR
if (!refresh_needed && !sctofunc(shortcut)->viewok)
if (!refresh_needed && !okay_for_view(shortcut))
check_the_multis(openfile->current);
#endif
if (!refresh_needed && (shortcut->func == do_delete ||
@@ -1920,11 +1936,6 @@ int main(int argc, char **argv)
#ifdef ENABLE_WRAPPING
bool forced_wrapping = FALSE;
/* Should long lines be automatically hard wrapped? */
#endif
#ifdef ENABLE_MULTIBUFFER
bool is_multibuffer;
/* The actual value of the multibuffer option, restored after
* we've loaded all files given on the command line. */
#endif
const struct option long_options[] = {
{"boldtext", 0, NULL, 'D'},
@@ -1997,6 +2008,7 @@ int main(int argc, char **argv)
{"autoindent", 0, NULL, 'i'},
{"cutfromcursor", 0, NULL, 'k'},
{"unix", 0, NULL, 'u'},
{"afterends", 0, NULL, 'y'},
{"softwrap", 0, NULL, '$'},
#endif
{NULL, 0, NULL, 0}
@@ -2055,15 +2067,9 @@ int main(int argc, char **argv)
while ((optchr =
getopt_long(argc, argv,
"ABC:DEFGHIKLMNOPQ:RST:UVWX:Y:abcdefghijklmno:pqr:s:tuvwxz$",
"ABC:DEFGHIKLMNOPQ:RST:UVWX:Y:abcdefghijklmno:pqr:s:tuvwxyz$",
long_options, NULL)) != -1) {
switch (optchr) {
case 'b':
case 'e':
case 'f':
case 'j':
/* Pico compatibility flags. */
break;
#ifndef NANO_TINY
case 'A':
SET(SMART_HOME);
@@ -2180,6 +2186,9 @@ int main(int argc, char **argv)
case 'g':
SET(SHOW_CURSOR);
break;
case 'h':
usage();
exit(0);
#ifndef NANO_TINY
case 'i':
SET(AUTOINDENT);
@@ -2188,6 +2197,11 @@ int main(int argc, char **argv)
SET(CUT_FROM_CURSOR);
break;
#endif
#ifdef ENABLE_LINENUMBERS
case 'l':
SET(LINE_NUMBERS);
break;
#endif
#ifdef ENABLE_MOUSE
case 'm':
SET(USE_MOUSE);
@@ -2250,6 +2264,11 @@ int main(int argc, char **argv)
case 'x':
SET(NO_HELP);
break;
#ifndef NANO_TINY
case 'y':
SET(AFTER_ENDS);
break;
#endif
case 'z':
SET(SUSPEND);
break;
@@ -2258,14 +2277,11 @@ int main(int argc, char **argv)
SET(SOFTWRAP);
break;
#endif
#ifdef ENABLE_LINENUMBERS
case 'l':
SET(LINE_NUMBERS);
case 'b': /* Pico compatibility flags. */
case 'e':
case 'f':
case 'j':
break;
#endif
case 'h':
usage();
exit(0);
default:
printf(_("Type '%s -h' for a list of available options.\n"), argv[0]);
exit(1);
@@ -2573,13 +2589,8 @@ int main(int argc, char **argv)
fprintf(stderr, "Main: open file\n");
#endif
#ifdef ENABLE_MULTIBUFFER
is_multibuffer = ISSET(MULTIBUFFER);
SET(MULTIBUFFER);
#endif
/* Read the files mentioned on the command line into new buffers. */
while (optind < argc && (!openfile || ISSET(MULTIBUFFER))) {
while (optind < argc && (!openfile || read_them_all)) {
ssize_t givenline = 0, givencol = 0;
/* If there's a +LINE[,COLUMN] argument here, eat it up. */
@@ -2591,10 +2602,10 @@ int main(int argc, char **argv)
/* If the filename is a dash, read from standard input; otherwise,
* open the file; skip positioning the cursor if either failed. */
if (strcmp(argv[optind], "-") == 0) {
optind++;
if (!scoop_stdin())
continue;
optind++;
} else if (!open_buffer(argv[optind++], FALSE))
} else if (!open_buffer(argv[optind++], TRUE))
continue;
/* If a position was given on the command line, go there. */
@@ -2614,15 +2625,12 @@ int main(int argc, char **argv)
* directories, then open a blank buffer and allow editing. Otherwise,
* switch from the last opened file to the next, that is: the first. */
if (openfile == NULL) {
open_buffer("", FALSE);
open_buffer("", TRUE);
UNSET(VIEW_MODE);
}
#ifdef ENABLE_MULTIBUFFER
else
openfile = openfile->next;
if (!is_multibuffer)
UNSET(MULTIBUFFER);
#endif
#ifdef DEBUG
@@ -2672,6 +2680,7 @@ int main(int argc, char **argv)
} else
edit_refresh();
errno = 0;
focusing = TRUE;
/* Forget any earlier statusbar x position. */

View File

@@ -142,6 +142,11 @@
#define REPLACING 1
#define INREGION 2
#ifdef ENABLE_COLOR
#define USE_THE_DEFAULT -1
#define BAD_COLOR -2
#endif
/* Enumeration types. */
typedef enum {
NIX_FILE, DOS_FILE, MAC_FILE
@@ -408,10 +413,12 @@ typedef struct openfilestruct {
colortype *colorstrings;
/* The file's associated colors. */
#endif
#ifdef ENABLE_MULTIBUFFER
struct openfilestruct *next;
/* The next open file, if any. */
struct openfilestruct *prev;
/* The preceding open file, if any. */
#endif
} openfilestruct;
#ifdef ENABLE_NANORC
@@ -536,7 +543,8 @@ enum
SHOW_CURSOR,
LINE_NUMBERS,
NO_PAUSES,
AT_BLANKS
AT_BLANKS,
AFTER_ENDS
};
/* Flags for the menus in which a given function should be present. */

View File

@@ -153,7 +153,7 @@ int do_statusbar_input(bool *finished)
shortcut->func == do_backspace))
;
#ifdef ENABLE_NANORC
else if (shortcut->func == (void *)implant)
else if (shortcut->func == (functionptrtype)implant)
implant(shortcut->expansion);
#endif
else if (shortcut->func == do_verbatim_input)
@@ -171,7 +171,7 @@ int do_statusbar_input(bool *finished)
/* Handle any other shortcut in the current menu, setting finished
* to TRUE to indicate that we're done after running or trying to
* run its associated function. */
if (!ISSET(VIEW_MODE) || sctofunc(shortcut)->viewok)
if (!ISSET(VIEW_MODE) || okay_for_view(shortcut))
shortcut->func();
*finished = TRUE;
}
@@ -187,27 +187,25 @@ void do_statusbar_output(int *the_input, size_t input_len,
{
char *output = charalloc(input_len + 1);
char onechar[MAXCHARLEN];
int i, char_len;
size_t char_len, i, j = 0;
/* Copy the typed stuff so it can be treated. */
for (i = 0; i < input_len; i++)
output[i] = (char)the_input[i];
output[i] = '\0';
i = 0;
while (i < input_len) {
while (j < input_len) {
/* Encode any NUL byte as 0x0A. */
if (output[i] == '\0')
output[i] = '\n';
if (output[j] == '\0')
output[j] = '\n';
/* Interpret the next multibyte character. */
char_len = parse_mbchar(output + i, onechar, NULL);
char_len = parse_mbchar(output + j, onechar, NULL);
i += char_len;
j += char_len;
/* When filtering, skip any ASCII control character. */
if (filtering && is_ascii_cntrl_char(*(output + i - char_len)))
if (filtering && is_ascii_cntrl_char(*(output + j - char_len)))
continue;
/* Insert the typed character into the existing answer string. */
@@ -294,17 +292,28 @@ void do_statusbar_cut_text(void)
void do_statusbar_next_word(void)
{
bool seen_space = !is_word_mbchar(answer + statusbar_x, FALSE);
bool seen_word = !seen_space;
/* Move forward until we reach the start of a word. */
/* Move forward until we reach either the end or the start of a word,
* depending on whether the AFTER_ENDS flag is set or not. */
while (answer[statusbar_x] != '\0') {
statusbar_x = move_mbright(answer, statusbar_x);
/* If this is not a word character, then it's a separator; else
* if we've already seen a separator, then it's a word start. */
if (!is_word_mbchar(answer + statusbar_x, FALSE))
seen_space = TRUE;
else if (seen_space)
break;
if (ISSET(AFTER_ENDS)) {
/* If this is a word character, continue; else it's a separator,
* and if we've already seen a word, then it's a word end. */
if (is_word_mbchar(answer + statusbar_x, FALSE))
seen_word = TRUE;
else if (seen_word)
break;
} else {
/* If this is not a word character, then it's a separator; else
* if we've already seen a separator, then it's a word start. */
if (!is_word_mbchar(answer + statusbar_x, FALSE))
seen_space = TRUE;
else if (seen_space)
break;
}
}
update_the_statusbar();
@@ -661,20 +670,16 @@ int do_prompt(bool allow_tabs, bool allow_files,
int do_yesno_prompt(bool all, const char *msg)
{
int response = -2, width = 16;
/* TRANSLATORS: For the next three strings, if possible, specify
* the single-byte letters for both your language and English.
* For example, in French: "OoYy", for both "Oui" and "Yes". */
/* TRANSLATORS: For the next three strings, specify the starting letters
* of the translations for "Yes"/"No"/"All". The first letter of each of
* these strings MUST be a single-byte letter; others may be multi-byte. */
const char *yesstr = _("Yy");
const char *nostr = _("Nn");
const char *allstr = _("Aa");
/* The above three variables consist of all the single-byte characters
* that are accepted for the corresponding answer. Of each variable,
* the first character is displayed in the help lines. */
while (response == -2) {
int kbinput;
char letter[MAXCHARLEN + 1];
int kbinput, index = 0;
if (!ISSET(NO_HELP)) {
char shortstr[MAXCHARLEN + 2];
@@ -691,16 +696,16 @@ int do_yesno_prompt(bool all, const char *msg)
wmove(bottomwin, 1, 0);
post_one_key(shortstr, _("Yes"), width);
shortstr[1] = nostr[0];
wmove(bottomwin, 2, 0);
post_one_key(shortstr, _("No"), width);
if (all) {
shortstr[1] = allstr[0];
wmove(bottomwin, 1, width);
post_one_key(shortstr, _("All"), width);
}
shortstr[1] = nostr[0];
wmove(bottomwin, 2, 0);
post_one_key(shortstr, _("No"), width);
wmove(bottomwin, 2, width);
post_one_key("^C", _("Cancel"), width);
}
@@ -717,12 +722,34 @@ int do_yesno_prompt(bool all, const char *msg)
/* When not replacing, show the cursor while waiting for a key. */
kbinput = get_kbinput(bottomwin, !all);
/* See if the pressed key is in the Yes, No, or All strings. */
if (strchr(yesstr, kbinput) != NULL)
#ifdef ENABLE_NLS
letter[index++] = (unsigned char)kbinput;
#ifdef ENABLE_UTF8
/* If the received code is a UTF-8 starter byte, get also the
* continuation bytes and assemble them into one letter. */
if (using_utf8() && 0xC0 <= kbinput && kbinput <= 0xF7) {
int extras = (kbinput / 16) % 4 + (kbinput <= 0xCF ? 1 : 0);
while (extras <= get_key_buffer_len() && extras-- > 0)
letter[index++] = (unsigned char)get_kbinput(bottomwin, !all);
}
#endif
letter[index] = '\0';
/* See if the typed letter is in the Yes, No, or All strings. */
if (strstr(yesstr, letter) != NULL)
response = 1;
else if (strchr(nostr, kbinput) != NULL)
else if (strstr(nostr, letter) != NULL)
response = 0;
else if (all && strchr(allstr, kbinput) != NULL)
else if (all && strstr(allstr, letter) != NULL)
response = 2;
else
#endif /* ENABLE_NLS */
if (strchr("Yy", kbinput) != NULL)
response = 1;
else if (strchr("Nn", kbinput) != NULL)
response = 0;
else if (all && strchr("Aa", kbinput) != NULL)
response = 2;
else if (func_from_key(&kbinput) == do_cancel)
response = -1;

View File

@@ -40,9 +40,6 @@ extern bool focusing;
extern bool as_an_at;
extern int margin;
extern int editwincols;
extern bool suppress_cursorpos;
extern message_type lastmessage;
@@ -91,10 +88,13 @@ extern char *last_search;
extern char *present_path;
extern unsigned flags[4];
extern WINDOW *topwin;
extern WINDOW *edit;
extern WINDOW *bottomwin;
extern int editwinrows;
extern int editwincols;
extern int margin;
extern filestruct *cutbuffer;
extern filestruct *cutbottom;
@@ -267,7 +267,7 @@ void do_uncut_text(void);
/* Most functions in files.c. */
void initialize_buffer_text(void);
void set_modified(void);
bool open_buffer(const char *filename, bool undoable);
bool open_buffer(const char *filename, bool new_buffer);
#ifdef ENABLE_SPELLER
void replace_buffer(const char *filename);
#ifndef NANO_TINY
@@ -281,8 +281,7 @@ void switch_to_prev_buffer(void);
void switch_to_next_buffer(void);
bool close_buffer(void);
#endif
void read_file(FILE *f, int fd, const char *filename, bool undoable,
bool checkwritable);
void read_file(FILE *f, int fd, const char *filename, bool undoable);
int open_file(const char *filename, bool newfie, bool quiet, FILE **f);
char *get_next_filename(const char *name, const char *suffix);
void do_insertfile_void(void);
@@ -381,16 +380,14 @@ void do_para_end_void(void);
void do_prev_block(void);
void do_next_block(void);
void do_prev_word(bool allow_punct, bool update_screen);
bool do_next_word(bool allow_punct, bool update_screen);
bool do_next_word(bool after_ends, bool allow_punct, bool update_screen);
void do_prev_word_void(void);
void do_next_word_void(void);
void do_home(void);
void do_end(void);
void do_up(bool scroll_only);
void do_down(bool scroll_only);
void do_up_void(void);
void do_down_void(void);
#ifndef NANO_TINY
void do_up(void);
void do_down(void);
#ifdef ENABLE_HELP
void do_scroll_up(void);
void do_scroll_down(void);
#endif
@@ -413,8 +410,10 @@ void extract_buffer(filestruct **file_top, filestruct **file_bot,
void ingraft_buffer(filestruct *somebuffer);
void copy_from_buffer(filestruct *somebuffer);
openfilestruct *make_new_opennode(void);
#ifdef ENABLE_MULTIBUFFER
void unlink_opennode(openfilestruct *fileptr);
void delete_opennode(openfilestruct *fileptr);
#endif
void print_view_warning(void);
void show_restricted_warning(void);
#ifndef ENABLE_HELP
@@ -422,11 +421,14 @@ void say_there_is_no_help(void);
#endif
void finish(void);
void die(const char *msg, ...);
void die_save_file(const char *die_filename, struct stat *die_stat);
void emergency_save(const char *die_filename, struct stat *die_stat);
void window_init(void);
void do_exit(void);
void close_and_go(void);
RETSIGTYPE handle_hupterm(int signal);
#ifndef DEBUG
RETSIGTYPE handle_crash(int signal);
#endif
RETSIGTYPE do_suspend(int signal);
RETSIGTYPE do_continue(int signal);
#ifndef NANO_TINY
@@ -434,13 +436,13 @@ RETSIGTYPE handle_sigwinch(int signal);
void regenerate_screen(void);
void allow_sigwinch(bool allow);
void do_toggle(int flag);
void do_toggle_void(void);
void enable_signals(void);
#endif
void disable_flow_control(void);
void enable_flow_control(void);
void terminal_init(void);
void unbound_key(int code);
bool okay_for_view(const sc *shortcut);
int do_input(bool allow_funcs);
void do_output(char *output, size_t output_len, bool allow_cntrls);
@@ -471,7 +473,6 @@ int do_yesno_prompt(bool all, const char *msg);
/* Most functions in rcfile.c. */
#ifdef ENABLE_NANORC
#ifdef ENABLE_COLOR
bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright);
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage);
#endif
void parse_rcfile(FILE *rcstream, bool syntax_only);
@@ -479,18 +480,18 @@ void do_rcfiles(void);
#endif /* ENABLE_NANORC */
/* Most functions in search.c. */
void not_found_msg(const char *str);
void search_replace_abort(void);
void tidy_up_after_search(void);
int findnextstr(const char *needle, bool whole_word_only, int modus,
size_t *match_len, bool skipone, const filestruct *begin, size_t begin_x);
void do_search(void);
void do_search_forward(void);
void do_search_backward(void);
void do_research(void);
#ifndef NANO_TINY
void do_findprevious(void);
void do_findnext(void);
#endif
void do_research(void);
void not_found_msg(const char *str);
void go_looking(void);
ssize_t do_replace_loop(const char *needle, bool whole_word_only,
const filestruct *real_current, size_t *real_current_x);
@@ -522,7 +523,6 @@ void do_unindent(void);
bool white_string(const char *s);
#ifdef ENABLE_COMMENT
void do_comment(void);
bool comment_line(undo_type action, filestruct *f, const char *comment_seq);
#endif
void do_undo(void);
void do_redo(void);
@@ -661,7 +661,7 @@ bool line_needs_update(const size_t old_column, const size_t new_column);
int go_back_chunks(int nrows, filestruct **line, size_t *leftedge);
int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge);
bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge);
void edit_scroll(bool direction, int nrows);
void edit_scroll(bool direction);
#ifndef NANO_TINY
size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
bool *end_of_line);
@@ -692,7 +692,6 @@ void do_credits(void);
#endif
/* These are just name definitions. */
void do_cancel(void);
void case_sens_void(void);
void regexp_void(void);
void backwards_void(void);
@@ -703,6 +702,7 @@ void to_files_void(void);
void goto_dir_void(void);
#endif
#ifndef NANO_TINY
void do_toggle_void(void);
void dos_format_void(void);
void mac_format_void(void);
void append_void(void);
@@ -714,5 +714,6 @@ void flip_execute(void);
void flip_newbuffer(void);
#endif
void discard_buffer(void);
void do_cancel(void);
#endif /* !PROTO_H */

View File

@@ -31,14 +31,14 @@
#ifdef ENABLE_NANORC
#ifndef RCFILE_NAME
#define HOME_RC_NAME ".nanorc"
#define RCFILE_NAME "nanorc"
#else
#define HOME_RC_NAME RCFILE_NAME
#endif
static const rcoption rcopts[] = {
{"boldtext", BOLD_TEXT},
#ifdef ENABLE_LINENUMBERS
{"linenumbers", LINE_NUMBERS},
#endif
#ifdef ENABLE_JUSTIFY
{"brackets", 0},
#endif
@@ -48,6 +48,9 @@ static const rcoption rcopts[] = {
#endif
#ifdef ENABLE_HISTORIES
{"historylog", HISTORYLOG},
#endif
#ifdef ENABLE_LINENUMBERS
{"linenumbers", LINE_NUMBERS},
#endif
{"morespace", MORE_SPACE},
#ifdef ENABLE_MOUSE
@@ -85,6 +88,7 @@ static const rcoption rcopts[] = {
{"tempfile", TEMP_FILE},
{"view", VIEW_MODE},
#ifndef NANO_TINY
{"afterends", AFTER_ENDS},
{"allow_insecure_backup", INSECURE_BACKUP},
{"atblanks", AT_BLANKS},
{"autoindent", AUTOINDENT},
@@ -92,9 +96,9 @@ static const rcoption rcopts[] = {
{"backupdir", 0},
{"backwards", BACKWARDS_SEARCH},
{"casesensitive", CASE_SENSITIVE},
{"cut", CUT_FROM_CURSOR}, /* deprecated form, remove in 2020 */
{"cut", CUT_FROM_CURSOR}, /* deprecated form, remove end of 2018 */
{"cutfromcursor", CUT_FROM_CURSOR},
{"justifytrim", TRIM_BLANKS}, /* deprecated form, remove in 2020 */
{"justifytrim", TRIM_BLANKS}, /* deprecated form, remove end of 2018 */
{"locking", LOCKING},
{"matchbrackets", 0},
{"noconvert", NO_CONVERT},
@@ -413,7 +417,7 @@ void parse_binding(char *ptr, bool dobind)
* otherwise it is the name of a function. */
if (*funcptr == '"') {
newsc = nmalloc(sizeof(sc));
newsc->func = (void *)implant;
newsc->func = (functionptrtype)implant;
newsc->expansion = mallocstrcpy(NULL, funcptr + 1);
#ifndef NANO_TINY
newsc->toggle = 0;
@@ -449,7 +453,7 @@ void parse_binding(char *ptr, bool dobind)
#endif
#ifdef ENABLE_NANORC
/* Handle the special case of a key defined as a string. */
if (newsc->func == (void *)implant)
if (newsc->func == (functionptrtype)implant)
mask = MMOST | MHELP;
#endif
/* Now limit the given menu to those where the function exists. */
@@ -602,9 +606,39 @@ short color_to_short(const char *colorname, bool *bright)
return COLOR_MAGENTA;
else if (strcasecmp(colorname, "black") == 0)
return COLOR_BLACK;
else if (strcasecmp(colorname, "normal") == 0)
return USE_THE_DEFAULT;
rcfile_error(N_("Color \"%s\" not understood"), colorname);
return -1;
return BAD_COLOR;
}
/* 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_color_names(char *combostr, short *fg, short *bg, bool *bright)
{
char *comma = strchr(combostr, ',');
if (comma != NULL) {
*bg = color_to_short(comma + 1, bright);
if (*bright) {
rcfile_error(N_("A background color cannot be bright"));
return FALSE;
}
if (*bg == BAD_COLOR)
return FALSE;
*comma = '\0';
} else
*bg = USE_THE_DEFAULT;
if (comma != combostr) {
*fg = color_to_short(combostr, bright);
if (*fg == BAD_COLOR)
return FALSE;
} else
*fg = USE_THE_DEFAULT;
return TRUE;
}
/* Parse the color string in the line at ptr, and add it to the current
@@ -734,33 +768,6 @@ void parse_colors(char *ptr, int rex_flags)
}
}
/* Parse the color name, or pair of color names, in combostr. */
bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright)
{
char *comma = strchr(combostr, ',');
if (comma != NULL) {
*bg = color_to_short(comma + 1, bright);
if (*bright) {
rcfile_error(N_("A background color cannot be bright"));
return FALSE;
}
*comma = '\0';
} else
*bg = -1;
if (comma != combostr) {
*fg = color_to_short(combostr, bright);
/* If the specified foreground color is bad, ignore the regexes. */
if (*fg == -1)
return FALSE;
} else
*fg = -1;
return TRUE;
}
/* Parse the argument of an interface color option. */
colortype *parse_interface_color(char *combostr)
{
@@ -1249,7 +1256,7 @@ void do_rcfiles(void)
/* Now try the to find a nanorc file in the user's home directory
* or in the XDG configuration directories. */
if (have_nanorc(homedir, "/." RCFILE_NAME))
if (have_nanorc(homedir, "/" HOME_RC_NAME))
parse_one_nanorc();
else if (have_nanorc(xdgconfdir, "/nano/" RCFILE_NAME))
parse_one_nanorc();

View File

@@ -28,8 +28,8 @@
static bool came_full_circle = FALSE;
/* Have we reached the starting line again while searching? */
static bool regexp_compiled = FALSE;
/* Have we compiled any regular expressions? */
static bool have_compiled_regexp = FALSE;
/* Whether we have compiled a regular expression for the search. */
/* Compile the given regular expression and store it in search_regexp.
* Return TRUE if the expression is valid, and FALSE otherwise. */
@@ -50,43 +50,23 @@ bool regexp_init(const char *regexp)
return FALSE;
}
regexp_compiled = TRUE;
have_compiled_regexp = TRUE;
return TRUE;
}
/* Decompile the compiled regular expression we used in the last
* search, if any. */
void regexp_cleanup(void)
/* Free a compiled regular expression, if one was compiled; and schedule a
* full screen refresh when the mark is on, in case the cursor has moved. */
void tidy_up_after_search(void)
{
if (regexp_compiled) {
regexp_compiled = FALSE;
if (have_compiled_regexp) {
regfree(&search_regexp);
have_compiled_regexp = FALSE;
}
}
/* Report on the status bar that the given string was not found. */
void not_found_msg(const char *str)
{
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE);
size_t numchars = actual_x(disp, strnlenpt(disp, COLS / 2));
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
(disp[numchars] == '\0') ? "" : "...");
free(disp);
}
/* Abort the current search or replace. Clean up by displaying the main
* shortcut list, updating the screen if the mark was on before, and
* decompiling the compiled regular expression we used in the last
* search, if any. */
void search_replace_abort(void)
{
#ifndef NANO_TINY
if (openfile->mark)
refresh_needed = TRUE;
#endif
regexp_cleanup();
}
/* Prepare the prompt and ask the user what to search for. Keep looping
@@ -135,7 +115,7 @@ void search_init(bool replacing, bool keep_the_answer)
* nothing was searched for yet during this session, get out. */
if (i == -1 || (i == -2 && *last_search == '\0')) {
statusbar(_("Cancelled"));
search_replace_abort();
tidy_up_after_search();
free(thedefault);
return;
}
@@ -150,21 +130,18 @@ void search_init(bool replacing, bool keep_the_answer)
#endif
}
free(thedefault);
/* If doing a regular-expression search, compile the
* search string, and get out when it's invalid. */
if (ISSET(USE_REGEXP) && !regexp_init(last_search)) {
search_replace_abort();
return;
/* When not doing a regular-expression search, just search;
* otherwise compile the search string, and only search when
* the expression is valid. */
if (!ISSET(USE_REGEXP) || regexp_init(last_search)) {
if (replacing)
ask_for_replacement();
else
go_looking();
}
if (replacing)
ask_for_replacement();
else
go_looking();
search_replace_abort();
tidy_up_after_search();
free(thedefault);
return;
}
@@ -184,7 +161,7 @@ void search_init(bool replacing, bool keep_the_answer)
if (func == flip_goto)
do_gotolinecolumn(openfile->current->lineno,
openfile->placewewant + 1, TRUE, TRUE);
search_replace_abort();
tidy_up_after_search();
free(thedefault);
return;
}
@@ -228,7 +205,7 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
lastkbcheck = time(NULL);
/* Consume all waiting keystrokes until a Cancel. */
while (input) {
while (input != ERR) {
if (func_from_key(&input) == do_cancel) {
statusbar(_("Cancelled"));
enable_waiting();
@@ -363,22 +340,6 @@ void do_search_backward(void)
do_search();
}
#ifndef NANO_TINY
/* Search in the backward direction for the next occurrence. */
void do_findprevious(void)
{
SET(BACKWARDS_SEARCH);
do_research();
}
/* Search in the forward direction for the next occurrence. */
void do_findnext(void)
{
UNSET(BACKWARDS_SEARCH);
do_research();
}
#endif /* !NANO_TINY */
/* Search for the last string without prompting. */
void do_research(void)
{
@@ -402,7 +363,34 @@ void do_research(void)
go_looking();
search_replace_abort();
tidy_up_after_search();
}
#ifndef NANO_TINY
/* Search in the backward direction for the next occurrence. */
void do_findprevious(void)
{
SET(BACKWARDS_SEARCH);
do_research();
}
/* Search in the forward direction for the next occurrence. */
void do_findnext(void)
{
UNSET(BACKWARDS_SEARCH);
do_research();
}
#endif /* !NANO_TINY */
/* Report on the status bar that the given string was not found. */
void not_found_msg(const char *str)
{
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE);
size_t numchars = actual_x(disp, strnlenpt(disp, COLS / 2));
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
(disp[numchars] == '\0') ? "" : "...");
free(disp);
}
/* Search for the global string 'last_search'. Inform the user when
@@ -702,8 +690,10 @@ void do_replace(void)
{
if (ISSET(VIEW_MODE))
print_view_warning();
else
else {
UNSET(BACKWARDS_SEARCH);
search_init(TRUE, FALSE);
}
}
/* Ask the user what the already given search string should be replaced with. */
@@ -782,6 +772,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
}
if (func_from_key(&i) == flip_goto) {
UNSET(BACKWARDS_SEARCH);
/* Retain what the user typed so far and switch to searching. */
search_init(FALSE, TRUE);
return;
@@ -840,11 +831,11 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
filestruct *line = openfile->current;
filestruct *currentline = openfile->current;
size_t leftedge = leftedge_for(xplustabs(), openfile->current);
rows_from_tail = (editwinrows / 2) -
go_forward_chunks(editwinrows / 2, &line, &leftedge);
rows_from_tail = (editwinrows / 2) - go_forward_chunks(
editwinrows / 2, &currentline, &leftedge);
} else
#endif
rows_from_tail = openfile->filebot->lineno -

View File

@@ -209,7 +209,7 @@ void do_cutword(bool backward)
if (backward)
do_prev_word(ISSET(WORD_BOUNDS), FALSE);
else
do_next_word(ISSET(WORD_BOUNDS), FALSE);
do_next_word(FALSE, ISSET(WORD_BOUNDS), FALSE);
/* Set the mark at the start of that word. */
openfile->mark = openfile->current;
@@ -320,11 +320,11 @@ void do_indent(void)
add_undo(INDENT);
/* Go through each of the lines, but skip empty ones. */
/* Go through each of the lines, adding an indent to the non-empty ones,
* and recording whatever was added in the undo item. */
for (line = top; line != bot->next; line = line->next) {
char *real_indent = (line->data[0] == '\0') ? "" : indentation;
/* Indent a line, add undo data, and save the original indent. */
indent_a_line(line, real_indent);
update_multiline_undo(line->lineno, real_indent);
}
@@ -412,14 +412,14 @@ void do_unindent(void)
add_undo(UNINDENT);
/* Go through each of the lines and remove their leading indent. */
/* Go through each of the lines, removing their leading indent where
* possible, and saving the removed whitespace in the undo item. */
for (line = top; line != bot->next; line = line->next) {
size_t indent_len = length_of_white(line->data);
char *indentation = mallocstrncpy(NULL, line->data, indent_len + 1);
indentation[indent_len] = '\0';
/* Unindent a line, add undo data, and save the original indent. */
unindent_a_line(line, indent_len);
update_multiline_undo(line->lineno, indentation);
@@ -435,27 +435,25 @@ void do_unindent(void)
void handle_indent_action(undo *u, bool undoing, bool add_indent)
{
undo_group *group = u->grouping;
filestruct *line = fsfromline(group->top_line);
if (group->next != NULL)
statusline(ALERT, "Multiple groups -- please report a bug");
/* When redoing, reposition the cursor and let the indenter adjust it. */
if (!undoing)
goto_line_posx(u->lineno, u->begin);
while (group) {
filestruct *line = fsfromline(group->top_line);
/* For each line in the group, add or remove the individual indent. */
while (line && line->lineno <= group->bottom_line) {
char *blanks = group->indentations[line->lineno - group->top_line];
/* For each line in the group, add or remove the individual indent. */
while (line && line->lineno <= group->bottom_line) {
char *blanks = group->indentations[line->lineno - group->top_line];
if (undoing ^ add_indent)
indent_a_line(line, blanks);
else
unindent_a_line(line, strlen(blanks));
if (undoing ^ add_indent)
indent_a_line(line, blanks);
else
unindent_a_line(line, strlen(blanks));
line = line->next;
}
group = group->next;
line = line->next;
}
/* When undoing, reposition the cursor to the recorded location. */
@@ -476,66 +474,6 @@ bool white_string(const char *s)
}
#ifdef ENABLE_COMMENT
/* Comment or uncomment the current line or the marked lines. */
void do_comment(void)
{
const char *comment_seq = GENERAL_COMMENT_CHARACTER;
undo_type action = UNCOMMENT;
filestruct *top, *bot, *line;
bool empty, all_empty = TRUE;
#ifdef ENABLE_COLOR
if (openfile->syntax)
comment_seq = openfile->syntax->comment;
if (*comment_seq == '\0') {
statusbar(_("Commenting is not supported for this file type"));
return;
}
#endif
/* Determine which lines to work on. */
get_range((const filestruct **)&top, (const filestruct **)&bot);
/* If only the magic line is selected, don't do anything. */
if (top == bot && bot == openfile->filebot && !ISSET(NO_NEWLINES)) {
statusbar(_("Cannot comment past end of file"));
return;
}
/* Figure out whether to comment or uncomment the selected line or lines. */
for (line = top; line != bot->next; line = line->next) {
empty = white_string(line->data);
/* If this line is not blank and not commented, we comment all. */
if (!empty && !comment_line(PREFLIGHT, line, comment_seq)) {
action = COMMENT;
break;
}
all_empty = all_empty && empty;
}
/* If all selected lines are blank, we comment them. */
action = all_empty ? COMMENT : action;
add_undo(action);
/* Store the comment sequence used for the operation, because it could
* change when the file name changes; we need to know what it was. */
openfile->current_undo->strdata = mallocstrcpy(NULL, comment_seq);
/* Process the selected line or lines. */
for (line = top; line != bot->next; line = line->next) {
/* Comment/uncomment a line, and add undo data when line changed. */
if (comment_line(action, line, comment_seq))
update_multiline_undo(line->lineno, "");
}
set_modified();
refresh_needed = TRUE;
shift_held = TRUE;
}
/* Test whether the given line can be uncommented, or add or remove a comment,
* depending on action. Return TRUE if the line is uncommentable, or when
* anything was added or removed; FALSE otherwise. */
@@ -598,6 +536,66 @@ bool comment_line(undo_type action, filestruct *line, const char *comment_seq)
return FALSE;
}
/* Comment or uncomment the current line or the marked lines. */
void do_comment(void)
{
const char *comment_seq = GENERAL_COMMENT_CHARACTER;
undo_type action = UNCOMMENT;
filestruct *top, *bot, *line;
bool empty, all_empty = TRUE;
#ifdef ENABLE_COLOR
if (openfile->syntax)
comment_seq = openfile->syntax->comment;
if (*comment_seq == '\0') {
statusbar(_("Commenting is not supported for this file type"));
return;
}
#endif
/* Determine which lines to work on. */
get_range((const filestruct **)&top, (const filestruct **)&bot);
/* If only the magic line is selected, don't do anything. */
if (top == bot && bot == openfile->filebot && !ISSET(NO_NEWLINES)) {
statusbar(_("Cannot comment past end of file"));
return;
}
/* Figure out whether to comment or uncomment the selected line or lines. */
for (line = top; line != bot->next; line = line->next) {
empty = white_string(line->data);
/* If this line is not blank and not commented, we comment all. */
if (!empty && !comment_line(PREFLIGHT, line, comment_seq)) {
action = COMMENT;
break;
}
all_empty = all_empty && empty;
}
/* If all selected lines are blank, we comment them. */
action = all_empty ? COMMENT : action;
add_undo(action);
/* Store the comment sequence used for the operation, because it could
* change when the file name changes; we need to know what it was. */
openfile->current_undo->strdata = mallocstrcpy(NULL, comment_seq);
/* Comment/uncomment each of the selected lines when possible, and
* store undo data when a line changed. */
for (line = top; line != bot->next; line = line->next) {
if (comment_line(action, line, comment_seq))
update_multiline_undo(line->lineno, "");
}
set_modified();
refresh_needed = TRUE;
shift_held = TRUE;
}
/* Perform an undo or redo for a comment or uncomment action. */
void handle_comment_action(undo *u, bool undoing, bool add_comment)
{
@@ -1085,81 +1083,80 @@ RETSIGTYPE cancel_command(int signal)
bool execute_command(const char *command)
{
int fd[2];
FILE *f;
FILE *stream;
const char *shellenv;
struct sigaction oldaction, newaction;
/* Original and temporary handlers for SIGINT. */
bool sig_failed = FALSE;
/* Did sigaction() fail without changing the signal handlers? */
bool setup_failed = FALSE;
/* Whether setting up the temporary SIGINT handler failed. */
/* Make our pipes. */
/* Create a pipe to read the command's output from. */
if (pipe(fd) == -1) {
statusbar(_("Could not create pipe"));
return FALSE;
}
/* Check $SHELL for the shell to use. If it isn't set, use /bin/sh.
* Note that $SHELL should contain only a path, with no arguments. */
/* Check which shell to use. If none is specified, use /bin/sh. */
shellenv = getenv("SHELL");
if (shellenv == NULL)
shellenv = (char *) "/bin/sh";
/* Fork a child. */
/* Fork a child process to run the command in. */
if ((pid = fork()) == 0) {
/* Child: close the unused read end of the pipe. */
close(fd[0]);
/* Connect the write end of the pipe to the process' output streams. */
dup2(fd[1], fileno(stdout));
dup2(fd[1], fileno(stderr));
/* If execl() returns at all, there was an error. */
/* Run the given command inside the preferred shell. */
execl(shellenv, tail(shellenv), "-c", command, NULL);
exit(0);
/* If the exec call returns, there was an error. */
exit(1);
}
/* Continue as parent. */
/* Parent: close the unused write end of the pipe. */
close(fd[1]);
if (pid == -1) {
close(fd[0]);
statusbar(_("Could not fork"));
close(fd[0]);
return FALSE;
}
/* Before we start reading the forked command's output, we set
* things up so that Ctrl-C will cancel the new process. */
/* Enable interpretation of the special control keys so that we get
/* Re-enable interpretation of the special control keys so that we get
* SIGINT when Ctrl-C is pressed. */
enable_signals();
/* Set things up so that Ctrl-C will terminate the forked process. */
if (sigaction(SIGINT, NULL, &newaction) == -1) {
sig_failed = TRUE;
setup_failed = TRUE;
nperror("sigaction");
} else {
newaction.sa_handler = cancel_command;
if (sigaction(SIGINT, &newaction, &oldaction) == -1) {
sig_failed = TRUE;
setup_failed = TRUE;
nperror("sigaction");
}
}
/* Note that now oldaction is the previous SIGINT signal handler,
* to be restored later. */
f = fdopen(fd[0], "rb");
if (f == NULL)
nperror("fdopen");
read_file(f, 0, "stdin", TRUE, FALSE);
stream = fdopen(fd[0], "rb");
if (stream == NULL)
statusline(ALERT, _("Failed to open pipe: %s"), strerror(errno));
else
read_file(stream, 0, "pipe", TRUE);
if (wait(NULL) == -1)
nperror("wait");
if (!sig_failed && sigaction(SIGINT, &oldaction, NULL) == -1)
/* If it was changed, restore the handler for SIGINT. */
if (!setup_failed && sigaction(SIGINT, &oldaction, NULL) == -1)
nperror("sigaction");
/* Restore the terminal to its previous state. In the process,
* disable interpretation of the special control keys so that we can
* use Ctrl-C for other things. */
/* Restore the terminal to its desired state, and disable
* interpretation of the special control keys again. */
terminal_init();
return TRUE;
@@ -1184,6 +1181,7 @@ void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep)
free(group);
group = next;
}
free(dropit);
dropit = thefile->undotop;
}
@@ -1334,8 +1332,8 @@ void add_undo(undo_type action)
}
/* Update a multiline undo item. This should be called once for each line
* affected by a multiple-line-altering feature. The existing indentation
* is saved separately for each line in the undo item. */
* affected by a multiple-line-altering feature. The indentation that is
* added or removed is saved separately for each line in the undo item. */
void update_multiline_undo(ssize_t lineno, char *indentation)
{
undo *u = openfile->current_undo;
@@ -1505,7 +1503,7 @@ bool do_wrap(filestruct *line)
/* The length of the remainder. */
size_t old_x = openfile->current_x;
filestruct * old_line = openfile->current;
filestruct *old_line = openfile->current;
/* There are three steps. First, we decide where to wrap. Then, we
* create the new wrap line. Finally, we clean up. */
@@ -2505,10 +2503,28 @@ void do_full_justify(void)
}
#endif /* ENABLE_JUSTIFY */
#if defined(ENABLE_SPELLER) || defined (ENABLE_COLOR)
/* Set up an argument list for executing the given command. */
void construct_argument_list(char ***arguments, char *command, char *filename)
{
char *copy_of_command = mallocstrcpy(NULL, command);
char *element = strtok(copy_of_command, " ");
int count = 2;
while (element != NULL) {
*arguments = (char **)nrealloc(*arguments, ++count * sizeof(char *));
(*arguments)[count - 3] = element;
element = strtok(NULL, " ");
}
(*arguments)[count - 2] = filename;
(*arguments)[count - 1] = NULL;
}
#endif
#ifdef ENABLE_SPELLER
/* A word is misspelled in the file. Let the user replace it. We
* return FALSE if the user cancels. */
bool do_int_spell_fix(const char *word)
/* Let the user edit the misspelled word. Return FALSE if the user cancels. */
bool fix_spello(const char *word)
{
char *save_search;
size_t firstcolumn_save = openfile->firstcolumn;
@@ -2520,8 +2536,6 @@ bool do_int_spell_fix(const char *word)
/* The return value of this function. */
bool result;
/* The return value of searching for a misspelled word. */
unsigned stash[sizeof(flags) / sizeof(flags[0])];
/* A storage place for the current flag settings. */
#ifndef NANO_TINY
bool right_side_up = FALSE;
/* TRUE if (mark_begin, mark_begin_x) is the top of the mark,
@@ -2530,14 +2544,6 @@ bool do_int_spell_fix(const char *word)
size_t top_x, bot_x;
#endif
/* Save the settings of the global flags. */
memcpy(stash, flags, sizeof(flags));
/* Do the spell checking case sensitive, forward, and without regexes. */
SET(CASE_SENSITIVE);
UNSET(BACKWARDS_SEARCH);
UNSET(USE_REGEXP);
/* Save the current search string, then set it to the misspelled word. */
save_search = last_search;
last_search = mallocstrcpy(NULL, word);
@@ -2629,9 +2635,6 @@ bool do_int_spell_fix(const char *word)
openfile->edittop = edittop_save;
openfile->firstcolumn = firstcolumn_save;
/* Restore the settings of the global flags. */
memcpy(flags, stash, sizeof(flags));
return proceed;
}
@@ -2759,14 +2762,19 @@ const char *do_int_speller(const char *tempfile_name)
*read_buff_ptr = '\0';
close(uniq_fd[0]);
/* Process the spelling errors. */
/* Do any replacements case sensitive, forward, and without regexes. */
SET(CASE_SENSITIVE);
UNSET(BACKWARDS_SEARCH);
UNSET(USE_REGEXP);
read_buff_word = read_buff_ptr = read_buff;
/* Process each of the misspelled words. */
while (*read_buff_ptr != '\0') {
if ((*read_buff_ptr == '\r') || (*read_buff_ptr == '\n')) {
*read_buff_ptr = '\0';
if (read_buff_word != read_buff_ptr) {
if (!do_int_spell_fix(read_buff_word)) {
if (!fix_spello(read_buff_word)) {
read_buff_word = read_buff_ptr;
break;
}
@@ -2778,10 +2786,10 @@ const char *do_int_speller(const char *tempfile_name)
/* Special case: the last word doesn't end with '\r' or '\n'. */
if (read_buff_word != read_buff_ptr)
do_int_spell_fix(read_buff_word);
fix_spello(read_buff_word);
free(read_buff);
search_replace_abort();
tidy_up_after_search();
refresh_needed = TRUE;
/* Process the end of the three processes. */
@@ -2825,8 +2833,6 @@ const char *do_alt_speller(char *tempfile_name)
struct stat spellfileinfo;
time_t timestamp;
pid_t pid_spell;
char *ptr;
static int arglen = 3;
static char **spellargs = NULL;
/* Get the timestamp and the size of the temporary file. */
@@ -2840,20 +2846,7 @@ const char *do_alt_speller(char *tempfile_name)
/* Exit from curses mode. */
endwin();
/* Set up the argument list to pass to execvp(). */
if (spellargs == NULL) {
spellargs = (char **)nmalloc(arglen * sizeof(char *));
spellargs[0] = strtok(alt_speller, " ");
while ((ptr = strtok(NULL, " ")) != NULL) {
arglen++;
spellargs = (char **)nrealloc(spellargs, arglen *
sizeof(char *));
spellargs[arglen - 3] = ptr;
}
spellargs[arglen - 1] = NULL;
}
spellargs[arglen - 2] = tempfile_name;
construct_argument_list(&spellargs, alt_speller, tempfile_name);
/* Fork a child process and run the alternate spell program in it. */
if ((pid_spell = fork()) == 0) {
@@ -2943,6 +2936,8 @@ void do_spell(void)
bool status;
FILE *temp_file;
char *temp;
unsigned stash[sizeof(flags) / sizeof(flags[0])];
/* A storage place for the current flag settings. */
const char *spell_msg;
if (ISSET(RESTRICTED)) {
@@ -2957,6 +2952,12 @@ void do_spell(void)
return;
}
/* Save the settings of the global flags. */
memcpy(stash, flags, sizeof(flags));
/* Don't add an extra newline when writing out the (selected) text. */
SET(NO_NEWLINES);
#ifndef NANO_TINY
if (openfile->mark)
status = write_marked_file(temp, temp_file, TRUE, OVERWRITE);
@@ -2978,6 +2979,9 @@ void do_spell(void)
unlink(temp);
free(temp);
/* Restore the settings of the global flags. */
memcpy(flags, stash, sizeof(flags));
/* If the spell-checker printed any error messages onscreen, make
* sure that they're cleared off. */
total_refresh();
@@ -2999,12 +3003,11 @@ void do_spell(void)
* termination, and the error string otherwise. */
void do_linter(void)
{
char *read_buff, *read_buff_ptr, *read_buff_word, *ptr, *lintcopy;
char *read_buff, *read_buff_ptr, *read_buff_word;
size_t pipe_buff_size, read_buff_size, read_buff_read, bytesread;
size_t parsesuccess = 0;
int lint_status, lint_fd[2];
pid_t pid_lint;
static int arglen = 3;
static char **lintargs = NULL;
lintstruct *lints = NULL, *tmplint = NULL, *curlint = NULL;
@@ -3033,7 +3036,6 @@ void do_linter(void)
return;
}
lintcopy = mallocstrcpy(NULL, openfile->syntax->linter);
/* Create a pipe up front. */
if (pipe(lint_fd) == -1) {
statusbar(_("Could not create pipe"));
@@ -3043,19 +3045,7 @@ void do_linter(void)
blank_bottombars();
statusbar(_("Invoking linter, please wait"));
/* Set up an argument list to pass to execvp(). */
if (lintargs == NULL) {
lintargs = (char **)nmalloc(arglen * sizeof(char *));
lintargs[0] = strtok(lintcopy, " ");
while ((ptr = strtok(NULL, " ")) != NULL) {
arglen++;
lintargs = (char **)nrealloc(lintargs, arglen * sizeof(char *));
lintargs[arglen - 3] = ptr;
}
lintargs[arglen - 1] = NULL;
}
lintargs[arglen - 2] = openfile->filename;
construct_argument_list(&lintargs, openfile->syntax->linter, openfile->filename);
/* Start a new process to run the linter in. */
if ((pid_lint = fork()) == 0) {
@@ -3197,75 +3187,77 @@ void do_linter(void)
while (TRUE) {
int kbinput;
functionptrtype func;
struct stat lintfileinfo;
if (stat(curlint->filename, &lintfileinfo) != -1 &&
openfile->current_stat->st_ino != lintfileinfo.st_ino) {
openfilestruct *tmpof = openfile;
#ifdef ENABLE_MULTIBUFFER
while (tmpof != openfile->next) {
if (tmpof->current_stat->st_ino == lintfileinfo.st_ino)
break;
tmpof = tmpof->next;
}
#endif
if (tmpof->current_stat->st_ino != lintfileinfo.st_ino) {
#ifdef ENABLE_MULTIBUFFER
char *msg = charalloc(1024 + strlen(curlint->filename));
int i;
sprintf(msg, _("This message is for unopened file %s,"
" open it in a new buffer?"), curlint->filename);
i = do_yesno_prompt(FALSE, msg);
free(msg);
if (i == -1) {
statusbar(_("Cancelled"));
goto free_lints_and_return;
} else if (i == 1) {
open_buffer(curlint->filename, TRUE);
} else {
#endif
char *dontwantfile = mallocstrcpy(NULL, curlint->filename);
lintstruct *restlint = NULL;
while (curlint != NULL) {
if (strcmp(curlint->filename, dontwantfile) == 0) {
if (curlint == lints)
lints = curlint->next;
else
curlint->prev->next = curlint->next;
if (curlint->next != NULL)
curlint->next->prev = curlint->prev;
tmplint = curlint;
curlint = curlint->next;
free(tmplint->msg);
free(tmplint->filename);
free(tmplint);
} else {
if (restlint == NULL)
restlint = curlint;
curlint = curlint->next;
}
}
if (restlint == NULL) {
statusbar(_("No more errors in unopened files, cancelling"));
napms(2400);
break;
} else {
curlint = restlint;
continue;
}
free(dontwantfile);
}
#ifdef ENABLE_MULTIBUFFER
} else
openfile = tmpof;
#endif
}
if (tmplint != curlint) {
#ifndef NANO_TINY
struct stat lintfileinfo;
new_lint_loop:
if (stat(curlint->filename, &lintfileinfo) != -1) {
if (openfile->current_stat->st_ino != lintfileinfo.st_ino) {
openfilestruct *tmpof = openfile;
while (tmpof != openfile->next) {
if (tmpof->current_stat->st_ino == lintfileinfo.st_ino)
break;
tmpof = tmpof->next;
}
if (tmpof->current_stat->st_ino != lintfileinfo.st_ino) {
char *msg = charalloc(1024 + strlen(curlint->filename));
int i;
sprintf(msg, _("This message is for unopened file %s,"
" open it in a new buffer?"),
curlint->filename);
i = do_yesno_prompt(FALSE, msg);
free(msg);
if (i == -1) {
statusbar(_("Cancelled"));
goto free_lints_and_return;
} else if (i == 1) {
SET(MULTIBUFFER);
open_buffer(curlint->filename, FALSE);
} else {
char *dontwantfile = mallocstrcpy(NULL, curlint->filename);
lintstruct *restlint = NULL;
while (curlint != NULL) {
if (strcmp(curlint->filename, dontwantfile) == 0) {
if (curlint == lints)
lints = curlint->next;
else
curlint->prev->next = curlint->next;
if (curlint->next != NULL)
curlint->next->prev = curlint->prev;
tmplint = curlint;
curlint = curlint->next;
free(tmplint->msg);
free(tmplint->filename);
free(tmplint);
} else {
if (restlint == NULL)
restlint = curlint;
curlint = curlint->next;
}
}
if (restlint == NULL) {
statusbar(_("No more errors in unopened files, cancelling"));
napms(2400);
break;
} else {
curlint = restlint;
goto new_lint_loop;
}
free(dontwantfile);
}
} else
openfile = tmpof;
}
}
#endif /* !NANO_TINY */
goto_line_posx(curlint->lineno, curlint->colno - 1);
titlebar(NULL);
adjust_viewport(CENTERING);
@@ -3307,7 +3299,7 @@ void do_linter(void)
wipe_statusbar();
#ifndef NANO_TINY
#ifdef ENABLE_MULTIBUFFER
free_lints_and_return:
#endif
for (curlint = lints; curlint != NULL;) {
@@ -3333,9 +3325,8 @@ void do_formatter(void)
size_t pww_save = openfile->placewewant;
bool was_at_eol = (openfile->current->data[openfile->current_x] == '\0');
pid_t pid_format;
static int arglen = 3;
static char **formatargs = NULL;
char *temp, *ptr, *finalstatus = NULL;
char *temp, *finalstatus = NULL;
if (openfile->totsize == 0) {
statusbar(_("Finished"));
@@ -3364,19 +3355,7 @@ void do_formatter(void)
blank_bottombars();
statusbar(_("Invoking formatter, please wait"));
/* Set up an argument list to pass to execvp(). */
if (formatargs == NULL) {
formatargs = (char **)nmalloc(arglen * sizeof(char *));
formatargs[0] = strtok(openfile->syntax->formatter, " ");
while ((ptr = strtok(NULL, " ")) != NULL) {
arglen++;
formatargs = (char **)nrealloc(formatargs, arglen * sizeof(char *));
formatargs[arglen - 3] = ptr;
}
formatargs[arglen - 1] = NULL;
}
formatargs[arglen - 2] = temp;
construct_argument_list(&formatargs, openfile->syntax->formatter, temp);
/* Start a new process for the formatter. */
if ((pid_format = fork()) == 0) {
@@ -3480,7 +3459,7 @@ void do_wordlinechar_count(void)
* count whenever we're on a word just before moving. */
while (openfile->current != openfile->filebot ||
openfile->current->data[openfile->current_x] != '\0') {
if (do_next_word(TRUE, FALSE))
if (do_next_word(FALSE, TRUE, FALSE))
words++;
}
@@ -3577,8 +3556,8 @@ char *copy_completion(char *check_line, int start)
void complete_a_word(void)
{
char *shard, *completion = NULL;
int start_of_shard, shard_length = 0;
int i = 0, j = 0;
size_t start_of_shard, shard_length = 0;
size_t i = 0, j = 0;
completion_word *some_word;
#ifdef ENABLE_WRAPPING
bool was_set_wrapping = !ISSET(NO_WRAP);
@@ -3637,7 +3616,7 @@ void complete_a_word(void)
/* The point where we can stop searching for shard. */
/* Traverse the whole line, looking for shard. */
for (i = pletion_x; i < threshold; i++) {
for (i = pletion_x; (int)i < threshold; i++) {
/* If the first byte doesn't match, run on. */
if (pletion_line->data[i] != shard[0])
continue;

View File

@@ -325,15 +325,18 @@ const char *strstrwrapper(const char *haystack, const char *needle,
else
return haystack + regmatches[0].rm_so;
}
if (ISSET(CASE_SENSITIVE)) {
if (ISSET(BACKWARDS_SEARCH))
return revstrstr(haystack, needle, start);
else
return strstr(start, needle);
} else if (ISSET(BACKWARDS_SEARCH))
return mbrevstrcasestr(haystack, needle, start);
}
return mbstrcasestr(start, needle);
if (ISSET(BACKWARDS_SEARCH))
return mbrevstrcasestr(haystack, needle, start);
else
return mbstrcasestr(start, needle);
}
/* This is a wrapper for the perror() function. The wrapper temporarily
@@ -456,7 +459,7 @@ size_t strnlenpt(const char *text, size_t maxlen)
return 0;
while (*text != '\0') {
int charlen = parse_mbchar(text, NULL, &width);
size_t charlen = parse_mbchar(text, NULL, &width);
if (maxlen <= charlen)
break;

View File

@@ -363,7 +363,7 @@ int parse_kbinput(WINDOW *win)
kbinput = get_input(win, 1);
if (kbinput == NULL && !waiting_mode)
return 0;
return ERR;
while (kbinput == NULL)
kbinput = get_input(win, 1);
@@ -1944,7 +1944,7 @@ char *display_string(const char *buf, size_t column, size_t span, bool isdata)
continue;
}
/* Represent an invalid sequence with the Replacement Character. */
/* Represent an invalid starter byte with the Replacement Character. */
converted[index++] = '\xEF';
converted[index++] = '\xBF';
converted[index++] = '\xBD';
@@ -1973,6 +1973,7 @@ char *display_string(const char *buf, size_t column, size_t span, bool isdata)
return converted;
}
#ifdef ENABLE_MULTIBUFFER
/* Determine the sequence number of the given buffer in the circular list. */
int buffer_number(openfilestruct *buffer)
{
@@ -1985,6 +1986,7 @@ int buffer_number(openfilestruct *buffer)
return count;
}
#endif
/* If path is NULL, we're in normal editing mode, so display the current
* version of nano, the current filename, and whether the current file
@@ -2030,6 +2032,7 @@ void titlebar(const char *path)
else
#endif
if (!inhelp) {
#ifdef ENABLE_MULTIBUFFER
/* If there are/were multiple buffers, show which out of how many. */
if (more_than_one) {
indicator = charalloc(24);
@@ -2037,6 +2040,7 @@ void titlebar(const char *path)
buffer_number(firstfile->prev));
upperleft = indicator;
} else
#endif
upperleft = BRANDING;
if (openfile->filename[0] == '\0')
@@ -2155,6 +2159,7 @@ void statusline(message_type importance, const char *msg, ...)
/* Curses mode is turned off. If we use wmove() now, it will muck
* up the terminal settings. So we just use vfprintf(). */
if (isendwin()) {
fprintf(stderr, "\n");
vfprintf(stderr, msg, ap);
va_end(ap);
return;
@@ -2912,57 +2917,42 @@ bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge)
return (openfile->current->lineno - was_lineno < editwinrows);
}
/* Scroll the edit window in the given direction and the given number of rows,
* and draw new lines on the blank lines left after the scrolling. */
void edit_scroll(bool direction, int nrows)
/* Scroll the edit window one row in the given direction, and
* draw the relevant content on the resultant blank row. */
void edit_scroll(bool direction)
{
filestruct *line;
size_t leftedge;
int remainder = 0, nrows = 1;
/* Part 1: nrows is the number of rows we're going to scroll the text of
* the edit window. */
/* Move the top line of the edit window the requested number of rows up or
* down, and reduce the number of rows with the amount we couldn't move. */
/* Move the top line of the edit window one row up or down. */
if (direction == BACKWARD)
nrows -= go_back_chunks(nrows, &openfile->edittop, &openfile->firstcolumn);
remainder = go_back_chunks(1, &openfile->edittop, &openfile->firstcolumn);
else
nrows -= go_forward_chunks(nrows, &openfile->edittop, &openfile->firstcolumn);
remainder = go_forward_chunks(1, &openfile->edittop, &openfile->firstcolumn);
/* Don't bother scrolling zero rows, nor more than the window can hold. */
if (nrows == 0) {
if (remainder > 0) {
#ifndef NANO_TINY
statusline(ALERT, "Underscrolling -- please report a bug");
statusline(ALERT, "Could not scroll -- please report a bug");
#endif
return;
}
if (nrows >= editwinrows) {
#ifndef NANO_TINY
if (editwinrows > 1)
statusline(ALERT, "Overscrolling -- please report a bug");
#endif
refresh_needed = TRUE;
return;
}
/* Scroll the text of the edit window a number of rows up or down. */
/* Actually scroll the text of the edit window one row up or down. */
scrollok(edit, TRUE);
wscrl(edit, (direction == BACKWARD) ? -nrows : nrows);
wscrl(edit, (direction == BACKWARD) ? -1 : 1);
scrollok(edit, FALSE);
/* Part 2: nrows is now the number of rows in the scrolled region of the
* edit window that we need to draw. */
/* If we're not on the first "page" (when not softwrapping), or the mark
* is on, the row next to the scrolled region needs to be redrawn too. */
if (line_needs_update(openfile->placewewant, 0) && nrows < editwinrows)
nrows++;
/* If we scrolled backward, start on the first line of the blank region. */
/* If we scrolled backward, the top row needs to be redrawn. */
line = openfile->edittop;
leftedge = openfile->firstcolumn;
/* If we scrolled forward, move down to the start of the blank region. */
/* If we scrolled forward, the bottom row needs to be redrawn. */
if (direction == FORWARD)
go_forward_chunks(editwinrows - nrows, &line, &leftedge);
@@ -2977,8 +2967,8 @@ void edit_scroll(bool direction, int nrows)
}
#endif
/* Draw new content on the blank rows inside the scrolled region
* (and on the bordering row too when it was deemed necessary). */
/* Draw new content on the blank row (and on the bordering row too
* when it was deemed necessary). */
while (nrows > 0 && line != NULL) {
nrows -= update_line(line, (line == openfile->current) ?
openfile->current_x : 0);

View File

@@ -7,8 +7,8 @@ comment "#"
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|i?color|extendsyntax).*$"
# Keywords
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cutfromcursor|fill[[:space:]]+-?[[:digit:]]+|historylog|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize[[:space:]]+[1-9][0-9]*|tabstospaces|tempfile|trimblanks|unix|view|wordbounds)\>"
icolor yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cutfromcursor|fill[[:space:]]+-?[[:digit:]]+|historylog|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize[[:space:]]+[1-9][0-9]*|tabstospaces|tempfile|trimblanks|unix|view|wordbounds)\>"
icolor yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|titlecolor|whitespace|wordchars)[[:space:]]+"
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+([[:alpha:]]+|".*")[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
icolor brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
@@ -20,7 +20,7 @@ icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|
color brightmagenta "".+"([[:space:]]|$)"
# Colors
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
icolor magenta "^[[:space:]]*i?color\>" "\<(start|end)="
# Comments

View File

@@ -20,9 +20,9 @@ color red " fuzzy(,|$)"
color yellow " (no-)?[-[:alpha:]]+-format(,|$)"
# Format specifiers.
color brightmagenta "%([1-9]\$)?[a-z]*"
# Quotes and newlines.
# Quotes and escaped characters.
color yellow "\""
color cyan "\\n"
color cyan "\\[abcefnrtv"\]"
# Reminders.
color brightwhite,yellow "(FIXME|TODO|XXX)"
# Obsolete strings.

View File

@@ -6,13 +6,21 @@ magic "(POSIX|Bourne-Again) shell script.*text"
linter dash -n
comment "#"
icolor brightgreen "^[0-9A-Z_]+\(\)"
# Function declarations.
color brightgreen "^[A-Za-z0-9_-]+\(\)"
# Keywords, symbols, and comparisons.
color green "\<(break|case|continue|do|done|elif|else|esac|exit|fi|for|function|if|in|read|return|select|shift|then|time|until|while)\>"
color green "\<(declare|eval|exec|export|let|local)\>"
color green "[{}():;|`$<>!=&\\]" "(\]|\[)"
color green "-[Ldefgruwx]\>"
color green "-(eq|ne|gt|lt|ge|le|s|n|z)\>"
color brightblue "\<(awk|cat|cd|ch(grp|mod|own)|cp|echo|env|grep|install|ln|make|mkdir|mv|popd|printf|pushd|rm|rmdir|sed|set|tar|touch|umask|unset)\>"
color green "-(eq|ne|gt|lt|ge|le|ef|ot|nt)\>"
# Short and long options.
color brightmagenta "[[:blank:]]-[A-Za-z]\>" "[[:blank:]]--[A-Za-z-]+\>"
# Common commands.
color brightblue "\<(awk|cat|cd|ch(grp|mod|own)|cp|cut|echo|env|grep|head|install|ln|make|mkdir|mv|popd|printf|pushd|rm|rmdir|sed|set|sort|tail|tar|touch|umask|unset)\>"
color normal "[.-]tar\>"
# Basic variable names (no braces).
color brightred "\$[-0-9@*#?$!]" "\$[[:alpha:]_][[:alnum:]_]*"