Compare commits

...

175 Commits

Author SHA1 Message Date
Benno Schulenberg
ea1afac9db po: update translations and regenerate POT file and PO files 2016-10-29 11:53:44 +02:00
Benno Schulenberg
04aab233d0 bump version numbers and add a news item for 2.7.1 2016-10-29 11:11:33 +02:00
Benno Schulenberg
33bc848c5b binding: properly conditionalize the UTF-8 parts
Reported-by: Sumedh Pendurkar <sumedh.pendurkar@gmail.com>
2016-10-29 10:19:28 +02:00
Benno Schulenberg
4c476bc872 scrolling: use a comparison that will work also in softwrap mode
This fixes https://savannah.gnu.org/bugs/?49467.
2016-10-28 11:38:58 +02:00
Benno Schulenberg
9c2e270b3e softwrap: initialize 'editwincols' early, for computing the number of wraps
When giving a line number on the command line, do_gotolinecolumn() needs
to know the width of the screen to be able to (roughly) place the target
line in the center of the screen.

This fixes https://savannah.gnu.org/bugs/?49462.
2016-10-28 10:50:06 +02:00
Benno Schulenberg
0eef5610eb files: mark a new buffer as modified after inserting command output
This fixes https://savannah.gnu.org/bugs/?49423.
2016-10-27 20:05:05 +02:00
Benno Schulenberg
2a55d2b29a tweaks: adjust some comments and reduce the scope of some variables
Also remove some cluttering conditional compilation.
2016-10-27 20:04:50 +02:00
Benno Schulenberg
5416b9c09d tweaks: remove a band-aid condition that is no longer needed
Also, don't bother conditionalizing two booleans for the tiny version.
2016-10-27 20:00:01 +02:00
Benno Schulenberg
7287300e0d tweaks: compile two parameters unconditionally 2016-10-27 12:24:41 +02:00
Benno Schulenberg
ffeb0f9d4b tweaks: don't spread a statement over multiple lines unnecessarily 2016-10-27 11:41:49 +02:00
Benno Schulenberg
10c9093942 general: add the option -g/--showcursor, to match Pico
The nanorc option already exists, but not the corresponding one
for the command line.
2016-10-27 11:34:41 +02:00
Benno Schulenberg
b38cbfe173 startup: always initialize 'margin' and 'editwincols'
This fixes https://savannah.gnu.org/bugs/?49428.
2016-10-24 17:40:06 +02:00
Benno Schulenberg
702b09c859 tweaks: elide a parameter that is always FALSE 2016-10-23 20:07:39 +02:00
Benno Schulenberg
2cd8ca4eb1 tweaks: stop compiling the whole_word_only parameter conditionally
This make tiny nano slightly less tiny, but makes the code more readable.
2016-10-23 20:07:30 +02:00
Benno Schulenberg
55b1403542 tweaks: adjust some whitespace and a comment 2016-10-23 17:26:19 +02:00
Benno Schulenberg
9d5ee16614 tweaks: don't bother redrawing some lines when whole screen will be redrawn 2016-10-23 17:26:19 +02:00
Benno Schulenberg
01bbf7e82f tweaks: rename a function to better describe what it does
It does not update anything -- it just picks a new point from
where to start displaying the buffer.  All actual updating of
the screen is done by edit_refresh() and edit_redraw() and such.
2016-10-23 17:26:19 +02:00
Benno Schulenberg
3ed5ddba31 docs: remove a reference that was only valid on Debian systems 2016-10-23 17:22:30 +02:00
Benno Schulenberg
6cacd1e320 tweaks: make several small adjustments to the documentation 2016-10-23 12:29:21 +02:00
Benno Schulenberg
d9cae81a0e docs: mention the existence of the toggles in the man page 2016-10-22 17:27:15 +02:00
Benno Schulenberg
83ee1feda4 docs: add 'set linenumbers' and '--linenumbers' to the texinfo document
Also mention the corresponding toggle (M-#).
2016-10-22 17:06:50 +02:00
Benno Schulenberg
c7610ba356 docs: add 'linenumbers' and 'numbercolor' to the sample nanorc 2016-10-22 13:49:13 +02:00
Benno Schulenberg
ae648778e2 screen: refresh when a new magicline is added in line-numbering mode
This fixes https://savannah.gnu.org/bugs/?49406.
2016-10-21 15:59:16 +02:00
Benno Schulenberg
023edffe3d screen: move the margin determination to the main loop
There is no need to look at this for every painted line, because
the margin can only change when some key is struck.
2016-10-21 14:56:56 +02:00
Benno Schulenberg
2789bb0813 screen: repaint the edit window in a single place -- the main loop
Instead of doing this in two places: after interpreting shortcuts,
and after injecting characters.
2016-10-21 14:56:53 +02:00
Benno Schulenberg
4d996e4c39 screen: suppress line numbers when the terminal is very narrow
To prevent the display from getting messed up, making nano unusable.
2016-10-21 14:55:43 +02:00
Benno Schulenberg
de2aa4f24a rcfile: add an option to customize the color of line numbers 2016-10-20 16:48:45 +02:00
Faissal Bensefia
de95ca68f7 new feature: the ability to show line numbers before the text
It can be activated with --linenumbers on the command line or with
'set linenumbers' in a nanorc file, and it can be toggled with M-#.

Signed-off-by: Faissal Bensefia <faissaloo@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@justemail.net>
2016-10-20 16:47:52 +02:00
Benno Schulenberg
55878efe5d binding: supply the keycode for most special keys directly
Instead of figuring them out from the string.  This is possible
because those dedicated editing keys cannot be rebound anyway.
2016-10-18 20:38:27 +02:00
Benno Schulenberg
43f35fc7a9 softwrap: ensure the current line is fully visible when moving in it
This fixes https://savannah.gnu.org/bugs/?49099,
and fixes the unreported corresponding bugs for
<End> and <Del> and typing extra characters.
2016-10-18 15:07:47 +02:00
Benno Schulenberg
d66ea08473 moving: adjust the Y position to correspond with the changed X position
So the softwrap code in do_down() can compute the correct amount to scroll.

This fixes https://savannah.gnu.org/bugs/?49374.
2016-10-18 11:46:15 +02:00
Benno Schulenberg
8476bf86a1 tweaks: fix compilation when configured with --enable-tiny 2016-10-15 18:05:01 +02:00
Benno Schulenberg
c92982d60f binding: fix some duplicated carets and too restrictive menus 2016-10-15 17:18:51 +02:00
Benno Schulenberg
7a274d621a binding: use arrows instead of words to designate the cursor keys 2016-10-15 17:04:01 +02:00
Benno Schulenberg
fdee0df849 input: keep the Ctrl+Arrow keys working when their synonyms are unbound
This fixes https://savannah.gnu.org/bugs/?49058 reported by Rishabh Dave.
2016-10-15 17:03:10 +02:00
Benno Schulenberg
00efa50385 build: avoid updated PO files being remerged upon every make 2016-10-15 15:09:34 +02:00
Benno Schulenberg
a35803d502 build: avoid an annoying warning at configure time 2016-10-15 15:06:18 +02:00
Benno Schulenberg
7013039c3a tweaks: rename a variable, for consistency 2016-10-12 21:10:04 +02:00
Benno Schulenberg
925ad6393a tweaks: remove a superfluous setting, and add a comment 2016-10-12 21:07:16 +02:00
Benno Schulenberg
3264d0c5be tweaks: move a variable that doesn't need to be global 2016-10-12 19:59:26 +02:00
Benno Schulenberg
d9148e7b3f tweaks: elide an unneeded variable 2016-10-12 19:20:39 +02:00
Benno Schulenberg
0a18d8912b screen: defeat a VTE bug by doing an extra cursor move and update
This fixes https://savannah.gnu.org/bugs/?49106.
2016-10-12 13:56:48 +02:00
Benno Schulenberg
815b326864 syntax: show another deprecated keyword (replace2) in red 2016-10-11 20:57:57 +02:00
Rishabh Dave
01bf034bb6 rcfile: reject rebindings that have no effect or have side effects
Also, show in green only the ^ and M- combinations that are valid.

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

Signed-off-by: Rishabh Dave <rishabhddave@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@justemail.net>
2016-10-11 19:46:18 +02:00
Benno Schulenberg
d716809228 scrolling: don't put the last line at the bottom when softwrap in on
This avoids https://savannah.gnu.org/bugs/?49298.
2016-10-10 13:19:51 +02:00
Benno Schulenberg
8041627cc3 tweaks: remove a bit of duplication 2016-09-20 12:54:16 +02:00
Benno Schulenberg
598e0af7af softwrap: scroll the current line fully into view when jumping words
This fixes https://savannah.gnu.org/bugs/?47710
and fixes https://savannah.gnu.org/bugs/?49088.
2016-09-20 12:29:10 +02:00
Benno Schulenberg
8ba57cf87b input: don't return zero when some function is completely unbound
Returning a zero would mean returning a ^Space -- the keycode that
by default is bound to the Next-Word function.  So, unbinding the
keys to which the modified Arrow keys are hard bound would cause
the latter ones to mysteriously jump to the next word.

This partially fixes https://savannah.gnu.org/bugs/?49058.
2016-09-20 11:11:44 +02:00
Rishabh Dave
e2027aee15 rcfile: reject key names that are wrong or too long
Meta keys should have a dash as second character, and apart from ^Space
and M-Space key names should be at most two or three characters long.

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

Reviewed-by: Benno Schulenberg <bensberg@justemail.net>
Signed-off-by: Rishabh Dave <rishabhddave@gmail.com>
2016-09-14 19:53:38 +02:00
Benno Schulenberg
97f6ae5267 softwrap: scroll 'enough' whenever it surpasses 'amount'
This fixes https://savannah.gnu.org/bugs/?49086.
2016-09-14 12:40:58 +02:00
Benno Schulenberg
fc9c7b4917 softwrap: scroll when searching lands on an overlong bottom line
This fixes https://savannah.gnu.org/bugs/index.php?42189.
2016-09-14 11:02:36 +02:00
Benno Schulenberg
77a1a5c3e4 tweaks: reshuffle some ifdefs, for less fragmentation 2016-09-14 11:00:18 +02:00
Benno Schulenberg
bc8bb7e942 screen: keep the help items nicely lined up also in the tiny version 2016-09-13 09:29:44 +02:00
Benno Schulenberg
08cd197bf1 general: include word-jumping and block-jumping into the tiny version
And also case-sensitive searches, backward searches, and searching again.
2016-09-13 09:27:04 +02:00
Benno Schulenberg
4de0a5049b tweaks: reshuffle an if statement 2016-09-11 21:43:47 +02:00
Benno Schulenberg
dc76e84657 files: alert about an unwritable file also in the tiny version 2016-09-11 21:40:50 +02:00
Benno Schulenberg
1c2b35675e tweaks: adjust some indentation 2016-09-11 21:36:46 +02:00
Benno Schulenberg
add0d698b7 syntax: show deprecated keywords in red, and 'wordchars' in green 2016-09-11 12:22:02 +02:00
Benno Schulenberg
09e95b2d91 tweaks: frob a few comments 2016-09-11 11:26:09 +02:00
Benno Schulenberg
03fd6f3af8 tweaks: remove a useless cursor movement 2016-09-11 10:43:21 +02:00
Benno Schulenberg
b92d35d1f2 browser: add the option showcursor, to place the cursor on the highlight
This lets users of braille displays find the selected item immediately.

This fulfills a request by Enrico Mioso.
See https://lists.gnu.org/archive/html/nano-devel/2016-09/msg00025.html.
2016-09-11 09:41:52 +02:00
Benno Schulenberg
9eeb1c8fb8 docs: brush up the TODO list 2016-09-08 12:11:38 +02:00
Benno Schulenberg
ad83ed22d9 input: handle the "resize key" in a better way
And correct a comment: the key /does/ occur also in the tiny version.
2016-09-06 12:09:18 +02:00
Benno Schulenberg
3ddf6ff955 syntax: make the contents of the X-Bugs field in a PO file stand out 2016-09-06 10:58:03 +02:00
Benno Schulenberg
d04c0b7555 docs: refresh some info in the FAQ 2016-09-03 21:46:22 +02:00
Benno Schulenberg
f13707fd1d history: slate the search-history migration for removal 2016-09-03 21:04:17 +02:00
Benno Schulenberg
ed9e5d7183 docs: mark some rebindable function names as deprecated 2016-09-03 20:12:29 +02:00
Benno Schulenberg
2fd497e3ef tweaks: remove a superfluous blanking of the statusbar
The prompt from which the browser was invoked has already blanked it.
2016-09-03 15:34:44 +02:00
Benno Schulenberg
fd6308d6d3 tweaks: reshuffle a couple of items 2016-09-03 13:42:19 +02:00
Benno Schulenberg
1dbebbcadc screen: keep the help items aligned in more configurations
This fixes https://savannah.gnu.org/bugs/?48987.
2016-09-03 13:35:19 +02:00
Benno Schulenberg
57d1755d10 tweaks: preen some comments, and reshuffle a few ifdefs 2016-09-03 12:14:08 +02:00
Benno Schulenberg
bace664fbc startup: allow to rebind the RegExp toggle also in the tiny version
This fixes https://savannah.gnu.org/bugs/?48988.
2016-09-03 11:45:49 +02:00
Benno Schulenberg
acd8809d71 tweaks: use hard-baked keycodes where possible
These keycodes have non-rebindable entries in the list of shortcuts, so
they will always be there -- no need for a function call to find them.
2016-09-02 12:04:29 +02:00
Benno Schulenberg
7b7d2bf7c9 tweaks: make tiny nano a teeny bit smaller 2016-09-02 12:01:03 +02:00
Benno Schulenberg
244de605a7 po: update translations and regenerate POT file and PO files 2016-09-01 12:42:50 +02:00
Benno Schulenberg
002652d263 bump version numbers and add a news item for 2.7.0 2016-09-01 12:38:35 +02:00
Benno Schulenberg
08b770d425 files: close a lockfile after reading it 2016-08-30 11:48:35 +02:00
Benno Schulenberg
2dffcf101f tweaks: fix compilation with --disable-histories 2016-08-30 11:14:19 +02:00
Benno Schulenberg
96fbdfbc7d input: unset a softmark whenever a character is typed 2016-08-30 10:41:28 +02:00
Benno Schulenberg
272a953889 tweaks: fix compilation when configured with --with-slang 2016-08-30 10:12:02 +02:00
Benno Schulenberg
db310ac9b6 input: ignore the resize "key", to prevent reporting an unbound key
In the tiny version it would beep and report an unbound key for every
window resize.
2016-08-30 09:40:51 +02:00
Benno Schulenberg
c11c688420 tweaks: fix compilation with --enable-tiny again 2016-08-30 09:36:49 +02:00
Benno Schulenberg
514cd9a099 update the license text to the preferred version
Mentioning "GNU nano" instead of "This program" and referring to the
website instead of to a postal address.
2016-08-29 21:27:16 +02:00
Benno Schulenberg
406e5242a3 update the copyright notices 2016-08-29 21:27:05 +02:00
Benno Schulenberg
c26f58e783 AUTHORS: add Mahyar Abbaspour and Mike Scalora for their contributions 2016-08-29 21:26:57 +02:00
Benno Schulenberg
5ad26f864a tweaks: adjust indentation after previous change 2016-08-29 13:36:29 +02:00
Benno Schulenberg
e7f39bc248 tweaks: remove an unneeded check, reshuffle some things, add a comment
Resetting the cutbuffer is irrelevant when 'allow_funcs' is false or
when in view mode, so do_input() can just return in those cases.
2016-08-29 13:35:35 +02:00
Benno Schulenberg
0242d84218 tweaks: make a call in one place instead of in four different ones
And remove a superfluous call.
2016-08-28 21:27:52 +02:00
Benno Schulenberg
7275e11c4f tweaks: adjust some comments and remove needless asserts 2016-08-28 18:17:10 +02:00
Benno Schulenberg
77d140728d tweaks: don't bother trimming the prompt again
The prompt has already been trimmed in do_prompt() to fit into the
available space.
2016-08-28 17:53:44 +02:00
Benno Schulenberg
4d2ada60f5 tweaks: don't bother avoiding unneeded rewrites of the promptbar
Leave the optimization of actual screen writes to ncurses.
2016-08-28 17:37:25 +02:00
Benno Schulenberg
382c9d792d new feature: allow text selection by holding Shift with the cursor keys
Add the keycodes and routines to allow the user to forego setting the
mark explicitly (with M-A / ^6) and instead quickly select a few words
or lines by holding down Shift together with the movement keys.

(Some combinations with Shift are swallowed by some terminal emulators.
To work around some of those, the combinations Shift+Alt+Left/Right work
as Shift+Home/End and Shift+Alt+Up/Down work as Shift+PageUp/PageDown.)
2016-08-28 11:29:28 +02:00
Benno Schulenberg
aeb49a8013 bottombar: only count help items that have a shortcut bound to them
This avoids showing a ghost item in, for example, the WriteOut menu
when not using --tempfile and the user does not bind 'discardbuffer'.
2016-08-27 12:22:59 +02:00
Benno Schulenberg
c05c914eee tweaks: rename three variables 2016-08-27 12:10:18 +02:00
Benno Schulenberg
c19f0c732e tweaks: simplify the determination of the number of shown help items 2016-08-27 12:06:08 +02:00
Benno Schulenberg
6ad3700a3d prompt: mouse clicks that moved the cursor need no further processing
This fixes https://savannah.gnu.org/bugs/?48917.
2016-08-27 12:00:08 +02:00
Benno Schulenberg
4f156aa6db prompt: set up the prepared answer before allowing to change it
This fixes https://savannah.gnu.org/bugs/?48916.
2016-08-27 11:59:57 +02:00
Benno Schulenberg
6142ef87b5 prompt: use angular brackets as continuation mark, as Pico does
The $ sign looks too much like an S, and it "obscures" the answer by
being so "massive".  The < and > signs are lighter and work better.
2016-08-27 09:34:54 +02:00
Benno Schulenberg
da2fce90bd tweaks: elide a variable and rename some others 2016-08-27 09:34:42 +02:00
Benno Schulenberg
1e3cffbbd6 prompt: show a trailing $ when the tail of the answer is offscreen
This fixes https://savannah.gnu.org/bugs/?48894.
2016-08-26 21:42:23 +02:00
Benno Schulenberg
92c97c70d4 prompt: leave always at least the last character of the answer visible
This fixes https://savannah.gnu.org/bugs/?48912.
2016-08-26 21:32:07 +02:00
Benno Schulenberg
b77b1391c3 tweaks: improve some indentation and reshuffle a few lines 2016-08-26 12:24:18 +02:00
Benno Schulenberg
7e0c4e5726 tweaks: rename a function and adjust indentation 2016-08-25 20:20:50 +02:00
Benno Schulenberg
50616148b0 prompt: recompose the statusbar text whenever the window size changes
This fixes https://savannah.gnu.org/bugs/?48796.
2016-08-25 20:12:36 +02:00
Benno Schulenberg
3e40e5d4b5 docs: explain how to contribute code 2016-08-25 19:35:14 +02:00
Benno Schulenberg
2f9232a493 tweaks: adjust indentation after previous change 2016-08-25 11:45:38 +02:00
Benno Schulenberg
0d5fbfb91c tweaks: reshuffle some things, and remove a misplaced comment 2016-08-25 11:45:34 +02:00
Benno Schulenberg
56147434f3 prompt: don't crash when the terminal is less than four columns wide
This fixes https://savannah.gnu.org/bugs/?48792.
2016-08-25 11:45:13 +02:00
Benno Schulenberg
21cb01e543 tweaks: rename two variables, to make some sense
And move a statement to a better place.
2016-08-25 11:45:05 +02:00
Benno Schulenberg
ea9aaee8c7 statusbar: leave out the brackets when the message is very long
This also prevents the message from spilling into the help lines
when the terminal is less than four columns wide.  (Not that one
can read anything then, but it looks better.)
2016-08-25 11:45:01 +02:00
Benno Schulenberg
c22cd03f18 prompt: work around a VTE bug by outdancing an ncurses optimization
This fixes https://savannah.gnu.org/bugs/?48852.
2016-08-25 10:46:28 +02:00
Benno Schulenberg
bd1c5d7c63 moving: make PgUp and PgDown functional also in very flat terminals
Even when the edit window consists of just one or two lines, the PageUp
and PageDown functions (^Y and ^V) should continue to move the window.

This fixes https://savannah.gnu.org/bugs/?48805.
2016-08-21 15:52:24 +02:00
Benno Schulenberg
00b293bf70 tweaks: adjust some braces and indentations 2016-08-21 15:39:00 +02:00
Benno Schulenberg
76a960d73d screen: continue to function also in a terminal with very few lines
This fixes https://savannah.gnu.org/bugs/?48787.
2016-08-17 10:13:22 +02:00
Benno Schulenberg
97eb0e515f tweaks: reshuffle some stuff in a more logical order 2016-08-16 19:22:56 +02:00
Benno Schulenberg
68010d931a startup: don't crash when dying early
That is: don't try to look at open files when none are open yet.
2016-08-16 16:59:37 +02:00
Benno Schulenberg
c661506681 tweaks: use a separate function to ask ncurses for keycodes 2016-08-16 12:01:59 +02:00
Benno Schulenberg
0dd2a55284 screen: don't die when the window is narrower than four columns
This fixes https://savannah.gnu.org/bugs/?48520.
2016-08-15 17:25:33 +02:00
Benno Schulenberg
49fc528d88 restore the GNU marker in nano's name 2016-08-14 21:42:37 +02:00
Benno Schulenberg
928a24c204 input: look at the modifier keys only when compiled on Linux
This fixes https://savannah.gnu.org/bugs/?48751 reported by Andrew Ho.

This also fixes compilation when configured with --enable-tiny.
2016-08-14 21:42:08 +02:00
Benno Schulenberg
d8031af030 screen: retain the placewewant also when using an alternate speller
When using the default speller or the formatter, the placewewant is
remembered.  So it should be remembered too when the user specifies
a different speller.

(This behavior was inadvertently lost last year, in commit 82d737e.)
2016-08-12 20:02:04 +02:00
Benno Schulenberg
f85648db68 po: update translations and regenerate POT file and PO files 2016-08-10 12:14:26 +02:00
Benno Schulenberg
b2e2c89b62 bump version numbers and add a news item for 2.6.3 2016-08-10 11:48:32 +02:00
Benno Schulenberg
290d278f68 input: make the Ctrl+Arrow keys work on a Linux console
If this breaks your build, please send report or instructions or patch.
2016-08-07 18:20:34 +02:00
Benno Schulenberg
8edb096821 input: after an Esc, don't discard starter byte of a multibyte sequence
This fixes https://savannah.gnu.org/bugs/?48711.
2016-08-07 17:40:38 +02:00
Benno Schulenberg
0a387d9d08 usage: show that the option --wordchars needs an argument 2016-08-07 17:04:23 +02:00
Benno Schulenberg
6c16744292 files: avoid a warning about not being able to write a lockfile
Instead be more specific and say that the directory is not writable.
2016-08-07 13:00:35 +02:00
Benno Schulenberg
86a64b1bb5 tweaks: reduce two comparisons to a single one 2016-08-07 13:00:21 +02:00
Rishabh Dave
1fd2354ad4 shortcuts: zero the value of 'toggle' for keys that are not toggles
This fixes http://savannah.gnu.org/bugs/?48698.

Signed-off-by: Rishabh Dave <rishabhddave@gmail.com>
2016-08-07 11:31:55 +02:00
Benno Schulenberg
c8bc05b10e chars: make searching case-insensitively some ten percent faster
It is quicker to do a handful of superfluous compares at the end of
each line than it is to compute and keep track of and compare the
remaining line length the whole time.

The typical line is some sixty characters long, the typical search
string ten characters -- with a shorter search string the speedup is
even higher: some fifteen percent.  Only when the string is longer
than half the average line length does searching become slower with
this new method.

All this for a UTF-8 locale.  For a C locale it makes no difference.
2016-08-07 11:02:41 +02:00
Benno Schulenberg
ee57cbfa66 debug: add a timing instrument to the main search routine 2016-08-07 10:14:42 +02:00
Benno Schulenberg
bd1fcc5fe2 tweaks: correct one comment, and adjust another 2016-08-06 12:17:24 +02:00
Benno Schulenberg
370406bb41 tweaks: don't optimize for a special case -- it is far too seldom 2016-08-06 11:11:56 +02:00
Benno Schulenberg
85844ee6ef chars: remove superfluous afterchecks
Now that mbstrncasecmp() does the right thing, there is no need any
more to verify that only a valid multibyte sequence was matched.

(See https://savannah.gnu.org/bugs/?45579 for a test case.)

Also, this will make it possible to search for invalid sequences.

(Currently it isn't possible to enter a search string with invalid
characters, but... a user might edit the search history file.  And
if pasting at the prompt is implemented, it will be trivial to enter
invalid sequences if you have a file that contains them.)
2016-08-06 11:10:39 +02:00
Benno Schulenberg
e38e2c634b chars: don't persist when only one of the compared sequences is invalid
Persisting might lead to count 'n' reaching zero, which would mean that
the needle has matched, which is wrong when one of the strings contains
an invalid or incomplete multibyte sequence.
2016-08-06 10:34:38 +02:00
Benno Schulenberg
d80109dd5e chars: properly compare strings of different lengths
That is: don't run towlower() on the two differing bytes when having
reached the end of one of the strings.

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

In the bargain, don't do the conversion to lowercase twice.

Furthermore, persist when encountering invalid byte sequences --
until finding bytes that differ.
2016-08-05 16:07:55 +02:00
Benno Schulenberg
b305911cba chars: straighten out the flow of a loop, so it is easier to follow 2016-08-04 13:40:55 +02:00
Benno Schulenberg
d60f95137e chars: remove a special case that never occurs
The needle is never part of the hay -- it is always a separate string.

(And even if needle and haystack were identical, the routine works fine,
the case does not need special treatment.)
2016-08-04 13:40:19 +02:00
Benno Schulenberg
14ac47517b spelling: don't abort when a misspelled word isn't found, just note it
This fixes https://savannah.gnu.org/bugs/?48660 doubly, in case there
are other ways in which 'spell' sees words differently from 'nano'.
2016-08-03 12:55:21 +02:00
Benno Schulenberg
20058a1b63 spelling: don't consider digits as word parts, because GNU spell doesn't
This fixes https://savannah.gnu.org/bugs/?48660.
2016-08-03 12:43:57 +02:00
Benno Schulenberg
f6dd0ad18a tweaks: compile a parameter unconditionally
Straightforward code is more important than the tiniest possible binary.

Also adjust some comments and rename a variable.
2016-08-02 17:30:58 +02:00
Benno Schulenberg
a7ae1766c0 locking: remove any lock files when dying
This fixes https://savannah.gnu.org/bugs/?48675.
2016-08-02 17:30:40 +02:00
Benno Schulenberg
faa46a3c71 screen: remove redundant redrawings of the entire edit window
(It may have been necessary in the past; there is no need for it now.)

This fixes https://savannah.gnu.org/bugs/?48633.
2016-08-01 19:41:13 +02:00
Benno Schulenberg
03b168d0e3 tweaks: restore earlier conditions to prevent superfluous redrawings
When doing an <Up> on the top line, or a <Down> on the bottom line of
the edit window, the affected lines have already been redrawn by the
scrolling code, so there is no need to do that again.

(However, that does not prevent the second line (or the last-but-one
line) from being redrawn unnecessarily when using the M-- (or M-+)
command elsewhere on the screen and /that/ line is horizontally
scrolled.  But we'll let that pass for now.)
2016-08-01 19:41:13 +02:00
Benno Schulenberg
2f6647687a tweaks: rename a function, and adjust some comments 2016-08-01 19:41:13 +02:00
Benno Schulenberg
c9e9964207 screen: don't look at placewewant but at where we actually were and are
For horizontal scrolling, it is not the /desired/ column position that
is relevant for determining whether a line needs to be redrawn after a
cursor movement, but the /actual/ column positions before and after.

This fixes https://savannah.gnu.org/bugs/?48627,
and fixes https://savannah.gnu.org/bugs/?48629.
2016-08-01 19:41:13 +02:00
Benno Schulenberg
0a3a6441bc tweaks: unconditionally compile a couple of parameters
Having two unneeded parameters in the tiny version is acceptable --
the code gets so much more readable.
2016-08-01 19:41:13 +02:00
Benno Schulenberg
2eafe7bf58 files: make allowances for 32-bit PIDs
This addresses https://bugs.debian.org/831636 reported by Christoph Biedl.
2016-08-01 16:24:05 +02:00
Benno Schulenberg
08c51cfd45 input: ingest as verbatim just one control code or one or two escapes
Leave the rest of any escape sequence to be processed normally, which
should be possible because those characters are all in ASCII range.

This fixes https://savannah.gnu.org/bugs/?48318.
2016-08-01 14:47:02 +02:00
Benno Schulenberg
b472f5a633 tweaks: remove some unnecessary keycodes from a switch statement
These codes are the basic codes that get assigned for the movement keys
in the list of shortcuts -- they don't need any translation.
2016-08-01 14:07:21 +02:00
Benno Schulenberg
5806bf5249 tweaks: normalize some whitespace and adjust several comments 2016-08-01 14:05:42 +02:00
Benno Schulenberg
90a90365a8 tweaks: rename three constants, for clarity, and hardcode two others 2016-08-01 12:56:05 +02:00
Benno Schulenberg
9cd30d4917 tweaks: don't bother setting meta_key to false when a key is invalid
That is a task for the key-getting routine.
2016-07-31 18:32:18 +02:00
Benno Schulenberg
f33d8cae30 tweaks: don't use a function call when reference to the variable will do 2016-07-31 18:30:53 +02:00
Benno Schulenberg
e471e2d462 tweaks: move the modified editing keys again 2016-07-31 18:29:57 +02:00
Benno Schulenberg
fe38b78486 tweaks: adjust indentation after the previous changes 2016-07-31 18:22:07 +02:00
Benno Schulenberg
1af1f5c9f4 tweaks: return quicker from the key parsing routine 2016-07-31 18:19:17 +02:00
Benno Schulenberg
b9e83fe9f8 tweaks: move some debugging stuff, and move modified editing keys too
Again, just for preapring an easier return from the parsing routine.
2016-07-31 18:17:06 +02:00
Benno Schulenberg
cb10b2b908 tweaks: elide the global variable 'func_key'
There is no need to specially flag a function key or editing key --
the keycode is indication enough in itself: outside of byte range.
2016-07-31 18:13:05 +02:00
Benno Schulenberg
19dfd20a88 tweaks: add a variable, in preparation for making returning easier 2016-07-31 18:10:31 +02:00
Benno Schulenberg
d12fdda15b tweaks: replace a three-case switch with an if and an else 2016-07-31 18:10:01 +02:00
Benno Schulenberg
3930a697e8 tweaks: consistently use a parameter instead of a struct element 2016-07-30 13:05:52 +02:00
Benno Schulenberg
9322e1e6a4 tweaks: reshuffle two ifs for a little more speed
Saving roughly twenty microseconds at startup.
2016-07-30 13:04:06 +02:00
Benno Schulenberg
b70fe38eab tweaks: normalize some indentation 2016-07-30 12:24:35 +02:00
Benno Schulenberg
1c528db8da tweaks: condense three asserts into a single one
Also, when a key string does not denote a Ctrl nor Meta nor Function key,
there is no point in assigning a keycode, because plain characters cannot
be used as a function shortcut.
2016-07-30 12:24:35 +02:00
Benno Schulenberg
1c9ab8bf16 tweaks: rename a struct element, to be more fitting
The keycode is not a sequence; it is a single integer value.
2016-07-30 12:24:35 +02:00
Benno Schulenberg
e295070193 shortcuts: group the setting of key string and keycode into one function
And instead of using two key types, just use a bool to indicate whether
a keystroke involves Meta.
2016-07-30 12:21:42 +02:00
Benno Schulenberg
91951ab22a input: don't bother putting a keycode into byte range
A keycode is either already in byte range (so there is nothing to do)
or it is not and it shouldn't be (so there is nothing to do either).
2016-07-30 12:19:47 +02:00
Benno Schulenberg
5b0ab8be62 shortcuts: remove any unnecessary classifying of keys
After initialization, the type of a key is never used nor needed
(other than for meta keys).
2016-07-30 12:13:47 +02:00
Benno Schulenberg
ecef093def tweaks: adjust indentation after previous changes 2016-07-29 09:33:28 +02:00
Benno Schulenberg
6d6f5bd4a7 tweaks: check earlier on for sufficient length of the sequence 2016-07-29 09:33:28 +02:00
Benno Schulenberg
e3dbffc9f7 input: be more strict in recognizing certain escape sequences
Accept the "Esc [ 1 n ~" and "Esc [ 2 n ~" sequences only when they
end with the "~" character, not with any character.
2016-07-29 09:33:28 +02:00
Benno Schulenberg
2225d54126 input: don't use a function call when a literal value will do 2016-07-29 09:33:28 +02:00
Benno Schulenberg
9115828e76 input: fix a pasto from eight years ago, from commit e347efb 2016-07-29 09:33:16 +02:00
Benno Schulenberg
b43a72471a docs: tweak some spacing and spelling 2016-07-29 09:05:40 +02:00
69 changed files with 20781 additions and 20133 deletions

16
AUTHORS
View File

@@ -1,9 +1,9 @@
This file lists people who have made significant contributions to the
nano editor. Please see the ChangeLog for specific changes by author.
-------------------------------------------------------------------------
----------------------------------------------------------------------
Chris Allegretta <chrisa@asty.org>
* Original program author, former and current maintainer.
* Original program author and long-time maintainer.
David Lawrence Ramsey <pooka109@gmail.com>
* Former stable series maintainer. Multiple buffer support,
@@ -44,6 +44,16 @@ Mike Frysinger <vapier@gentoo.org>
Mark Majeres <mark@engine12.com>
* A functional undo/redo system, and coloring nano's interface.
Mahyar Abbaspour <mahyar.abaspour@gmail.com>
* Improved handling of SIGWINCH.
Mike Scalora <mike@scalora.org>
* The comment/uncomment feature.
Faissal Bensefia <faissaloo@gmail.com>
* Line numbers.
Benno Schulenberg <bensberg@justemail.net>
* A bunch of small bug fixes, the cutword routines, some extra
* An array of small bug fixes, the cut-word and block-jump
routines, text selection by holding Shift, and some extra
key bindings. Current maintainer.

View File

@@ -1,7 +1,12 @@
Improvements in nano
====================
Improvements in GNU nano
========================
Since 2.7.0:
- The ability to display line numbers in front of the text.
Since 2.6.0:
- Shift plus the cursor keys can be used for selecting text.
- Ctrl+Arrow should now work also on a Linux virtual console.
- Ctrl+Up and Ctrl+Down jump to previous or next block of text.
- Feedback during Unicode Input (M-V followed by six digits).
- The option 'wordchars' for specifying extra word characters.

46
NEWS
View File

@@ -1,3 +1,31 @@
2016.10.29 - GNU nano 2.7.1 "Leuven" adds an often-asked-for feature: the
ability to display line numbers beside the text. This can
be activated with -l or --linenumbers on the command line,
or with 'set linenumbers' in your nanorc, or toggled with
M-#. The coloring of these numbers can be chosen via the
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
read into it. Come and check it out!
2016.09.01 - GNU nano 2.7.0 "Suni" adds a new feature: allowing text to be
selected by holding Shift together with the cursor keys.
Besides that, nano now works also when run in very tiny
terminals (down to one line, one column), and improves
the handling of the prompt in cramped spaces. Not much,
but it's time to get it out there.
2016.08.10 - nano 2.6.3 "Marika" makes the Ctrl+Arrow keys work also on
a Linux virtual console, takes as verbatim only the very
first keystroke after M-V, removes any lock files that it
holds when dying, doesn't abort when a word contains digits
(when using the default speller), fixes a small sorting bug
in the file browser, makes searching case-insensitively in
a UTF-8 locale a little faster, and doesn't enter invalid
bytes when holding down both Alt keys. Santé!
2016.07.28 - nano 2.6.2 "Le vent nous portera" adds two new features: the
keystrokes Ctrl+Up and Ctrl+Down for jumping between blocks
of text, and the option 'wordchars' for specifying which
@@ -35,7 +63,7 @@
2016.02.25 - GNU nano 2.5.3 "Alphys" is released. This release
contains fixes for bugs like: stray cursor positioning
errors, many many memory leaks including file reading,
using the file browser, searching for multi-byte characters,
using the file browser, searching for multibyte characters,
history completion, and many other places.
New features include the ability to trim whitespace
from the ends of lines when justifying text, see nanorc(5)
@@ -161,7 +189,7 @@
2014.06.02 - GNU nano 2.3.4 won't leave you high, won't leave you dry. This
release contains only a small number of fixes, but in
particular allows nano to compile on non-UTF8 curses
particular allows nano to compile on non-UTF-8 curses
implementations (i.e. libncursesw). Other small fixes to
the undo implementation and the default syntax config are
also included. As always, Share and Enjoy!
@@ -197,7 +225,7 @@
release includes some fixes for the new libmagic code, as
well as a fix for improper character counts when using
auto-indent. Also included are new syntax highlighting
definitions for RPM spec and lua files. Thanks for
definitions for RPM spec and Lua files. Thanks for
using nano and keep circulating the tapes.
2011.02.26 - GNU nano 2.3.0 "Septic surprise" is released. This first
@@ -477,7 +505,7 @@
thanks for sticking with us!
2007.12.20- GNU nano 2.0.7 keeps its balance. This release fixes
2007.12.20 - GNU nano 2.0.7 keeps its balance. This release fixes
several bugs, among others: a segfault and several
cursor positioning problems when uncutting text or
inserting files into the current buffer; a problem where
@@ -499,12 +527,12 @@
under the GNU GPL version 3 or later and the GNU FDL
version 1.2 or later. Have fun.
2007.04.26- GNU nano 2.0.6 "that was quick" is released. This release
2007.04.26 - GNU nano 2.0.6 "that was quick" is released. This release
fixes a potential segfault after justifying text marked
from the bottom up. It also adds one more minor
documentation update. Enjoy.
2007.04.22- GNU nano 2.0.5 braces for impact. Among other things, this
2007.04.22 - GNU nano 2.0.5 braces for impact. Among other things, this
release fixes various problems (including a segfault)
when trying to open or save a file in a directory
beginning with "~" that isn't a home directory; fixes a
@@ -612,7 +640,7 @@
properly at all times; lines of text containing tabs are
now wrapped at the right place; double-column characters
are now properly displayed when past the right edge of
the screen; invalid multi-line color regexes are now
the screen; invalid multiline color regexes are now
ignored; and so on. Enjoy.
2006.03.30 - GNU nano 1.3.11 awakens from its fever dream. This release
@@ -950,7 +978,7 @@
0.11.2 of gettext, building with automake 1.6, some new
code for displaying control characters, browser
improvements, a new backup file option (-B, --backup), a
new option to ignore rc files (-I,--ignorercfiles),
new option to ignore rc files (-I, --ignorercfiles),
compatibility with -pedantic, handling null characters
before EOF, a slightly sportier nanorc.sample and more.
Fixes are included for justification,
@@ -1179,7 +1207,7 @@
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
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!"

6
README
View File

@@ -1,5 +1,5 @@
nano - an enhanced clone of the Pico text editor
GNU nano - an enhanced clone of the Pico text editor.
Overview
@@ -68,5 +68,5 @@ Mailing Lists and Bug Reports
Current Status
nano has reached its seventh milestone, 2.6.x. Since 2.5.0, it is
a "rolling" release: bug fixing and development go hand in hand.
GNU nano has reached its seventh milestone, 2.6.x. Since 2.5.0, it
is a "rolling" release: bug fixing and development go hand in hand.

View File

@@ -1,14 +1,14 @@
INSTRUCTIONS TO COMPILE AND INSTALL NANO GIT VERSIONS
=====================================================
The latest version of nano is available via git, but building this needs a
bit more care than the official stable and unstable tarballs.
The latest version of GNU nano is available via git, but building this needs
a bit more care than the official stable and unstable tarballs.
Prerequisites
-------------
To successfully compile nano from the git repo, you'll need the following
To successfully compile GNU nano from the git repo, you'll need the following
packages:
- autoconf (version >= 2.61)
@@ -80,5 +80,26 @@ you'll need to run that "make install" command with root privileges.
Problems?
---------
Please submit any bugs in the git repository using the Savannah project's
bug tracker (https://savannah.gnu.org/bugs/?group=nano).
Please submit any bugs you find in the code in git via the bug tracker
on Savannah (https://savannah.gnu.org/bugs/?group=nano).
Contributing something
----------------------
If you have a fix for a bug, or the code for a new or improved feature,
first create a branch off of master:
$ git checkout -b somename
Then change the code so it does what you want, and commit it, with in the
commit message (after the one-line summary) a rationale for the change:
$ git commit -as
Then create a patch (or patches):
$ git format-patch master
Send that patch (or patches) to <nano-devel@gnu.org>, as an attachment
or with git send-email.

2
THANKS
View File

@@ -1,4 +1,4 @@
The following people have helped nano in some way or other.
The following people have helped GNU nano in some way or another.
If we missed you here, let us know!

40
TODO
View File

@@ -1,9 +1,8 @@
TODO file (? means the feature may be implemented, but not definitely)
------------------------------------------------------------------------
A list of desired features
--------------------------
For the future (no targeted version, catch-all)
Vague musings:
- FriBidi support?
- Port to DJGPP?
- Make matching bracket searches sophisticated enough to skip over
brackets inside comments?
- Allow indentation of marked text by spaces as well as tabs?
@@ -12,26 +11,27 @@ For the future (no targeted version, catch-all)
- Allow conversion between different character sets. Maybe use glib's
iconv() if the system's iconv() is inadequate, since we already use
glib's vsnprintf() if the system lacks vsnprintf()?
- Allow setting marks (saved positions, not to be confused with the mark
set via Ctrl-^) at various lines and/or columns in the buffer, and
allow movement between them with a single keystroke?
- Allow searching for and replacing newlines?
See also https://savannah.gnu.org/bugs/?47053.
- New regression framework built on expect?
- Add the ability to move to different lines of the screen with a single
keystroke, e.g. M-` (M-~) to go to the top line, M-& (M-7) to go to
the center line, and M-' (M-") to go to the last line?
Somewhat urgent:
- Allow text searches in the help viewer.
See https://savannah.gnu.org/bugs/?28994.
- Detect when text is being pasted, so that we can handle it faster.
See https://savannah.gnu.org/bugs/?40060.
- Allow color syntaxes to apply to more than just color, so that we can
e.g. specify a different alternate spell checker depending on which
file type we have open.
- Allow setting marks (saved positions, not to be confused with the mark
set via Ctrl-^) at various lines and/or columns in the buffer, and
allow movement between them with a single keystroke? (We're running
out of keystrokes, though.)
- Allow searching for and replacing newlines.
For version 2.6:
- New regression framework built on expect.
- Allow text searches in the help viewer.
- Add the ability to move to different lines of the screen with a single
keystroke, e.g. M-` (M-~) to go to the top line, M-& (M-7) to go to
the center line, and M-' (M-") to go to the last line.
- Detect when we're pasting text, so that we can handle it differently
(i.e. faster than currently with screen redraws).
- Allow piping marked text to an external command and replacing it with
the command's output (as the internal spell checker already does with
the "spell" command)?
the command's output -- that is: generalize the spell-check flow.
See also https://savannah.gnu.org/bugs/?28993.
For version 2.4:
- Handle window resizes better. After we've resized, we should stay

View File

@@ -1,24 +1,22 @@
# Configuration for nano - a small and user-friendly text editor
# Configuration for GNU nano - a small and user-friendly text editor
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
# 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc.
#
# nano is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any
# later version.
# GNU nano is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
#
# nano is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# GNU nano is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with nano; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
# USA.
# along with this program. If not, see http://www.gnu.org/licenses/.
AC_INIT([nano], [2.6.2], [nano-devel@gnu.org], [nano])
AC_INIT([GNU nano], [2.7.1], [nano-devel@gnu.org], [nano])
AC_CONFIG_SRCDIR([src/nano.c])
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE
@@ -127,6 +125,19 @@ fi
AC_ARG_ENABLE(libmagic,
AS_HELP_STRING([--disable-libmagic], [Disable detection of file types via libmagic]))
AC_ARG_ENABLE(linenumbers,
AS_HELP_STRING([--disable-linenumbers], [Disable line numbering]))
if test "x$enable_tiny" = xyes; then
if test "x$enable_linenumbers" != xyes; then
enable_linenumbers=no
fi
fi
if test "x$disable_linenumbers" != xyes; then
if test "x$enable_linenumbers" != xno; then
AC_DEFINE(ENABLE_LINENUMBERS, 1, [Define this to enable line numbering.])
fi
fi
AC_ARG_ENABLE(mouse,
AS_HELP_STRING([--disable-mouse], [Disable mouse support (and -m flag)]))
if test "x$enable_mouse" = xno; then

View File

@@ -1,21 +1,21 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>The nano editor FAQ</title>
<title>The GNU nano editor FAQ</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#330000" bgcolor="#ffffff" link="#0000ef" vlink="#51188e" alink="#ff0000">
<h1>The nano editor FAQ</h1>
<h1>The GNU nano editor FAQ</h1>
<h2>Table of Contents</h2>
<h2><a href="#1">1. General</a></h2>
<blockquote><p><a href="#1.1">1.1 About this FAQ</a><br>
<a href="#1.2">1.2. How do I contribute to it?</a><br>
<a href="#1.3">1.3. What is nano?</a><br>
<a href="#1.3">1.3. What is GNU nano?</a><br>
<a href="#1.4">1.4. What is the history behind nano?</a><br>
<a href="#1.5">1.5. Why the name change from TIP?</a><br>
<a href="#1.6">1.6. What is the current version of nano?</a><br>
<a href="#1.7">1.7. I want to read the manpage without having to download the program!</a></p></blockquote>
<h2><a href="#2">2. Where to get nano.</a></h2>
<h2><a href="#2">2. Where to get GNU nano.</a></h2>
<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>
@@ -69,8 +69,8 @@
<blockquote><p>This FAQ was originally written and maintained by Chris Allegretta &lt;<a href="mailto:chrisa@asty.org">chrisa@asty.org</a>&gt;, who also happens to be the creator of nano. It was then maintained by David Lawrence Ramsey &lt;<a href="mailto:pooka109@gmail.com">pooka109@gmail.com</a>&gt;. Maybe someone else will volunteer to maintain this FAQ someday, who knows...</p></blockquote>
<h2><a name="1.2"></a>1.2. How do I contribute to it?</h2>
<blockquote><p>Your best bet is to send it to the nano email address, <a href="mailto:nano@nano-editor.org">nano@nano-editor.org</a> and if it is useful enough it will be included in future versions.</p></blockquote>
<h2><a name="1.3"></a>1.3. What is nano?</h2>
<blockquote><p>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 perhaps include extra functionality&quot;.</p></blockquote>
<h2><a name="1.3"></a>1.3. What is GNU nano?</h2>
<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 perhaps include extra functionality&quot;.</p></blockquote>
<h2><a name="1.4"></a>1.4. What is the history behind nano?</h2>
<blockquote><p>Funny you should ask!</p>
<p><b>In the beginning...</b></p>
@@ -84,24 +84,26 @@
<h2><a name="1.5"></a>1.5. Why the name change from TIP?</h2>
<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.6"></a>1.6. What is the current version of nano?</h2>
<blockquote><p>The current stable version of nano *should* be 2.4.2. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
<blockquote><p>The current version of nano *should* be 2.7.0. 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.7"></a>1.7. I want to read the man page without having to download the program!</h2>
<blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/v2.6/nano.1.html">here</a>.</p></blockquote>
<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 nano.</h1>
<h2><a name="2.1"></a>2.1. FTP and WWW sites that carry nano.</h2>
<blockquote><p>The nano distribution can be downloaded at the following web sites:</p>
<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>
<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. RedHat and derivatives (.rpm) packages.</h2>
<h2><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h2>
<blockquote>
<ul>
<li><a href="https://nano-editor.org/dist/v2.5/RPMS/">https://nano-editor.org/dist/v2.5/RPMS/</a></li>
<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. Debian (.deb) packages.</h2>
<h2><a name="2.3"></a>2.3. Deb packages (Debian and derivatives):</h2>
<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>
@@ -185,7 +187,7 @@
<h2><a name="4.6"></a>4.6. nano crashes when I type &lt;insert keystroke here&gt;!</h2>
<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>
<blockquote><p>Older versions of nano had this problem, please upgrade to a newer version (at least 0.9.9, but 2.4.2 is recommended).</p></blockquote>
<blockquote><p>Older versions of nano had this problem. Please upgrade to version 2.7.0 or newer.</p></blockquote>
<h2><a name="4.8"></a>4.8. [version 1.3.12 and later] I'm using glibc 2.2.3, and nano crashes when I use color support or do regular expression searches. How can I fix that?</h2>
<blockquote><p>It's a bug in glibc 2.2.3. You should upgrade to at least glibc 2.2.4.</p></blockquote>
<h2><a name="4.9"></a>4.9. [version 1.1.12 and earlier] Why does nano show ^\ in the shortcut list instead of ^J?</h2>
@@ -214,14 +216,13 @@
<h2><a name="4.14"></a>4.14. 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.15"></a>4.15. 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>
<blockquote><p>In nano 2.3.0, cursor-position history was introduced, and both history files now reside under a .nano directory in your home. nano was trying to move this file into the new location so it could continue to use it. This means that if you try and use an earlier version of nano, it will be unable to see your current search history. To fix this, run the following commands:<br>
<p><b>mv ~/.nano/search_history ~/.nano_history</b><br>
<b>ln -sf ~/.nano_history ~/.nano/search_history</b></p>
</p></blockquote>
<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:<br>
<p><b>ln -sf ~/.nano/search_history ~/.nano_history</b></p>
</p><p>The "migration service" (moving the search-history file to its new location) will be deleted from nano in early 2018.</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>
<blockquote><p>In June 2001, nano entered the <a href="http://translationproject.org/html/welcome.html">Translation Project</a> and since then, translations should be managed from there.</p>
<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 very 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 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>
@@ -247,7 +248,7 @@ Of course, due to the license change you can now use the <A HREF="http://www.was
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.2. I want to send the development team a big load of cash (or just a thank you).</h2>
<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/v2.6/TODO">cool feature</a> and send us that instead (though cash is fine too).</p></blockquote>
<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.3"></a>7.3. How do I submit a bug report or patch?</h2>
<blockquote>
<p>The best place to submit bugs is to the <a href="https://savannah.gnu.org/bugs/?group=nano">Savannah bug tracker</a> as you can check whether the bug you are submitting has already been submitted.

View File

@@ -17,16 +17,15 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH NANO 1 "version 2.6.2" "July 2016"
.TH NANO 1 "version 2.7.1" "October 2016"
.\" Please adjust this date whenever revising the manpage.
.\"
.SH NAME
nano \- Nano's ANOther editor, an enhanced free Pico clone
.SH SYNOPSIS
.B nano
.RI [ options "] [[+" line , column "]\ " file "]..."
.RI [ options "] [[+" line [, column "]]\ " file "]..."
.SH DESCRIPTION
\fBnano\fP is a small, free and friendly editor which aims to replace
@@ -38,7 +37,7 @@ replace" and "go to line and column number".
.SH EDITING
Entering text and moving around in a file is straightforward: typing the
letters and using the normal cursor movement keys. Commands are entered
by using the Control (^) and the Alt or Meta (M-) keys.
by using the Control (^) and the Alt or Meta (M\-) keys.
Typing \fB^K\fR deletes the current line and puts it in the cutbuffer.
Consecutive \fB^K\fRs will put all deleted lines together in the cutbuffer.
Any cursor movement or executing any other command will cause the next
@@ -47,10 +46,14 @@ contents of the cutbuffer at the current cursor position.
.PP
When a more precise piece of text needs to be cut or copied, one can mark
its start with \fB^6\fR, move the cursor to its end (the marked text will be
highlighted), and then use \fB^K\fR to cut it, or \fBM-6\fR to copy it to the
cutbuffer. One can also save the marked text to a file with \fB^O\fR, or
highlighted), and then use \fB^K\fR to cut it, or \fBM\-6\fR to copy it to the
cutbuffer. One can also save the marked text to a file with \fB^O\fR, or
spell check it with \fB^T\fR.
.PP
Since nano-2.7.0, text can also be selected by holding Shift and moving the
cursor with the arrow keys. Holding down the Alt key too will increase the
stride.
.PP
The two lines at the bottom of the screen show the most important commands;
the built-in help (\fB^G\fR) lists all the available ones.
The default key bindings can be changed via the .nanorc file -- see
@@ -168,6 +171,10 @@ Interpret the Delete key differently so that both Backspace and Delete
work properly. You should only need to use this option if Backspace
acts like Delete on your system.
.TP
.BR \-g ", " \-\-showcursor
Make the cursor visible in the file browser, putting it on the
highlighted item. Useful for braille users.
.TP
.BR \-h ", " \-\-help
Show a summary of the available command-line options and exit.
.TP
@@ -176,9 +183,12 @@ Indent new lines to the previous line's indentation. Useful when
editing source code.
.TP
.BR \-k ", " \-\-cut
Make the 'Cut Text' command (normally ^K) cut from the current cursor
Make the 'Cut Text' command (normally \fB^K\fR) cut from the current cursor
position to the end of the line, instead of cutting the entire line.
.TP
.BR \-l ", " \-\-linenumbers
Display line numbers to the left of the text area.
.TP
.BR \-m ", " \-\-mouse
Enable mouse support, if available for your system. When enabled, mouse
clicks can be used to place the cursor, set the mark (with a double
@@ -210,15 +220,13 @@ Hard-wrap lines at column \fInumber\fP. If this value is 0 or less, wrapping
will occur at the width of the screen less \fInumber\fP columns, allowing
the wrap point to vary along with the width of the screen if the screen
is resized. The default value is \-8. This option conflicts with
.B \-w
-- the last one given takes effect.
\fB\-w\fR -- the last one given takes effect.
.TP
.BR \-s\ \fIprogram\fR ", " \-\-speller= \fIprogram
Use this alternative spell checker command.
.TP
.BR \-t ", " \-\-tempfile
Always save a changed buffer without prompting. Same as Pico's \fB\-t\fP
option.
Save a changed buffer without prompting (when exiting with \fB^X\fR).
.TP
.BR \-u ", " \-\-unix
Save a file by default in Unix format. This overrides nano's
@@ -226,12 +234,11 @@ default behavior of saving a file in the format that it had.
(This option has no effect when you also use \fB\-\-noconvert\fR.)
.TP
.BR \-v ", " \-\-view
View-file (read-only) mode.
Just view the file and disallow editing: read-only mode.
.TP
.BR \-w ", " \-\-nowrap
Disable the hard-wrapping of long lines. This option conflicts with
.B \-r
-- the last one given takes effect.
\fB\-r\fR -- the last one given takes effect.
.TP
.BR \-x ", " \-\-nohelp
Don't show the two help lines at the bottom of the screen.
@@ -247,9 +254,17 @@ continuing it over multiple screen lines. Since
this option last when using other options (e.g.\& 'nano \-wS$') or pass it
separately (e.g.\& 'nano \-wS \-$').
.TP
.BR \-a ", " \-b ", " \-e ", " \-f ", " \-g ", " \-j
.BR \-a ", " \-b ", " \-e ", " \-f ", " \-j
Ignored, for compatibility with Pico.
.SH TOGGLES
Several of the above options can be switched on and off also while
\fBnano\fR is running. For example, \fBM\-L\fR toggles the
hard-wrapping of long lines, \fBM\-$\fR toggles soft-wrapping,
\fBM\-#\fR toggles line numbers, \fBM\-M\fR toggles the mouse,
\fBM\-I\fR auto-indentation, and \fBM\-X\fR the help lines.
See at the end of the \fB^G\fR help text for a complete list.
.SH INITIALIZATION FILE
\fBnano\fP will read initialization files in the following order:
the system's \fBnanorc\fP (if it exists), and then the user's
@@ -261,7 +276,7 @@ for more information on the possible contents of those files.
If no alternative spell checker command is specified on the command
line nor in one of the \fInanorc\fP files, \fBnano\fP will check the
\fBSPELL\fP environment variable for one.
.sp
In some cases \fBnano\fP will try to dump the buffer into an emergency
file. This will happen mainly if \fBnano\fP receives a SIGHUP or
SIGTERM or runs out of memory. It will write the buffer into a file
@@ -273,27 +288,24 @@ it unique. In multibuffer mode, \fBnano\fP will write all the open
buffers to their respective emergency files.
.SH BUGS
Justifications (\fB^J\fR) and reindentations (\fBM-{\fR and \fBM-}\fR)
Justifications (\fB^J\fR) and reindentations (\fBM\-{\fR and \fBM\-}\fR)
are not yet covered by the general undo system. So after a justification
that is not immediately undone, or after any reindentation, earlier edits
cannot be undone any more. The workaround is, of course, to exit without
saving.
.sp
Please report any other bugs that you encounter via
https://savannah.gnu.org/bugs/?group=nano.
\fIhttps://savannah.gnu.org/bugs/?group=nano\fR.
.SH HOMEPAGE
https://nano-editor.org/
.SH SEE ALSO
.PD 0
.TP
\fBnanorc\fP(5)
.BR nanorc (5)
.PP
\fI/usr/share/doc/nano/\fP (or equivalent on your system)
.SH AUTHOR
Chris Allegretta <chrisa@asty.org>, et al (see the files \fIAUTHORS\fP and
Chris Allegretta and others (see the files \fIAUTHORS\fR and
\fITHANKS\fP for details). This manual page was originally written by
Jordi Mallach <jordi@gnu.org>, for the Debian system (but may be used by
others).
Jordi Mallach for the Debian system (but may be used by others).

View File

@@ -17,11 +17,12 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH NANORC 5 "version 2.6.2" "July 2016"
.TH NANORC 5 "version 2.7.1" "October 2016"
.\" Please adjust this date whenever revising the manpage.
.\"
.SH NAME
nanorc \- nano's rcfile
nanorc \- GNU nano's configuration file
.SH DESCRIPTION
The \fInanorc\fP file contains the default settings for \fBnano\fP, a
small and friendly editor. The file should be in Unix format, not in
@@ -116,6 +117,9 @@ Specify the color combination to use for the shortcut key combos
in the two help lines at the bottom of the screen.
See \fBset titlecolor\fR for more details.
.TP
.B set linenumbers
Display line numbers to the left of the text area.
.TP
.B set locking
Enable vim-style lock-files for when editing files.
.TP
@@ -150,6 +154,10 @@ Don't automatically add a newline to the ends of files.
.B set nowrap
Don't hard-wrap text at all.
.TP
.B set numbercolor \fIfgcolor\fR,\fIbgcolor\fR
Specify the color combination to use for line numbers.
See \fBset titlecolor\fR for more details.
.TP
.B set operatingdir "\fIdirectory\fP"
\fBnano\fP will only read and write files inside \fIdirectory\fP and its
subdirectories. Also, the current directory is changed to here, so
@@ -200,6 +208,10 @@ won't work properly with this option enabled.
.B set regexp
Do extended regular expression searches by default.
.TP
.B set showcursor
Put the cursor on the highlighted item in the file browser, to aid
braille users.
.TP
.B set smarthome
Make the Home key smarter. When Home is pressed anywhere but at the
very beginning of non-whitespace characters on a line, the cursor will
@@ -413,6 +425,7 @@ a string in the current list in the file browser.
.TP
.B searchagain
Repeats the last search command without prompting.
(The form 'research' is deprecated.)
.TP
.B findprevious
As \fBsearchagain\fR, but always in the backward direction.
@@ -447,6 +460,7 @@ Cuts all text from the cursor position till the end of the buffer.
.TP
.B curpos
Shows the current cursor position: the line, column, and character positions.
(The form 'cursorpos' is deprecated.)
.TP
.B wordcount
Counts the number of words, lines and characters in the current buffer.
@@ -579,6 +593,7 @@ Toggles case sensitivity in searching (search/replace menus only).
.TP
.B regexp
Toggles whether searching/replacing is based on literal strings or regular expressions.
(The form 'regex' is deprecated.)
.TP
.B backwards
Toggles whether searching/replacing goes forward or backward.
@@ -591,6 +606,7 @@ Shows the next history entry in the prompt menus (e.g. search).
.TP
.B flipreplace
Toggles between searching for something and replacing something.
(The form 'dontreplace' is deprecated.)
.TP
.B flipexecute
Toggles between inserting a file and executing a command.
@@ -598,6 +614,7 @@ Toggles between inserting a file and executing a command.
.B flipnewbuffer
Toggles between inserting into the current buffer and into a new
empty buffer.
(The form 'newbuffer' is deprecated.)
.TP
.B dosformat
When writing a file, switches to writing a DOS format (CR/LF).
@@ -701,6 +718,7 @@ The 'search to replace' menu.
.TP
.B replacewith
The 'replace with' menu, which comes up after 'search to replace'.
(The form 'replace2' is deprecated.)
.TP
.B gotoline
The 'goto line (and column)' menu.
@@ -745,14 +763,11 @@ System-wide configuration file.
.TP
.B ~/.nanorc
Per-user configuration file.
.SH SEE ALSO
.TP
\fBnano\fP(1)
.PP
\fI/usr/share/doc/nano/examples/nanorc.sample\fP (or equivalent on your
system)
.BR nano (1)
.SH AUTHOR
Chris Allegretta <chrisa@asty.org>, et al (see \fIAUTHORS\fP and
Chris Allegretta and others (see the files \fIAUTHORS\fP and
\fITHANKS\fP for details). This manual page was originally written by
Jordi Mallach <jordi@gnu.org>, for the Debian system (but may be used by
others).
Jordi Mallach for the Debian system (but may be used by others).

View File

@@ -16,64 +16,52 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH RNANO 1 "version 2.6.2" "July 2016"
.TH RNANO 1 "version 2.7.1" "October 2016"
.\" Please adjust this date whenever revising the manpage.
.\"
.SH NAME
rnano \- Restricted mode for Nano's ANOther editor, an enhanced free
Pico clone
rnano \- a restricted nano
.SH SYNOPSIS
.B rnano
.RI [ options "] [[+" line , column "]\ " file "]..."
.RI [ options "] [[+" line [, column "]]\ " file "]..."
.SH DESCRIPTION
\fBnano\fP is a small, free and friendly editor which aims to replace
Pico, the default editor included in the non-free Pine package. On
top of copying Pico's look and feel, \fBnano\fP also implements some
missing (or disabled by default) features in Pico, such as "search and
replace" and "go to line and column number".
\fBrnano\fR runs the \fBnano\fR editor in restricted mode. This allows
editing only the specified file or files, and doesn't allow the user
access to the filesystem nor to a command shell.
.PP
\fBrnano\fP is a restricted version of \fBnano\fP, which only edits
specific files and doesn't allow the user access to the filesystem or a
command shell.
.PP
In restricted mode, \fBnano\fP will \fInot\/\fP:
In restricted mode, \fBnano\fR will:
.IP \[bu] 2
read or write to any file not specified on the command line;
not read any nanorc files;
.IP \[bu]
read any nanorc files;
not allow suspending;
.IP \[bu]
allow suspending;
not read nor write any file not specified on the command line;
.IP \[bu]
allow a file to be appended to, prepended to, or saved under a different
name;
not allow saving a file under a different name;
.IP \[bu]
use backup files or spell checking.
not allow appending or prepending to any file;
.IP \[bu]
not make backup files nor do spell checking.
.SH OPTIONS
.TP
.BR \-h ", " \-\-help
Show a summary of command-line options and exit.
.TP
.BR \-V ", " \-\-version
Show the current version number and exit.
.PP
See the \fBnano\fP(1) manpage for all of the possible options.
See the \fBnano\fP(1) manpage for all available options.
.SH BUGS
Please send any comments or bug reports to \fBnano@nano-editor.org\fP.
The \fBnano\fP mailing list is available from \fBnano-devel@gnu.org\fP.
To subscribe, email to \fBnano-devel-request@gnu.org\fP with a subject
of "subscribe".
Please report bugs via \fIhttps://savannah.gnu.org/bugs/?group=nano\fR.
.SH HOMEPAGE
http://www.nano-editor.org/
https://nano-editor.org/
.SH SEE ALSO
.BR nano (1)
.SH AUTHOR
Chris Allegretta <chrisa@asty.org>, et al (see the file AUTHORS for details).
This manual page was originally written by Thijs Kinkhorst
<thijs@kinkhorst.com>, for the Debian system (but may be used by
others).
Chris Allegretta and others (see the files \fIAUTHORS\fR and \fITHANKS\fR
for details). This manual page was originally written by Thijs Kinkhorst
for the Debian system (but may be used by others).

View File

@@ -1,4 +1,4 @@
## Sample initialization file for nano.
## Sample initialization file for GNU nano.
##
## Please note that you must have configured nano with --enable-nanorc
## for this file to be read! Also note that this file should not be in
@@ -63,6 +63,9 @@
## Make the justify command kill whitespace at the end of lines.
# set justifytrim
## Display line numbers to the left of the text.
# set linenumbers
## Enable vim-style lock-files. This is just to let a vim user know you
## are editing a file [s]he is trying to edit and vice versa. There are
## no plans to implement vim-style undo state in these files.
@@ -138,6 +141,10 @@
## Do extended regular expression searches by default.
# set regexp
## Put the cursor on the highlighted item in the file browser;
## useful for people who use a braille display.
# set showcursor
## Make the Home key smarter. When Home is pressed anywhere but at the
## very beginning of non-whitespace characters on a line, the cursor
## will jump to that beginning (either forwards or backwards). If the
@@ -189,8 +196,9 @@
## Paint the interface elements of nano.
## This is an example; by default there are no colors.
## These are examples; by default there are no colors.
# set titlecolor brightwhite,blue
# set numbercolor cyan
# set statuscolor brightwhite,green
# set keycolor green
# set functioncolor yellow

View File

@@ -7,11 +7,11 @@ comment "#"
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|comment|magic|linter|i?color|extendsyntax).*$"
# Keywords
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|autoindent|backup|backwards|boldtext|casesensitive|const(antshow)?|cut|fill|historylog|justifytrim|locking|morespace|mouse|multibuffer|noconvert|nohelp|nonewlines|nowrap|pos(ition)?log|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|smarthome|smooth|softwrap|suspend|tabsize|tabstospaces|tempfile|unix|view|wordbounds)\>"
icolor yellow "^[[:space:]]*set[[:space:]]+(functioncolor|keycolor|statuscolor|titlecolor)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|functioncolor|keycolor|matchbrackets|operatingdir|punct|quotestr|speller|statuscolor|titlecolor|whitespace)[[:space:]]+"
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^|M-)([[:alpha:]]|space|[]]|[0-9^_=+{}|;:'\",./<>\?-])|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+[[:alpha:]]+[[:space:]]+(all|main|search|replace(2|with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
icolor brightgreen "^[[:space:]]*unbind[[:space:]]+((\^|M-)([[:alpha:]]|space|[]]|[0-9^_=+{}|;:'\",./<>\?-])|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+(all|main|search|replace(2|with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cut|fill|historylog|justifytrim|locking|morespace|mouse|multibuffer|noconvert|nohelp|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize|tabstospaces|tempfile|unix|view|wordbounds)\>"
icolor yellow "^[[:space:]]*set[[:space:]]+((function|key|number|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[[:space:]]+(backupdir|brackets|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|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:]]*$)"
icolor brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|linter|formatter)[[:space:]]+.*$"
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|extendsyntax)\>"

View File

@@ -7,7 +7,8 @@ comment "#"
color green "^#.*$"
color yellow "Copyright|\(C\)"
# Header fields.
color brightmagenta "\<(Project\-Id\-Version|Report\-Msgid\-Bugs\-To|Last\-Translator|Language(\-Team)?|X\-Generator|Plural\-Forms)\>"
color brightred "^\"X-Bugs:.*\"$"
color brightmagenta "\<(Project\-Id\-Version|Report\-Msgid\-Bugs\-To|Last\-Translator|Language(\-Team)?|X-Bugs|X-Generator|Plural\-Forms)\>"
color cyan "\<(POT\-Creation\-Date|PO\-Revision\-Date|MIME\-Version|Content\-Type|Content\-Transfer\-Encoding)\>"
# Encodings and numbers.
color yellow "\<(UTF|ISO|Windows|Mac|IBM)\>\-[0-9]"

View File

@@ -6,8 +6,8 @@
@smallbook
@set EDITION 0.4
@set VERSION 2.6.2
@set UPDATED July 2016
@set VERSION 2.7.1
@set UPDATED October 2016
@dircategory Editors
@direntry
@@ -19,16 +19,16 @@
@c end tex
@titlepage
@title @code{nano}
@title GNU @code{nano}
@subtitle a small and friendly text editor.
@subtitle version 2.6.2
@subtitle version 2.7.1
@author Chris Allegretta
@page
This manual documents @code{nano}, a small and friendly text editor.
This manual documents GNU @code{nano}, a small and friendly text editor.
This manual is part of the @code{nano} distribution.@*
This manual is part of the GNU @code{nano} distribution.@*
@sp 4
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2009, 2014, 2015 Free Software Foundation, Inc.
@@ -55,7 +55,7 @@ e-mail: @email{chrisa@@asty.org}@*
@node Top
@top
This manual documents @code{nano}, a small and friendly text editor.
This manual documents GNU @code{nano}, a small and friendly text editor.
@menu
* Introduction::
@@ -74,7 +74,7 @@ This manual documents @code{nano}, a small and friendly text editor.
@node Introduction
@chapter Introduction
@code{nano} is a small and friendly text editor. Besides basic text
GNU @code{nano} is a small and friendly text editor. Besides basic text
editing, @code{nano} offers many extra features, such as an interactive
search-and-replace, undo/redo, syntax coloring, smooth scrolling,
auto-indentation, go-to-line-and-column-number, feature toggles,
@@ -256,6 +256,11 @@ Interpret the Delete key differently so that both Backspace and Delete
work properly. You should only need to use this option if Backspace
acts like Delete on your system.
@item -g
@itemx --showcursor
Make the cursor visible in the file browser, putting it on the
highlighted item. Useful for braille users.
@item -h
@itemx --help
Show a summary of command-line options and exit.
@@ -270,6 +275,10 @@ the previous line.
Make the 'Cut Text' command (normally ^K) cut from the current cursor
position to the end of the line, instead of cutting the entire line.
@item -l
@itemx --linenumbers
Display line numbers to the left of the text area.
@item -m
@itemx --mouse
Enable mouse support, if available for your system. When enabled, mouse
@@ -319,8 +328,8 @@ the @command{spell} program to be installed on your system.
@item -t
@itemx --tempfile
Don't ask whether or not to save the current contents of the file when
exiting, assume yes. This is most useful when using @command{nano} as the
Don't ask whether to save a modified buffer when exiting with ^X, but
assume yes. This option is useful when @command{nano} is used as the
composer of a mailer program.
@item -u
@@ -368,7 +377,6 @@ separately (e.g.@: @code{nano -wS -$}).
@itemx -b
@itemx -e
@itemx -f
@itemx -g
@itemx -j
Ignored, for compatibility with Pico.
@@ -592,6 +600,9 @@ toggles the @code{-z} (@code{--suspend}) command-line option.
@item Soft Wrapping Toggle (Meta-$)
toggles the @code{-$} (@code{--softwrap}) command-line option.
@item Line Numbers Toggle (Meta-#)
toggles the @code{-l} (@code{--linenumbers}) command-line option.
@end table
@@ -700,6 +711,9 @@ Specify the color combination to use for the shortcut key combos
in the two help lines at the bottom of the screen.
See @code{set titlecolor} for more details.
@item set linenumbers
Display line numbers to the left of the text area.
@item set locking
Enable vim-style lock-files for when editing files.
@@ -731,6 +745,10 @@ Don't add newlines to the ends of files.
@item set nowrap
Don't hard-wrap text at all.
@item set numbercolor @var{fgcolor},@var{bgcolor}
Specify the color combination to use for line numbers.
See @code{set titlecolor} for more details.
@item set operatingdir "directory"
@code{nano} will only read and write files inside "directory" and its
subdirectories. Also, the current directory is changed to here, so
@@ -782,6 +800,10 @@ won't work properly with this option enabled.
@item set regexp
Do extended regular expression searches by default.
@item set showcursor
Put the cursor on the highlighted item in the file browser, to aid
braille users.
@item set smarthome
Make the Home key smarter. When Home is pressed anywhere but at the
very beginning of non-whitespace characters on a line, the cursor will
@@ -1008,6 +1030,7 @@ a string in the current list in the file browser
@item searchagain
Repeats the last search command without prompting.
(The form 'research' is deprecated.)
@item findprevious
As @code{searchagain}, but always in the backward direction.
@@ -1042,6 +1065,7 @@ Cuts all text from the cursor position till the end of the buffer.
@item curpos
Shows the current cursor position: the line, column, and character positions.
(The form 'cursorpos' is deprecated.)
@item wordcount
Counts the number of words, lines and characters in the current buffer.
@@ -1171,6 +1195,7 @@ Toggles case sensitivity in searching (search/replace menus only).
@item regexp
Toggles whether searching/replacing is based on literal strings or regular expressions.
(The form 'regex' is deprecated.)
@item backwards
Toggles whether searching/replacing goes forward or backward.
@@ -1183,6 +1208,7 @@ Shows the next history entry in the prompt menus (e.g.@: search).
@item flipreplace
Toggles between searching for something and replacing something.
(The form 'dontreplace' is deprecated.)
@item flipexecute
Toggles between inserting a file and executing a command.
@@ -1190,6 +1216,7 @@ Toggles between inserting a file and executing a command.
@item flipnewbuffer
Toggles between inserting into the current buffer and into a new
empty buffer.
(The form 'newbuffer' is deprecated.)
@item dosformat
When writing a file, switches to writing a DOS format (CR/LF).
@@ -1294,6 +1321,7 @@ The 'search to replace' menu.
@item replacewith
The 'replace with' menu, which comes up after 'search to replace'.
(The form 'replace2' is deprecated.)
@item gotoline
The 'goto line (and column)' menu.
@@ -1491,7 +1519,7 @@ chances are you only want this feature when you're working on the nano source.
@item --disable-nls
Disables Native Language support. This will disable the use of any
available @code{nano} translations.
available GNU @code{nano} translations.
@item --disable-wrapping-as-root
Disable hard-wrapping of overlong lines by default when @code{nano}

View File

@@ -18,7 +18,7 @@ Requires(post) : info
Requires(preun) : info
%description
nano is a small and friendly text editor. It aims to emulate the
GNU nano is a small and friendly text editor. It aims to emulate the
Pico text editor while also offering several enhancements.
%prep

1029
po/bg.po

File diff suppressed because it is too large Load Diff

1051
po/ca.po

File diff suppressed because it is too large Load Diff

1188
po/cs.po

File diff suppressed because it is too large Load Diff

1258
po/da.po

File diff suppressed because it is too large Load Diff

1051
po/de.po

File diff suppressed because it is too large Load Diff

1051
po/eo.po

File diff suppressed because it is too large Load Diff

1049
po/es.po

File diff suppressed because it is too large Load Diff

1029
po/eu.po

File diff suppressed because it is too large Load Diff

1008
po/fi.po

File diff suppressed because it is too large Load Diff

1058
po/fr.po

File diff suppressed because it is too large Load Diff

1029
po/ga.po

File diff suppressed because it is too large Load Diff

1261
po/gl.po

File diff suppressed because it is too large Load Diff

1037
po/hr.po

File diff suppressed because it is too large Load Diff

1057
po/hu.po

File diff suppressed because it is too large Load Diff

1008
po/id.po

File diff suppressed because it is too large Load Diff

1069
po/it.po

File diff suppressed because it is too large Load Diff

1029
po/ja.po

File diff suppressed because it is too large Load Diff

1024
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1049
po/nb.po

File diff suppressed because it is too large Load Diff

1052
po/nl.po

File diff suppressed because it is too large Load Diff

1021
po/nn.po

File diff suppressed because it is too large Load Diff

1237
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1196
po/ro.po

File diff suppressed because it is too large Load Diff

1029
po/ru.po

File diff suppressed because it is too large Load Diff

1029
po/sl.po

File diff suppressed because it is too large Load Diff

1166
po/sr.po

File diff suppressed because it is too large Load Diff

1051
po/sv.po

File diff suppressed because it is too large Load Diff

1008
po/tr.po

File diff suppressed because it is too large Load Diff

1049
po/uk.po

File diff suppressed because it is too large Load Diff

View File

@@ -17,3 +17,10 @@ fi
echo "Regenerating POT file and remerging and recompiling PO files..."
make update-po
# Ensure that the PO files are newer than the POT.
touch *.po
# If needed, fix a problem in the Makefile template.
grep -q '^datarootdir' Makefile.in.in || \
sed -i 's/^\(datadir.*\)/datarootdir = @datarootdir@\n\1/' Makefile.in.in

1049
po/vi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,22 @@
/**************************************************************************
* browser.c *
* browser.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, *
* 2010, 2011, 2013, 2014, 2015 Free Software Foundation, Inc. *
* Copyright (C) 2015, 2016 Benno Schulenberg *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -60,7 +59,6 @@ char *do_browser(char *path)
/* Don't show a cursor in the file list. */
curs_set(0);
blank_statusbar();
read_directory_contents:
/* We come here when we refresh or select a new directory. */
@@ -149,7 +147,7 @@ char *do_browser(char *path)
/* If we selected the same filename as last time, fake a
* press of the Enter key so that the file is read in. */
if (old_selected == selected)
unget_kbinput(sc_seq_or(do_enter, 0), FALSE, FALSE);
unget_kbinput(sc_seq_or(do_enter, 0), FALSE);
}
continue;
@@ -504,6 +502,8 @@ void browser_refresh(void)
size_t i;
int line = 0, col = 0;
/* The current line and column while the list is getting displayed. */
int the_line = 0, the_column = 0;
/* The line and column of the selected item. */
char *info;
/* The additional information that we'll display about a file. */
@@ -523,28 +523,27 @@ void browser_refresh(void)
size_t infolen;
/* The length of the file information in columns. */
int infomaxlen = 7;
/* The maximum length of the file information in
* columns: seven for "--", "(dir)", or the file size,
* and 12 for "(parent dir)". */
/* 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);
/* Do we put an ellipsis before the filename? Don't set
* this to TRUE if we have fewer than 15 columns (i.e.
* one column for padding, plus seven columns for a
* filename other than ".."). */
char *disp = display_string(thename, dots ? namelen -
longest + infomaxlen + 4 : 0, longest, FALSE);
/* If we put an ellipsis before the filename, reserve
* one column for padding, plus seven columns for "--",
* "(dir)", or the file size, plus three columns for the
* ellipsis. */
/* Whether to put an ellipsis before the filename? We don't
* waste space on dots when there are fewer than 15 columns. */
char *disp = display_string(thename, dots ?
namelen + infomaxlen + 4 - longest : 0, longest, FALSE);
/* The filename (or a fragment of it) in displayable format.
* When a fragment, account for dots plus one space padding. */
/* Start highlighting the currently selected file or directory. */
if (i == selected)
/* If this is the selected item, start its highlighting, and
* remember its location to be able to place the cursor on it. */
if (i == selected) {
wattron(edit, hilite_attribute);
the_line = line;
the_column = col;
}
blank_line(edit, line, col, longest);
/* If dots is TRUE, we will display something like "...ename". */
/* If the name is too long, we display something like "...ename". */
if (dots)
mvwaddstr(edit, line, col, "...");
mvwaddstr(edit, line, dots ? col + 3 : col, disp);
@@ -553,21 +552,16 @@ void browser_refresh(void)
col += longest;
/* Show information about the file. We don't want to report
* file sizes for links, so we use lstat(). */
/* Show information about the file: "--" for symlinks (except when
* they point to a directory) and for files that have disappeared,
* "(dir)" for directories, and the file size for normal files. */
if (lstat(filelist[i], &st) == -1 || S_ISLNK(st.st_mode)) {
/* If the file doesn't exist (i.e. it's been deleted while
* the file browser is open), or it's a symlink that doesn't
* point to a directory, display "--". */
if (stat(filelist[i], &st) == -1 || !S_ISDIR(st.st_mode))
info = mallocstrcpy(NULL, "--");
/* If the file is a symlink that points to a directory,
* display it as a directory. */
else
/* TRANSLATORS: Try to keep this at most 7 characters. */
info = mallocstrcpy(NULL, _("(dir)"));
} else if (S_ISDIR(st.st_mode)) {
/* If the file is a directory, display it as such. */
if (strcmp(thename, "..") == 0) {
/* TRANSLATORS: Try to keep this at most 12 characters. */
info = mallocstrcpy(NULL, _("(parent dir)"));
@@ -580,6 +574,7 @@ void browser_refresh(void)
info = charalloc(infomaxlen + 1);
/* Massage the file size into a human-readable form. */
if (st.st_size < (1 << 10))
modifier = ' '; /* bytes */
else if (st.st_size < (1 << 20)) {
@@ -593,8 +588,7 @@ void browser_refresh(void)
modifier = 'G'; /* gigabytes */
}
/* Show the size if less than a terabyte,
* otherwise show "(huge)". */
/* Show the size if less than a terabyte, else show "(huge)". */
if (result < (1 << 10))
sprintf(info, "%4ju %cB", (intmax_t)result, modifier);
else
@@ -612,7 +606,7 @@ void browser_refresh(void)
mvwaddstr(edit, line, col - infolen, info);
/* Finish highlighting the currently selected file or directory. */
/* If this is the selected item, finish its highlighting. */
if (i == selected)
wattroff(edit, hilite_attribute);
@@ -627,8 +621,12 @@ void browser_refresh(void)
line++;
col = 0;
}
}
wmove(edit, line, col);
/* If requested, put the cursor on the selected item and switch it on. */
if (ISSET(SHOW_CURSOR)) {
wmove(edit, the_line, the_column);
curs_set(1);
}
wnoutrefresh(edit);
@@ -681,13 +679,13 @@ int filesearch_init(void)
/* This is now one simple call. It just does a lot. */
input = do_prompt(FALSE,
#ifndef DISABLE_TABCOMP
TRUE,
TRUE,
#endif
MWHEREISFILE, NULL,
MWHEREISFILE, NULL,
#ifndef DISABLE_HISTORIES
&search_history,
&search_history,
#endif
browser_refresh, "%s%s", _("Search"), buf);
browser_refresh, "%s%s", _("Search"), buf);
/* Release buf now that we don't need it anymore. */
free(buf);

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* chars.c *
* chars.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, *
* 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -93,6 +93,26 @@ void wctomb_reset(void)
IGNORE_CALL_RESULT(wctomb(NULL, 0));
}
/* This function is equivalent to isalpha() for multibyte characters. */
bool is_alpha_mbchar(const char *c)
{
assert(c != NULL);
#ifdef ENABLE_UTF8
if (use_utf8) {
wchar_t wc;
if (mbtowc(&wc, c, MB_CUR_MAX) < 0) {
mbtowc_reset();
return 0;
}
return iswalpha(wc);
} else
#endif
return isalpha((unsigned char)*c);
}
/* This function is equivalent to isalnum() for multibyte characters. */
bool is_alnum_mbchar(const char *c)
{
@@ -219,7 +239,7 @@ char control_rep(const signed char c)
/* An embedded newline is an encoded null. */
if (c == '\n')
return '@';
else if (c == NANO_CONTROL_8)
else if (c == DEL_CODE)
return '?';
else if (c == -97)
return '=';
@@ -236,7 +256,7 @@ char control_mbrep(const char *c)
#ifdef ENABLE_UTF8
if (use_utf8) {
if (0 <= c[0] && c[0] <= 127)
if ((unsigned char)c[0] < 128)
return control_rep(c[0]);
else
return control_rep(c[1]);
@@ -490,32 +510,40 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n)
if (use_utf8) {
wchar_t wc1, wc2;
if (s1 == s2)
return 0;
assert(s1 != NULL && s2 != NULL);
for (; *s1 != '\0' && *s2 != '\0' && n > 0;
s1 += move_mbright(s1, 0), s2 += move_mbright(s2, 0), n--) {
while (*s1 != '\0' && *s2 != '\0' && n > 0) {
bool bad1 = FALSE, bad2 = FALSE;
if (mbtowc(&wc1, s1, MB_CUR_MAX) < 0) {
mbtowc_reset();
wc1 = (unsigned char)*s1;
bad1 = TRUE;
}
if (mbtowc(&wc2, s2, MB_CUR_MAX) < 0) {
mbtowc_reset();
wc2 = (unsigned char)*s2;
bad2 = TRUE;
}
if (bad1 != bad2 || towlower(wc1) != towlower(wc2))
break;
if (bad1 || bad2) {
if (*s1 != *s2)
return (unsigned char)*s1 - (unsigned char)*s2;
if (bad1 != bad2)
return (bad1 ? 1 : -1);
} else {
int difference = towlower(wc1) - towlower(wc2);
if (difference != 0)
return difference;
}
s1 += move_mbright(s1, 0);
s2 += move_mbright(s2, 0);
n--;
}
return (n > 0) ? towlower(wc1) - towlower(wc2) : 0;
return (n > 0) ? ((unsigned char)*s1 - (unsigned char)*s2) : 0;
} else
#endif
return strncasecmp(s1, s2, n);
@@ -525,20 +553,20 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n)
/* This function is equivalent to strcasestr(). */
char *nstrcasestr(const char *haystack, const char *needle)
{
size_t haystack_len, needle_len;
size_t needle_len;
assert(haystack != NULL && needle != NULL);
if (*needle == '\0')
return (char *)haystack;
haystack_len = strlen(haystack);
needle_len = strlen(needle);
for (; *haystack != '\0' && haystack_len >= needle_len; haystack++,
haystack_len--) {
while (*haystack != '\0') {
if (strncasecmp(haystack, needle, needle_len) == 0)
return (char *)haystack;
haystack++;
}
return NULL;
@@ -550,21 +578,20 @@ char *mbstrcasestr(const char *haystack, const char *needle)
{
#ifdef ENABLE_UTF8
if (use_utf8) {
size_t haystack_len, needle_len;
size_t needle_len;
assert(haystack != NULL && needle != NULL);
if (*needle == '\0')
return (char *)haystack;
haystack_len = mbstrlen(haystack);
needle_len = mbstrlen(needle);
for (; *haystack != '\0' && haystack_len >= needle_len;
haystack += move_mbright(haystack, 0), haystack_len--) {
if (mbstrncasecmp(haystack, needle, needle_len) == 0 &&
mblen(haystack, MB_CUR_MAX) > 0)
while (*haystack != '\0') {
if (mbstrncasecmp(haystack, needle, needle_len) == 0)
return (char *)haystack;
haystack += move_mbright(haystack, 0);
}
return NULL;
@@ -573,7 +600,6 @@ char *mbstrcasestr(const char *haystack, const char *needle)
return (char *) strcasestr(haystack, needle);
}
#if !defined(NANO_TINY) || !defined(DISABLE_TABCOMP)
/* This function is equivalent to strstr(), except in that it scans the
* string in reverse, starting at rev_start. */
char *revstrstr(const char *haystack, const char *needle, const char
@@ -601,9 +627,7 @@ char *revstrstr(const char *haystack, const char *needle, const char
return NULL;
}
#endif /* !NANO_TINY || !DISABLE_TABCOMP */
#ifndef NANO_TINY
/* This function is equivalent to strcasestr(), except in that it scans
* the string in reverse, starting at rev_start. */
char *revstrcasestr(const char *haystack, const char *needle, const char
@@ -655,8 +679,7 @@ char *mbrevstrcasestr(const char *haystack, const char *needle, const
while (TRUE) {
if (rev_start_len >= needle_len &&
mbstrncasecmp(rev_start, needle, needle_len) == 0 &&
mblen(rev_start, MB_CUR_MAX) > 0)
mbstrncasecmp(rev_start, needle, needle_len) == 0)
return (char *)rev_start;
/* If we've reached the head of the haystack, we found nothing. */
@@ -670,7 +693,6 @@ char *mbrevstrcasestr(const char *haystack, const char *needle, const
#endif
return revstrcasestr(haystack, needle, rev_start);
}
#endif /* !NANO_TINY */
/* This function is equivalent to strlen() for multibyte strings. */
size_t mbstrlen(const char *s)

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* color.c *
* color.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, *
* 2010, 2011, 2013, 2014, 2015 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/

View File

@@ -1,22 +1,23 @@
/**************************************************************************
* cut.c *
* cut.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014 Mark Majeres *
* Copyright (C) 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -114,13 +115,7 @@ void cut_to_eof(void)
* copy_text is TRUE, copy the text back into the filestruct afterward.
* If cut_till_eof is TRUE, move all text from the current cursor
* position to the end of the file into the cutbuffer. */
void do_cut_text(
#ifndef NANO_TINY
bool copy_text, bool cut_till_eof
#else
void
#endif
)
void do_cut_text(bool copy_text, bool cut_till_eof)
{
#ifndef NANO_TINY
filestruct *cb_save = NULL;
@@ -220,10 +215,10 @@ void do_cut_text_void(void)
{
#ifndef NANO_TINY
add_undo(CUT);
#endif
do_cut_text(FALSE, FALSE);
#ifndef NANO_TINY
update_undo(CUT);
#else
do_cut_text();
#endif
}

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* files.c *
* files.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -51,6 +51,8 @@ bool has_valid_path(const char *filename)
statusline(ALERT, _("Path '%s' is not a directory"), parentdir);
else if (access(parentdir, X_OK) == -1)
statusline(ALERT, _("Path '%s' is not accessible"), parentdir);
else if (ISSET(LOCKING) && access(parentdir, W_OK) == -1)
statusline(MILD, _("Directory '%s' is not writable"), parentdir);
else
validity = TRUE;
@@ -98,6 +100,7 @@ void make_new_buffer(void)
openfile->mark_set = FALSE;
openfile->mark_begin = NULL;
openfile->mark_begin_x = 0;
openfile->kind_of_mark = SOFTMARK;
openfile->fmt = NIX_FILE;
@@ -232,8 +235,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
* byte 0 - 0x62
* byte 1 - 0x30
* bytes 2-12 - program name which created the lock
* bytes 24,25 - little endian store of creator program's PID
* (b24 = 256^0 column, b25 = 256^1 column)
* bytes 24-27 - PID (little endian) of creator process
* bytes 28-44 - username of who created the lock
* bytes 68-100 - hostname of where the lock was created
* bytes 108-876 - filename the lock is for
@@ -248,7 +250,9 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
lockdata[0] = 0x62;
lockdata[1] = 0x30;
lockdata[24] = mypid % 256;
lockdata[25] = mypid / 256;
lockdata[25] = (mypid / 256) % 256;
lockdata[26] = (mypid / (256 * 256)) % 256;
lockdata[27] = mypid / (256 * 256 * 256);
snprintf(&lockdata[2], 11, "nano %s", VERSION);
strncpy(&lockdata[28], mypwuid->pw_name, 16);
strncpy(&lockdata[68], myhostname, 31);
@@ -260,7 +264,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
wroteamt = fwrite(lockdata, sizeof(char), lockdatalen, filestream);
if (wroteamt < lockdatalen) {
statusline(MILD, _("Error writing lock file %s: %s"),
lockfilename, ferror(filestream));
lockfilename, ferror(filestream));
goto free_the_data;
}
@@ -270,7 +274,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
if (fclose(filestream) == EOF) {
statusline(MILD, _("Error writing lock file %s: %s"),
lockfilename, strerror(errno));
lockfilename, strerror(errno));
goto free_the_data;
}
@@ -318,7 +322,7 @@ int do_lockfile(const char *filename)
if (stat(lockfilename, &fileinfo) != -1) {
ssize_t readtot = 0;
ssize_t readamt = 0;
char *lockbuf, *question, *postedname, *promptstr;
char *lockbuf, *question, *pidstring, *postedname, *promptstr;
int room, response;
if ((lockfd = open(lockfilename, O_RDONLY)) < 0) {
@@ -333,6 +337,8 @@ int do_lockfile(const char *filename)
readtot += readamt;
} while (readamt > 0 && readtot < LOCKBUFSIZE);
close(lockfd);
if (readtot < 48) {
statusline(MILD, _("Error reading lock file %s: "
"Not enough data read"), lockfilename);
@@ -341,18 +347,23 @@ int do_lockfile(const char *filename)
}
strncpy(lockprog, &lockbuf[2], 10);
lockpid = (unsigned char)lockbuf[25] * 256 + (unsigned char)lockbuf[24];
lockpid = (((unsigned char)lockbuf[27] * 256 + (unsigned char)lockbuf[26]) * 256 +
(unsigned char)lockbuf[25]) * 256 + (unsigned char)lockbuf[24];
strncpy(lockuser, &lockbuf[28], 16);
free(lockbuf);
pidstring = charalloc(11);
sprintf (pidstring, "%u", (unsigned int)lockpid);
#ifdef DEBUG
fprintf(stderr, "lockpid = %d\n", lockpid);
fprintf(stderr, "program name which created this lock file should be %s\n", lockprog);
fprintf(stderr, "user which created this lock file should be %s\n", lockuser);
#endif
/* TRANSLATORS: The second %s is the name of the user, the third that of the editor. */
question = _("File %s is being edited (by %s with %s, PID %d); continue?");
room = COLS - strlenpt(question) - strlenpt(lockuser) - strlenpt(lockprog) + 3;
question = _("File %s is being edited (by %s with %s, PID %s); continue?");
room = COLS - strlenpt(question) + 7 - strlenpt(lockuser) -
strlenpt(lockprog) - strlenpt(pidstring);
if (room < 4)
postedname = mallocstrcpy(NULL, "_");
else if (room < strlenpt(filename)) {
@@ -365,11 +376,12 @@ int do_lockfile(const char *filename)
} else
postedname = mallocstrcpy(NULL, filename);
/* Allow extra space for username (14), program name (8), PID (3),
/* Allow extra space for username (14), program name (8), PID (8),
* and terminating \0 (1), minus the %s (2) for the file name. */
promptstr = charalloc(strlen(question) + 24 + strlen(postedname));
sprintf(promptstr, question, postedname, lockuser, lockprog, lockpid);
promptstr = charalloc(strlen(question) + 29 + strlen(postedname));
sprintf(promptstr, question, postedname, lockuser, lockprog, pidstring);
free(postedname);
free(pidstring);
response = do_yesno_prompt(FALSE, promptstr);
free(promptstr);
@@ -555,8 +567,7 @@ void display_buffer(void)
precalc_multicolorinfo();
#endif
/* Update the edit window. */
edit_refresh();
refresh_needed = TRUE;
}
#ifndef DISABLE_MULTIBUFFER
@@ -827,7 +838,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable, bool checkw
if (len > 0) {
#ifndef NANO_TINY
/* If file conversion isn't disabled and the last character in
* this file is '\r', set format to Mac if we currently think
* This file is '\r', set format to Mac if we currently think
* the file is a *nix file, or to both DOS and Mac if we
* currently think the file is a DOS file. */
if (buf[len - 1] == '\r' && !ISSET(NO_CONVERT) && format < 2)
@@ -900,39 +911,37 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable, bool checkw
* file we inserted. */
openfile->placewewant = xplustabs();
#ifndef NANO_TINY
if (undoable)
update_undo(INSERT);
if (!writable)
statusline(ALERT, "File '%s' is unwritable", filename);
#ifndef NANO_TINY
else if (format == 3) {
statusline(HUSH,
/* TRANSLATORS: Keep the next four messages at most 76 characters. */
P_("Read %lu line (Converted from DOS and Mac format)",
"Read %lu lines (Converted from DOS and Mac format)",
(unsigned long)num_lines), (unsigned long)num_lines);
/* TRANSLATORS: Keep the next four messages at most 78 characters. */
statusline(HUSH, P_("Read %lu line (Converted from DOS and Mac format)",
"Read %lu lines (Converted from DOS and Mac format)",
(unsigned long)num_lines), (unsigned long)num_lines);
} else if (format == 2) {
openfile->fmt = MAC_FILE;
statusline(HUSH,
P_("Read %lu line (Converted from Mac format)",
"Read %lu lines (Converted from Mac format)",
(unsigned long)num_lines), (unsigned long)num_lines);
statusline(HUSH, P_("Read %lu line (Converted from Mac format)",
"Read %lu lines (Converted from Mac format)",
(unsigned long)num_lines), (unsigned long)num_lines);
} else if (format == 1) {
openfile->fmt = DOS_FILE;
statusline(HUSH,
P_("Read %lu line (Converted from DOS format)",
"Read %lu lines (Converted from DOS format)",
(unsigned long)num_lines), (unsigned long)num_lines);
} else
#endif /* !NANO_TINY */
statusline(HUSH, P_("Read %lu line", "Read %lu lines",
(unsigned long)num_lines), (unsigned long)num_lines);
statusline(HUSH, P_("Read %lu line (Converted from DOS format)",
"Read %lu lines (Converted from DOS format)",
(unsigned long)num_lines), (unsigned long)num_lines);
}
#endif
else
statusline(HUSH, P_("Read %lu line", "Read %lu lines",
(unsigned long)num_lines), (unsigned long)num_lines);
if (num_lines < editwinrows)
focusing = FALSE;
#ifndef NANO_TINY
if (undoable)
update_undo(INSERT);
if (ISSET(MAKE_IT_UNIX))
openfile->fmt = NIX_FILE;
#endif
@@ -959,7 +968,7 @@ int open_file(const char *filename, bool newfie, bool quiet, FILE **f)
/* Okay, if we can't stat the path due to a component's
* permissions, just try the relative one. */
if (full_filename == NULL || (stat(full_filename, &fileinfo) == -1 &&
stat(filename, &fileinfo2) != -1))
stat(filename, &fileinfo2) != -1))
full_filename = mallocstrcpy(full_filename, filename);
if (stat(full_filename, &fileinfo) == -1) {
@@ -1049,48 +1058,36 @@ char *get_next_filename(const char *name, const char *suffix)
return buf;
}
/* Insert a file into a new buffer if the MULTIBUFFER flag is set, or
* into the current buffer if it isn't. If execute is TRUE, insert the
* output of an executed command instead of a file. */
void do_insertfile(
#ifndef NANO_TINY
bool execute
#else
void
#endif
)
/* Insert a file into the current buffer, or into a new buffer when
* the MULTIBUFFER flag is set. */
void do_insertfile(void)
{
int i;
const char *msg;
char *given = mallocstrcpy(NULL, "");
/* The last answer the user typed at the statusbar prompt. */
filestruct *edittop_save = openfile->edittop;
ssize_t was_current_lineno = openfile->current->lineno;
size_t was_current_x = openfile->current_x;
ssize_t was_current_y = openfile->current_y;
bool edittop_inside = FALSE;
#ifndef NANO_TINY
bool right_side_up = FALSE, single_line = FALSE;
bool execute = FALSE, right_side_up = FALSE, single_line = FALSE;
#endif
while (TRUE) {
#ifndef NANO_TINY
if (execute) {
msg =
#ifndef DISABLE_MULTIBUFFER
ISSET(MULTIBUFFER) ?
_("Command to execute in new buffer [from %s] ") :
if (ISSET(MULTIBUFFER))
msg = _("Command to execute in new buffer [from %s] ");
else
#endif
_("Command to execute [from %s] ");
msg = _("Command to execute [from %s] ");
} else
#endif /* NANO_TINY */
{
msg =
#ifndef DISABLE_MULTIBUFFER
ISSET(MULTIBUFFER) ?
_("File to insert into new buffer [from %s] ") :
if (ISSET(MULTIBUFFER))
msg = _("File to insert into new buffer [from %s] ");
else
#endif
_("File to insert [from %s] ");
msg = _("File to insert [from %s] ");
}
present_path = mallocstrcpy(present_path, "./");
@@ -1108,8 +1105,8 @@ void do_insertfile(
#endif
edit_refresh, msg,
#ifndef DISABLE_OPERATINGDIR
operating_dir != NULL && strcmp(operating_dir,
".") != 0 ? operating_dir :
operating_dir != NULL && strcmp(operating_dir, ".") != 0 ?
operating_dir :
#endif
"./");
@@ -1117,14 +1114,15 @@ void do_insertfile(
* blank, open a new buffer instead of canceling. If the
* filename or command begins with a newline (i.e. an encoded
* null), treat it as though it's blank. */
if (i == -1 || ((i == -2 || *answer == '\n')
#ifndef DISABLE_MULTIBUFFER
&& !ISSET(MULTIBUFFER)
#endif
)) {
if (i == -1 || (!ISSET(MULTIBUFFER) && (i == -2 || *answer == '\n'))) {
statusbar(_("Cancelled"));
break;
} else {
filestruct *edittop_save = openfile->edittop;
ssize_t was_current_lineno = openfile->current->lineno;
size_t was_current_x = openfile->current_x;
ssize_t was_current_y = openfile->current_y;
bool current_was_at_top = FALSE;
size_t pww_save = openfile->placewewant;
#if !defined(NANO_TINY) || !defined(DISABLE_BROWSER)
functionptrtype func = func_from_key(&i);
@@ -1134,7 +1132,7 @@ void do_insertfile(
#ifndef NANO_TINY
#ifndef DISABLE_MULTIBUFFER
if (func == new_buffer_void) {
/* Don't allow toggling if we're in view mode. */
/* Don't allow toggling when in view mode. */
if (!ISSET(VIEW_MODE))
TOGGLE(MULTIBUFFER);
else
@@ -1152,21 +1150,17 @@ void do_insertfile(
if (func == to_files_void) {
char *chosen = do_browse_from(answer);
/* If no file was chosen, go back to the prompt. */
if (chosen == NULL)
continue;
/* We have a file now. Indicate this. */
free(answer);
answer = chosen;
i = 0;
}
#endif
/* If we don't have a file yet, go back to the statusbar prompt. */
if (i != 0
#ifndef DISABLE_MULTIBUFFER
&& (i != -2 || !ISSET(MULTIBUFFER))
#endif
)
/* If we don't have a file yet, go back to the prompt. */
if (i != 0 && (!ISSET(MULTIBUFFER) || i != -2))
continue;
#ifndef NANO_TINY
@@ -1182,19 +1176,14 @@ void do_insertfile(
single_line = (top == bot);
}
#endif
#ifndef DISABLE_MULTIBUFFER
if (!ISSET(MULTIBUFFER))
#endif
{
/* If we're not inserting into a new buffer, partition
* the filestruct so that it contains no text and hence
* looks like a new buffer, and keep track of whether
* the top of the edit window is inside the partition. */
/* When not inserting into a new buffer, partition the filestruct
* so that it contains no text and hence looks like a new buffer,
* and remember whether the current line is the first on screen. */
if (!ISSET(MULTIBUFFER)) {
filepart = partition_filestruct(openfile->current,
openfile->current_x, openfile->current,
openfile->current_x);
edittop_inside = (openfile->edittop == openfile->fileage);
current_was_at_top = (openfile->edittop == openfile->fileage);
}
/* Convert newlines to nulls in the given filename. */
@@ -1204,21 +1193,21 @@ void do_insertfile(
#ifndef NANO_TINY
if (execute) {
#ifndef DISABLE_MULTIBUFFER
/* When in multibuffer mode, first open a blank buffer. */
if (ISSET(MULTIBUFFER))
/* Open a blank buffer. */
open_buffer("", FALSE);
#endif
/* Save the command's output in the current buffer. */
execute_command(answer);
#ifndef DISABLE_MULTIBUFFER
/* If this is a new buffer, put the cursor at the top. */
if (ISSET(MULTIBUFFER)) {
/* Move back to the beginning of the first line of
* the buffer. */
openfile->current = openfile->fileage;
openfile->current_x = 0;
openfile->placewewant = 0;
set_modified();
}
#endif
} else
@@ -1244,17 +1233,16 @@ void do_insertfile(
do_gotolinecolumn(priorline, priorcol, FALSE, FALSE);
}
#endif /* !DISABLE_HISTORIES */
/* Update the screen to account for the current buffer. */
/* Update stuff to account for the current buffer. */
display_buffer();
} else
#endif /* !DISABLE_MULTIBUFFER */
{
filestruct *top_save = openfile->fileage;
/* If we were at the top of the edit window before, set
* the saved value of edittop to the new top of the edit
* window. */
if (edittop_inside)
/* If we were at the top of the edit window before, change the
* saved value of edittop to the start of inserted stuff. */
if (current_was_at_top)
edittop_save = openfile->fileage;
/* Update the current x-coordinate to account for the
@@ -1284,7 +1272,6 @@ void do_insertfile(
}
}
#endif
/* Update the current y-coordinate to account for the
* number of lines inserted. */
openfile->current_y += was_current_y;
@@ -1310,8 +1297,7 @@ void do_insertfile(
openfile->current_x != was_current_x)
set_modified();
/* Update the screen. */
edit_refresh();
refresh_needed = TRUE;
}
break;
@@ -1336,11 +1322,7 @@ void do_insertfile_void(void)
statusbar(_("Key invalid in non-multibuffer mode"));
else
#endif
do_insertfile(
#ifndef NANO_TINY
FALSE
#endif
);
do_insertfile();
}
/* When passed "[relative path]" or "[relative path][filename]" in
@@ -2928,8 +2910,8 @@ char *histfilename(void)
return construct_filename("/.nano/search_history");
}
/* Construct the legacy history filename.
* (Deprecate in 2.5, delete later.) */
/* Construct the legacy history filename. */
/* (To be removed in 2018.) */
char *legacyhistfilename(void)
{
return construct_filename("/.nano_history");
@@ -2989,6 +2971,8 @@ void load_history(void)
char *legacyhist = legacyhistfilename();
struct stat hstat;
/* If there is an old history file, migrate it. */
/* (To be removed in 2018.) */
if (stat(legacyhist, &hstat) != -1 && stat(nanohist, &hstat) == -1) {
if (rename(legacyhist, nanohist) == -1)
history_error(N_("Detected a legacy nano history file (%s) which I tried to move\n"

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* global.c *
* global.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -33,21 +33,36 @@ volatile sig_atomic_t sigwinch_counter = 0;
/* Is incremented by the handler whenever a SIGWINCH occurs. */
#endif
#ifdef __linux__
bool console;
/* Whether we're running on a Linux VC (TRUE) or under X (FALSE). */
#endif
bool meta_key;
/* Whether the current keystroke is a Meta key. */
bool func_key;
/* Whether the current keystroke is an extended keypad value. */
bool shift_held;
/* Whether Shift was being held together with a movement key. */
bool focusing = TRUE;
/* Whether an update of the edit window should center the cursor. */
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. */
#ifdef ENABLE_LINENUMBERS
int last_drawn_line = 0;
/* The line number of the last drawn line. */
int last_line_y;
/* The y coordinate of the last drawn line. */
#endif
message_type lastmessage = HUSH;
/* Messages of type HUSH should not overwrite type MILD nor ALERT. */
int controlleft, controlright, controlup, controldown;
#ifndef NANO_TINY
int controlleft = CONTROL_LEFT;
int controlright = CONTROL_RIGHT;
int controlup = CONTROL_UP;
int controldown = CONTROL_DOWN;
int shiftcontrolleft, shiftcontrolright, shiftcontrolup, shiftcontroldown;
int shiftaltleft, shiftaltright, shiftaltup, shiftaltdown;
#endif
#ifndef DISABLE_WRAPJUSTIFY
@@ -85,13 +100,9 @@ int maxrows = 0;
filestruct *cutbuffer = NULL;
/* The buffer where we store cut text. */
filestruct *cutbottom = NULL;
#ifndef DISABLE_JUSTIFY
filestruct *jusbuffer = NULL;
/* The buffer where we store unjustified text. */
#endif
/* The last line in the cutbuffer. */
partition *filepart = NULL;
/* The partition where we store a portion of the current
* file. */
/* The "partition" where we store a portion of the current file. */
openfilestruct *openfile = NULL;
/* The list of all open file buffers. */
@@ -124,7 +135,7 @@ char *quoteerr = NULL;
size_t quotelen;
/* The length of the quoting string in bytes. */
#endif
#endif
#endif /* !DISABLE_JUSTIFY */
char *word_chars = NULL;
/* Nonalphanumeric characters that also form words. */
@@ -136,8 +147,7 @@ char *answer = NULL;
/* The answer string used by the statusbar prompt. */
ssize_t tabsize = -1;
/* The width of a tab in spaces. The default value is set in
* main(). */
/* The width of a tab in spaces. The default is set in main(). */
#ifndef NANO_TINY
char *backup_dir = NULL;
@@ -175,15 +185,15 @@ bool refresh_needed = FALSE;
int currmenu = MMOST;
/* The currently active menu, initialized to a dummy value. */
sc *sclist = NULL;
/* Pointer to the start of the shortcuts list. */
/* The start of the shortcuts list. */
subnfunc *allfuncs = NULL;
/* Pointer to the start of the functions list. */
/* The start of the functions list. */
subnfunc *tailfunc;
/* Pointer to the last function in the list. */
/* The last function in the list. */
subnfunc *exitfunc;
/* Pointer to the special Exit/Close item. */
/* A pointer to the special Exit/Close item. */
subnfunc *uncutfunc;
/* Pointer to the special Uncut/Unjustify item. */
/* A pointer to the special Uncut/Unjustify item. */
#ifndef DISABLE_HISTORIES
filestruct *search_history = NULL;
@@ -202,7 +212,6 @@ poshiststruct *position_history = NULL;
/* The cursor position history list. */
#endif
/* Regular expressions. */
#ifdef HAVE_REGEX_H
regex_t search_regexp;
/* The compiled regular expression to use in searches. */
@@ -212,7 +221,7 @@ regmatch_t regmatches[10];
#endif
int hilite_attribute = A_REVERSE;
/* The curses attribute we use for reverse video. */
/* The curses attribute we use to highlight something. */
#ifndef DISABLE_COLOR
char* specified_color_combo[] = {};
/* The color combinations as specified in the rcfile. */
@@ -223,6 +232,7 @@ int interface_color_pair[] = {};
char *homedir = NULL;
/* The user's home directory, from $HOME or /etc/passwd. */
/* Return the number of entries in the shortcut list for a given menu. */
size_t length_of_list(int menu)
{
@@ -230,9 +240,9 @@ size_t length_of_list(int menu)
size_t i = 0;
for (f = allfuncs; f != NULL; f = f->next)
if ((f->menus & menu) != 0) {
if ((f->menus & menu) && first_sc_for(menu, f->scfunc) != NULL)
i++;
}
return i;
}
@@ -319,10 +329,13 @@ void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *h
}
/* Add a key combo to the shortcut list. */
void add_to_sclist(int menus, const char *scstring, void (*func)(void), int toggle)
void add_to_sclist(int menus, const char *scstring, const int keycode,
void (*func)(void), int toggle)
{
static sc *tailsc;
#ifndef NANO_TINY
static int counter = 0;
#endif
sc *s = (sc *)nmalloc(sizeof(sc));
/* Start the list, or tack on the next item. */
@@ -336,15 +349,15 @@ void add_to_sclist(int menus, const char *scstring, void (*func)(void), int togg
/* Fill in the data. */
s->menus = menus;
s->scfunc = func;
#ifndef NANO_TINY
s->toggle = toggle;
if (toggle)
s->ordinal = ++counter;
s->keystr = (char *) scstring;
s->type = strtokeytype(scstring);
assign_keyinfo(s);
#endif
assign_keyinfo(s, scstring, keycode);
#ifdef DEBUG
fprintf(stderr, "Setting sequence to %d for shortcut \"%s\" in menus %x\n", s->seq, scstring, s->menus);
fprintf(stderr, "Setting keycode to %d for shortcut \"%s\" in menus %x\n", s->keycode, scstring, s->menus);
#endif
}
@@ -382,8 +395,8 @@ int sc_seq_or(void (*func)(void), int defaultval)
const sc *s = first_sc_for(currmenu, func);
if (s) {
meta_key = (s->type == META);
return s->seq;
meta_key = s->meta;
return s->keycode;
}
/* else */
return defaultval;
@@ -400,71 +413,32 @@ functionptrtype func_from_key(int *kbinput)
return NULL;
}
/* Return the type of command key based on the given string. */
key_type strtokeytype(const char *str)
/* Set the string and its corresponding keycode for the given shortcut s. */
void assign_keyinfo(sc *s, const char *keystring, const int keycode)
{
if (str[0] == '^')
return CONTROL;
else if (str[0] == 'M')
return META;
else if (str[0] == 'F')
return FKEY;
else
return RAWINPUT;
}
s->keystr = keystring;
s->meta = (keystring[0] == 'M');
/* Assign the info to the shortcut struct.
* Assumes keystr is already assigned, naturally. */
void assign_keyinfo(sc *s)
{
if (s->type == CONTROL) {
assert(strlen(s->keystr) > 1);
s->seq = s->keystr[1] - 64;
} else if (s->type == META) {
assert(strlen(s->keystr) > 2);
s->seq = tolower((int) s->keystr[2]);
} else if (s->type == FKEY) {
assert(strlen(s->keystr) > 1);
s->seq = KEY_F0 + atoi(&s->keystr[1]);
} else /* RAWINPUT */
s->seq = (int) s->keystr[0];
assert(strlen(keystring) > 1 && (!s->meta || strlen(keystring) > 2));
/* Override some keys which don't bind as easily as we'd like. */
if (s->type == CONTROL && (!strcasecmp(&s->keystr[1], "space")))
s->seq = 0;
else if (s->type == META && (!strcasecmp(&s->keystr[2], "space")))
s->seq = (int) ' ';
else if (s->type == RAWINPUT) {
if (!strcasecmp(s->keystr, "Up"))
s->seq = KEY_UP;
else if (!strcasecmp(s->keystr, "Down"))
s->seq = KEY_DOWN;
else if (!strcasecmp(s->keystr, "Left"))
s->seq = KEY_LEFT;
else if (!strcasecmp(s->keystr, "Right"))
s->seq = KEY_RIGHT;
else if (!strcasecmp(s->keystr, "Ins"))
s->seq = KEY_IC;
else if (!strcasecmp(s->keystr, "Del"))
s->seq = KEY_DC;
else if (!strcasecmp(s->keystr, "Bsp"))
s->seq = KEY_BACKSPACE;
/* The Tab and Enter keys don't actually produce special codes
* but the exact integer values of ^I and ^M. Rebinding the
* latter therefore also rebinds Tab and Enter. */
else if (!strcasecmp(s->keystr, "Tab"))
s->seq = NANO_CONTROL_I;
else if (!strcasecmp(s->keystr, "Enter"))
s->seq = KEY_ENTER;
else if (!strcasecmp(s->keystr, "PgUp"))
s->seq = KEY_PPAGE;
else if (!strcasecmp(s->keystr, "PgDn"))
s->seq = KEY_NPAGE;
else if (!strcasecmp(s->keystr, "Home"))
s->seq = KEY_HOME;
else if (!strcasecmp(s->keystr, "End"))
s->seq = KEY_END;
}
if (keycode)
s->keycode = keycode;
else if (keystring[0] == '^') {
if (strcasecmp(keystring, "^Space") == 0)
s->keycode = 0;
else
s->keycode = keystring[1] - 64;
} else if (s->meta) {
if (strcasecmp(keystring, "M-Space") == 0)
s->keycode = (int)' ';
else
s->keycode = tolower((int)keystring[2]);
} else if (keystring[0] == 'F')
s->keycode = KEY_F0 + atoi(&keystring[1]);
else if (!strcasecmp(keystring, "Ins"))
s->keycode = KEY_IC;
else if (!strcasecmp(keystring, "Del"))
s->keycode = KEY_DC;
}
#ifdef DEBUG
@@ -508,10 +482,8 @@ void shortcut_init(void)
const char *fulljustify_tag = N_("FullJstify");
#endif
const char *refresh_tag = N_("Refresh");
#ifndef NANO_TINY
/* TRANSLATORS: Try to keep this string at most 12 characters. */
const char *whereis_next_tag = N_("WhereIs Next");
#endif
#ifndef DISABLE_HELP
#ifndef DISABLE_JUSTIFY
@@ -567,18 +539,14 @@ void shortcut_init(void)
#endif
const char *nano_back_msg = N_("Go back one character");
const char *nano_forward_msg = N_("Go forward one character");
#ifndef NANO_TINY
const char *nano_prevword_msg = N_("Go back one word");
const char *nano_nextword_msg = N_("Go forward one word");
#endif
const char *nano_prevline_msg = N_("Go to previous line");
const char *nano_nextline_msg = N_("Go to next line");
const char *nano_home_msg = N_("Go to beginning of current line");
const char *nano_end_msg = N_("Go to end of current line");
#ifndef NANO_TINY
const char *nano_prevblock_msg = N_("Go to previous block of text");
const char *nano_nextblock_msg = N_("Go to next block of text");
#endif
#ifndef DISABLE_JUSTIFY
const char *nano_parabegin_msg =
N_("Go to beginning of paragraph; then of previous paragraph");
@@ -779,20 +747,25 @@ void shortcut_init(void)
#endif
}
#ifndef NANO_TINY
add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
N_("Case Sens"), IFSCHELP(nano_case_msg), TOGETHER, VIEW);
add_to_funcs(do_cursorpos_void, MMAIN,
N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg), TOGETHER, VIEW);
#if (!defined(DISABLE_JUSTIFY) && (!defined(DISABLE_SPELLER) || !defined(DISABLE_COLOR)) || \
defined(DISABLE_JUSTIFY) && defined(DISABLE_SPELLER) && defined(DISABLE_COLOR))
/* Conditionally placing this one here or further on, to keep the
* help items nicely paired in most conditions. */
add_to_funcs(do_gotolinecolumn_void, MMAIN,
gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
#endif
add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
N_("Case Sens"), IFSCHELP(nano_case_msg), TOGETHER, VIEW);
#ifdef HAVE_REGEX_H
add_to_funcs(regexp_void, MWHEREIS|MREPLACE,
N_("Regexp"), IFSCHELP(nano_regexp_msg), TOGETHER, VIEW);
#endif
#ifndef NANO_TINY
add_to_funcs(backwards_void, MWHEREIS|MREPLACE,
N_("Backwards"), IFSCHELP(nano_reverse_msg), TOGETHER, VIEW);
#endif
add_to_funcs(flip_replace_void, MWHEREIS,
replace_tag, IFSCHELP(nano_replace_msg), BLANKAFTER, VIEW);
@@ -803,15 +776,8 @@ void shortcut_init(void)
#ifndef DISABLE_JUSTIFY
add_to_funcs(do_full_justify, MWHEREIS,
fulljustify_tag, IFSCHELP(nano_fulljustify_msg), TOGETHER, NOVIEW);
#endif
add_to_funcs(do_cursorpos_void, MMAIN,
N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg), TOGETHER, VIEW);
#if defined(DISABLE_COLOR) || !defined(DISABLE_JUSTIFY)
/* Conditionally placing this one here or further on, to keep the
* help items nicely paired in most conditions. */
add_to_funcs(do_gotolinecolumn_void, MMAIN|MWHEREIS,
add_to_funcs(do_gotolinecolumn_void, MWHEREIS,
gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
#endif
@@ -861,12 +827,10 @@ void shortcut_init(void)
N_("Forward"), IFSCHELP(nano_forwardfile_msg), TOGETHER, VIEW);
#endif
#ifndef NANO_TINY
add_to_funcs(do_prev_word_void, MMAIN,
N_("Prev Word"), IFSCHELP(nano_prevword_msg), TOGETHER, VIEW);
add_to_funcs(do_next_word_void, MMAIN,
N_("Next Word"), IFSCHELP(nano_nextword_msg), TOGETHER, VIEW);
#endif
add_to_funcs(do_home, MMAIN,
N_("Home"), IFSCHELP(nano_home_msg), TOGETHER, VIEW);
@@ -878,12 +842,10 @@ void shortcut_init(void)
add_to_funcs(do_down_void, MMAIN|MBROWSER,
next_line_tag, IFSCHELP(nano_nextline_msg), BLANKAFTER, VIEW);
#ifndef NANO_TINY
add_to_funcs(do_prev_block, MMAIN,
N_("Prev Block"), IFSCHELP(nano_prevblock_msg), TOGETHER, VIEW);
add_to_funcs(do_next_block, MMAIN,
N_("Next Block"), IFSCHELP(nano_nextblock_msg), TOGETHER, VIEW);
#endif
#ifndef DISABLE_JUSTIFY
add_to_funcs(do_para_begin_void, MMAIN|MWHEREIS,
@@ -906,11 +868,18 @@ void shortcut_init(void)
N_("Next File"), IFSCHELP(nano_nextfile_msg), BLANKAFTER, VIEW);
#endif
#if !defined(DISABLE_COLOR) && defined(DISABLE_JUSTIFY)
#if (defined(DISABLE_JUSTIFY) && (!defined(DISABLE_SPELLER) || !defined(DISABLE_COLOR)) || \
!defined(DISABLE_JUSTIFY) && defined(DISABLE_SPELLER) && defined(DISABLE_COLOR))
add_to_funcs(do_gotolinecolumn_void, MMAIN,
gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
#endif
#ifdef NANO_TINY
/* Place this one here only in the tiny version; otherwise further up. */
add_to_funcs(do_research, MMAIN,
whereis_next_tag, IFSCHELP(nano_whereis_next_msg), TOGETHER, VIEW);
#endif
add_to_funcs(do_verbatim_input, MMAIN,
N_("Verbatim"), IFSCHELP(nano_verbatim_msg), TOGETHER, NOVIEW);
@@ -979,7 +948,7 @@ void shortcut_init(void)
N_("NextHstory"), IFSCHELP(nano_next_history_msg), BLANKAFTER, VIEW);
#endif
#if !defined(DISABLE_COLOR) && defined(DISABLE_JUSTIFY)
#ifdef DISABLE_JUSTIFY
add_to_funcs(do_gotolinecolumn_void, MWHEREIS,
gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
#endif
@@ -1067,224 +1036,241 @@ void shortcut_init(void)
/* Start associating key combos with functions in specific menus. */
add_to_sclist(MMOST, "^G", do_help_void, 0);
add_to_sclist(MMOST, "F1", do_help_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", do_exit, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", do_exit, 0);
add_to_sclist(MMAIN, "^O", do_writeout_void, 0);
add_to_sclist(MMAIN, "F3", do_writeout_void, 0);
add_to_sclist(MMAIN, "^R", do_insertfile_void, 0);
add_to_sclist(MMAIN, "F5", do_insertfile_void, 0);
add_to_sclist(MMAIN, "Ins", do_insertfile_void, 0);
add_to_sclist(MMAIN|MBROWSER, "^W", do_search, 0);
add_to_sclist(MMAIN|MBROWSER, "F6", do_search, 0);
add_to_sclist(MMAIN, "^\\", do_replace, 0);
add_to_sclist(MMAIN, "M-R", do_replace, 0);
add_to_sclist(MMAIN, "F14", do_replace, 0);
add_to_sclist(MMOST, "^K", do_cut_text_void, 0);
add_to_sclist(MMOST, "F9", do_cut_text_void, 0);
add_to_sclist(MMAIN, "^U", do_uncut_text, 0);
add_to_sclist(MMAIN, "F10", do_uncut_text, 0);
add_to_sclist(MMOST, "^G", 0, do_help_void, 0);
add_to_sclist(MMOST, "F1", 0, do_help_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", 0, do_exit, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", 0, do_exit, 0);
add_to_sclist(MMAIN, "^O", 0, do_writeout_void, 0);
add_to_sclist(MMAIN, "F3", 0, do_writeout_void, 0);
add_to_sclist(MMAIN, "^R", 0, do_insertfile_void, 0);
add_to_sclist(MMAIN, "F5", 0, do_insertfile_void, 0);
add_to_sclist(MMAIN, "Ins", 0, do_insertfile_void, 0);
add_to_sclist(MMAIN|MBROWSER, "^W", 0, do_search, 0);
add_to_sclist(MMAIN|MBROWSER, "F6", 0, do_search, 0);
add_to_sclist(MMAIN, "^\\", 0, do_replace, 0);
add_to_sclist(MMAIN, "M-R", 0, do_replace, 0);
add_to_sclist(MMAIN, "F14", 0, do_replace, 0);
add_to_sclist(MMOST, "^K", 0, do_cut_text_void, 0);
add_to_sclist(MMOST, "F9", 0, do_cut_text_void, 0);
add_to_sclist(MMAIN, "^U", 0, do_uncut_text, 0);
add_to_sclist(MMAIN, "F10", 0, do_uncut_text, 0);
#ifndef DISABLE_JUSTIFY
add_to_sclist(MMAIN, "^J", do_justify_void, 0);
add_to_sclist(MMAIN, "F4", do_justify_void, 0);
add_to_sclist(MMAIN, "^J", 0, do_justify_void, 0);
add_to_sclist(MMAIN, "F4", 0, do_justify_void, 0);
#endif
#ifndef DISABLE_SPELLER
add_to_sclist(MMAIN, "^T", do_spell, 0);
add_to_sclist(MMAIN, "F12", do_spell, 0);
add_to_sclist(MMAIN, "^T", 0, do_spell, 0);
add_to_sclist(MMAIN, "F12", 0, do_spell, 0);
#else
#ifndef DISABLE_COLOR
add_to_sclist(MMAIN, "^T", do_linter, 0);
add_to_sclist(MMAIN, "F12", do_linter, 0);
add_to_sclist(MMAIN, "^T", 0, do_linter, 0);
add_to_sclist(MMAIN, "F12", 0, do_linter, 0);
#endif
#endif
add_to_sclist(MMAIN, "^C", do_cursorpos_void, 0);
add_to_sclist(MMAIN, "F11", do_cursorpos_void, 0);
add_to_sclist(MMAIN, "^_", do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN, "M-G", do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN, "F13", do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^Y", do_page_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F7", do_page_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgUp", do_page_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^V", do_page_down, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F8", do_page_down, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgDn", do_page_down, 0);
add_to_sclist(MMAIN|MHELP, "M-\\", do_first_line, 0);
add_to_sclist(MMAIN|MHELP, "M-|", do_first_line, 0);
add_to_sclist(MMAIN|MHELP, "M-/", do_last_line, 0);
add_to_sclist(MMAIN|MHELP, "M-?", do_last_line, 0);
add_to_sclist(MMAIN, "^C", 0, do_cursorpos_void, 0);
add_to_sclist(MMAIN, "F11", 0, do_cursorpos_void, 0);
add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN, "M-G", 0, do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN, "F13", 0, do_gotolinecolumn_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^Y", 0, do_page_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F7", 0, do_page_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgUp", KEY_PPAGE, do_page_up, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^V", 0, do_page_down, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F8", 0, do_page_down, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgDn", KEY_NPAGE, do_page_down, 0);
add_to_sclist(MMAIN|MHELP, "M-\\", 0, do_first_line, 0);
add_to_sclist(MMAIN|MHELP, "M-|", 0, do_first_line, 0);
add_to_sclist(MMAIN|MHELP, "M-/", 0, do_last_line, 0);
add_to_sclist(MMAIN|MHELP, "M-?", 0, do_last_line, 0);
add_to_sclist(MMAIN|MBROWSER, "M-W", 0, do_research, 0);
add_to_sclist(MMAIN|MBROWSER, "F16", 0, do_research, 0);
#ifndef NANO_TINY
add_to_sclist(MMAIN|MBROWSER, "M-W", do_research, 0);
add_to_sclist(MMAIN|MBROWSER, "F16", do_research, 0);
add_to_sclist(MMAIN, "M-]", do_find_bracket, 0);
add_to_sclist(MMAIN, "^^", do_mark, 0);
add_to_sclist(MMAIN, "M-A", do_mark, 0);
add_to_sclist(MMAIN, "F15", do_mark, 0);
add_to_sclist(MMAIN, "M-^", do_copy_text, 0);
add_to_sclist(MMAIN, "M-6", do_copy_text, 0);
add_to_sclist(MMAIN, "M-}", do_indent_void, 0);
add_to_sclist(MMAIN, "M-{", do_unindent, 0);
add_to_sclist(MMAIN, "M-U", do_undo, 0);
add_to_sclist(MMAIN, "M-E", do_redo, 0);
add_to_sclist(MMAIN, "M-]", 0, do_find_bracket, 0);
add_to_sclist(MMAIN, "^^", 0, do_mark, 0);
add_to_sclist(MMAIN, "M-A", 0, do_mark, 0);
add_to_sclist(MMAIN, "F15", 0, do_mark, 0);
add_to_sclist(MMAIN, "M-^", 0, do_copy_text, 0);
add_to_sclist(MMAIN, "M-6", 0, do_copy_text, 0);
add_to_sclist(MMAIN, "M-}", 0, do_indent_void, 0);
add_to_sclist(MMAIN, "M-{", 0, do_unindent, 0);
add_to_sclist(MMAIN, "M-U", 0, do_undo, 0);
add_to_sclist(MMAIN, "M-E", 0, do_redo, 0);
#endif
#ifdef ENABLE_COMMENT
add_to_sclist(MMAIN, "M-3", do_comment, 0);
add_to_sclist(MMAIN, "M-3", 0, do_comment, 0);
#endif
add_to_sclist(MMOST, "^B", do_left, 0);
add_to_sclist(MMOST, "Left", do_left, 0);
add_to_sclist(MMOST, "^F", do_right, 0);
add_to_sclist(MMOST, "Right", do_right, 0);
#ifndef NANO_TINY
add_to_sclist(MMOST, "M-Space", do_prev_word_void, 0);
add_to_sclist(MMOST, "^Space", do_next_word_void, 0);
add_to_sclist(MMOST, "^B", 0, do_left, 0);
add_to_sclist(MMOST, "Left", KEY_LEFT, do_left, 0);
add_to_sclist(MMOST, "^F", 0, do_right, 0);
add_to_sclist(MMOST, "Right", KEY_RIGHT, do_right, 0);
#ifdef ENABLE_UTF8
if (using_utf8()) {
add_to_sclist(MMOST, "^\xE2\x86\x90", CONTROL_LEFT, do_prev_word_void, 0);
add_to_sclist(MMOST, "^\xE2\x86\x92", CONTROL_RIGHT, do_next_word_void, 0);
} else
#endif
add_to_sclist((MMOST & ~MBROWSER), "^A", do_home, 0);
add_to_sclist((MMOST & ~MBROWSER), "Home", do_home, 0);
add_to_sclist((MMOST & ~MBROWSER), "^E", do_end, 0);
add_to_sclist((MMOST & ~MBROWSER), "End", do_end, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", do_up_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", do_up_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", do_down_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", do_down_void, 0);
#ifndef NANO_TINY
add_to_sclist(MMAIN, "M-7", do_prev_block, 0);
add_to_sclist(MMAIN, "M-8", do_next_block, 0);
{
add_to_sclist(MMOST, "^Left", CONTROL_LEFT, do_prev_word_void, 0);
add_to_sclist(MMOST, "^Right", CONTROL_RIGHT, do_next_word_void, 0);
}
add_to_sclist(MMOST, "M-Space", 0, do_prev_word_void, 0);
add_to_sclist(MMOST, "^Space", 0, do_next_word_void, 0);
add_to_sclist((MMOST & ~MBROWSER), "^A", 0, do_home, 0);
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, "Up", KEY_UP, do_up_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", 0, do_down_void, 0);
add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", KEY_DOWN, do_down_void, 0);
#ifdef ENABLE_UTF8
if (using_utf8()) {
add_to_sclist(MMAIN, "^\xE2\x86\x91", CONTROL_UP, do_prev_block, 0);
add_to_sclist(MMAIN, "^\xE2\x86\x93", CONTROL_DOWN, do_next_block, 0);
} else
#endif
{
add_to_sclist(MMAIN, "^Up", CONTROL_UP, do_prev_block, 0);
add_to_sclist(MMAIN, "^Down", CONTROL_DOWN, do_next_block, 0);
}
add_to_sclist(MMAIN, "M-7", 0, do_prev_block, 0);
add_to_sclist(MMAIN, "M-8", 0, do_next_block, 0);
#ifndef DISABLE_JUSTIFY
add_to_sclist(MMAIN, "M-(", do_para_begin_void, 0);
add_to_sclist(MMAIN, "M-9", do_para_begin_void, 0);
add_to_sclist(MMAIN, "M-)", do_para_end_void, 0);
add_to_sclist(MMAIN, "M-0", do_para_end_void, 0);
add_to_sclist(MMAIN, "M-(", 0, do_para_begin_void, 0);
add_to_sclist(MMAIN, "M-9", 0, do_para_begin_void, 0);
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
add_to_sclist(MMAIN, "M--", do_scroll_up, 0);
add_to_sclist(MMAIN, "M-_", do_scroll_up, 0);
add_to_sclist(MMAIN, "M-+", do_scroll_down, 0);
add_to_sclist(MMAIN, "M-=", do_scroll_down, 0);
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);
add_to_sclist(MMAIN, "M-=", 0, do_scroll_down, 0);
#endif
#ifndef DISABLE_MULTIBUFFER
add_to_sclist(MMAIN, "M-<", switch_to_prev_buffer_void, 0);
add_to_sclist(MMAIN, "M-,", switch_to_prev_buffer_void, 0);
add_to_sclist(MMAIN, "M->", switch_to_next_buffer_void, 0);
add_to_sclist(MMAIN, "M-.", switch_to_next_buffer_void, 0);
add_to_sclist(MMAIN, "M-<", 0, switch_to_prev_buffer_void, 0);
add_to_sclist(MMAIN, "M-,", 0, switch_to_prev_buffer_void, 0);
add_to_sclist(MMAIN, "M->", 0, switch_to_next_buffer_void, 0);
add_to_sclist(MMAIN, "M-.", 0, switch_to_next_buffer_void, 0);
#endif
add_to_sclist(MMOST, "M-V", do_verbatim_input, 0);
add_to_sclist(MMOST, "M-V", 0, do_verbatim_input, 0);
#ifndef NANO_TINY
add_to_sclist(MMAIN, "M-T", do_cut_till_eof, 0);
add_to_sclist(MMAIN, "M-D", do_wordlinechar_count, 0);
add_to_sclist(MMAIN, "M-T", 0, do_cut_till_eof, 0);
add_to_sclist(MMAIN, "M-D", 0, do_wordlinechar_count, 0);
#endif
#ifndef DISABLE_JUSTIFY
add_to_sclist(MMAIN|MWHEREIS, "M-J", do_full_justify, 0);
add_to_sclist(MMAIN|MWHEREIS, "M-J", 0, do_full_justify, 0);
#endif
add_to_sclist(MMAIN|MHELP, "^L", total_refresh, 0);
add_to_sclist(MMAIN, "^Z", do_suspend_void, 0);
add_to_sclist(MMAIN|MHELP, "^L", 0, total_refresh, 0);
add_to_sclist(MMAIN, "^Z", 0, do_suspend_void, 0);
#ifndef NANO_TINY
/* Group of "Appearance" toggles. */
add_to_sclist(MMAIN, "M-X", do_toggle_void, NO_HELP);
add_to_sclist(MMAIN, "M-C", do_toggle_void, CONST_UPDATE);
add_to_sclist(MMAIN, "M-O", do_toggle_void, MORE_SPACE);
add_to_sclist(MMAIN, "M-S", do_toggle_void, SMOOTH_SCROLL);
add_to_sclist(MMAIN, "M-$", do_toggle_void, SOFTWRAP);
add_to_sclist(MMAIN, "M-P", do_toggle_void, WHITESPACE_DISPLAY);
add_to_sclist(MMAIN, "M-X", 0, do_toggle_void, NO_HELP);
add_to_sclist(MMAIN, "M-C", 0, do_toggle_void, CONST_UPDATE);
add_to_sclist(MMAIN, "M-O", 0, do_toggle_void, MORE_SPACE);
add_to_sclist(MMAIN, "M-S", 0, do_toggle_void, SMOOTH_SCROLL);
add_to_sclist(MMAIN, "M-$", 0, do_toggle_void, SOFTWRAP);
#ifdef ENABLE_LINENUMBERS
add_to_sclist(MMAIN, "M-#", 0, do_toggle_void, LINE_NUMBERS);
#endif
add_to_sclist(MMAIN, "M-P", 0, do_toggle_void, WHITESPACE_DISPLAY);
#ifndef DISABLE_COLOR
add_to_sclist(MMAIN, "M-Y", do_toggle_void, NO_COLOR_SYNTAX);
add_to_sclist(MMAIN, "M-Y", 0, do_toggle_void, NO_COLOR_SYNTAX);
#endif
/* Group of "Editing-behavior" toggles. */
add_to_sclist(MMAIN, "M-H", do_toggle_void, SMART_HOME);
add_to_sclist(MMAIN, "M-I", do_toggle_void, AUTOINDENT);
add_to_sclist(MMAIN, "M-K", do_toggle_void, CUT_TO_END);
add_to_sclist(MMAIN, "M-H", 0, do_toggle_void, SMART_HOME);
add_to_sclist(MMAIN, "M-I", 0, do_toggle_void, AUTOINDENT);
add_to_sclist(MMAIN, "M-K", 0, do_toggle_void, CUT_TO_END);
#ifndef DISABLE_WRAPPING
add_to_sclist(MMAIN, "M-L", do_toggle_void, NO_WRAP);
add_to_sclist(MMAIN, "M-L", 0, do_toggle_void, NO_WRAP);
#endif
add_to_sclist(MMAIN, "M-Q", do_toggle_void, TABS_TO_SPACES);
add_to_sclist(MMAIN, "M-Q", 0, do_toggle_void, TABS_TO_SPACES);
/* Group of "Peripheral-feature" toggles. */
add_to_sclist(MMAIN, "M-B", do_toggle_void, BACKUP_FILE);
add_to_sclist(MMAIN, "M-B", 0, do_toggle_void, BACKUP_FILE);
#ifndef DISABLE_MULTIBUFFER
add_to_sclist(MMAIN, "M-F", do_toggle_void, MULTIBUFFER);
add_to_sclist(MMAIN, "M-F", 0, do_toggle_void, MULTIBUFFER);
#endif
#ifndef DISABLE_MOUSE
add_to_sclist(MMAIN, "M-M", do_toggle_void, USE_MOUSE);
add_to_sclist(MMAIN, "M-M", 0, do_toggle_void, USE_MOUSE);
#endif
add_to_sclist(MMAIN, "M-N", do_toggle_void, NO_CONVERT);
add_to_sclist(MMAIN, "M-Z", do_toggle_void, SUSPEND);
add_to_sclist(MMAIN, "M-N", 0, do_toggle_void, NO_CONVERT);
add_to_sclist(MMAIN, "M-Z", 0, do_toggle_void, SUSPEND);
#endif /* !NANO_TINY */
add_to_sclist(MMAIN, "^Q", xon_complaint, 0);
add_to_sclist(MMAIN, "^S", xoff_complaint, 0);
add_to_sclist(MMAIN, "^Q", 0, xon_complaint, 0);
add_to_sclist(MMAIN, "^S", 0, xoff_complaint, 0);
add_to_sclist(((MMOST & ~MMAIN & ~MBROWSER) | MYESNO), "^C", do_cancel, 0);
add_to_sclist(((MMOST & ~MMAIN & ~MBROWSER) | MYESNO), "^C", 0, do_cancel, 0);
#ifndef NANO_TINY
add_to_sclist(MWHEREIS|MREPLACE, "M-B", backwards_void, 0);
add_to_sclist(MWHEREIS|MREPLACE, "M-C", case_sens_void, 0);
#endif
add_to_sclist(MWHEREIS|MREPLACE, "M-R", regexp_void, 0);
add_to_sclist(MWHEREIS|MREPLACE, "^R", flip_replace_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^Y", do_first_line, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^V", do_last_line, 0);
add_to_sclist(MWHEREIS|MREPLACE, "M-C", 0, case_sens_void, 0);
add_to_sclist(MWHEREIS|MREPLACE, "M-R", 0, regexp_void, 0);
add_to_sclist(MWHEREIS|MREPLACE, "M-B", 0, backwards_void, 0);
add_to_sclist(MWHEREIS|MREPLACE, "^R", 0, flip_replace_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^Y", 0, do_first_line, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^V", 0, do_last_line, 0);
#ifndef DISABLE_JUSTIFY
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^W", do_para_begin_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^O", do_para_end_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^W", 0, do_para_begin_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^O", 0, do_para_end_void, 0);
#endif
add_to_sclist(MWHEREIS, "^T", do_gotolinecolumn_void, 0);
add_to_sclist(MGOTOLINE, "^T", gototext_void, 0);
add_to_sclist(MWHEREIS, "^T", 0, do_gotolinecolumn_void, 0);
add_to_sclist(MGOTOLINE, "^T", 0, gototext_void, 0);
#ifndef DISABLE_HISTORIES
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^P", get_history_older_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Up", get_history_older_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^N", get_history_newer_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Down", get_history_newer_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^P", 0, get_history_older_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Up", KEY_UP, get_history_older_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^N", 0, get_history_newer_void, 0);
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Down", KEY_DOWN, get_history_newer_void, 0);
#endif
#ifndef DISABLE_BROWSER
add_to_sclist(MWHEREISFILE, "^Y", do_first_file, 0);
add_to_sclist(MWHEREISFILE, "^V", do_last_file, 0);
add_to_sclist(MBROWSER|MWHEREISFILE, "M-\\", do_first_file, 0);
add_to_sclist(MBROWSER|MWHEREISFILE, "M-|", do_first_file, 0);
add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", do_last_file, 0);
add_to_sclist(MBROWSER|MWHEREISFILE, "M-?", do_last_file, 0);
add_to_sclist(MBROWSER, "Home", do_first_file, 0);
add_to_sclist(MBROWSER, "End", do_last_file, 0);
add_to_sclist(MBROWSER, "^_", goto_dir_void, 0);
add_to_sclist(MBROWSER, "M-G", goto_dir_void, 0);
add_to_sclist(MBROWSER, "F13", goto_dir_void, 0);
add_to_sclist(MBROWSER, "^L", total_refresh, 0);
add_to_sclist(MWHEREISFILE, "^Y", 0, do_first_file, 0);
add_to_sclist(MWHEREISFILE, "^V", 0, do_last_file, 0);
add_to_sclist(MBROWSER|MWHEREISFILE, "M-\\", 0, do_first_file, 0);
add_to_sclist(MBROWSER|MWHEREISFILE, "M-|", 0, do_first_file, 0);
add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", 0, do_last_file, 0);
add_to_sclist(MBROWSER|MWHEREISFILE, "M-?", 0, do_last_file, 0);
add_to_sclist(MBROWSER, "Home", KEY_HOME, do_first_file, 0);
add_to_sclist(MBROWSER, "End", KEY_END, do_last_file, 0);
add_to_sclist(MBROWSER, "^_", 0, goto_dir_void, 0);
add_to_sclist(MBROWSER, "M-G", 0, goto_dir_void, 0);
add_to_sclist(MBROWSER, "F13", 0, goto_dir_void, 0);
add_to_sclist(MBROWSER, "^L", 0, total_refresh, 0);
#endif
if (ISSET(TEMP_FILE))
add_to_sclist(MWRITEFILE, "^Q", discard_buffer, 0);
add_to_sclist(MWRITEFILE, "M-D", dos_format_void, 0);
add_to_sclist(MWRITEFILE, "M-M", mac_format_void, 0);
add_to_sclist(MWRITEFILE, "^Q", 0, discard_buffer, 0);
add_to_sclist(MWRITEFILE, "M-D", 0, dos_format_void, 0);
add_to_sclist(MWRITEFILE, "M-M", 0, mac_format_void, 0);
if (!ISSET(RESTRICTED)) {
/* Don't allow Appending, Prepending, nor Backups in restricted mode. */
add_to_sclist(MWRITEFILE, "M-A", append_void, 0);
add_to_sclist(MWRITEFILE, "M-P", prepend_void, 0);
add_to_sclist(MWRITEFILE, "M-B", backup_file_void, 0);
add_to_sclist(MWRITEFILE, "M-A", 0, append_void, 0);
add_to_sclist(MWRITEFILE, "M-P", 0, prepend_void, 0);
add_to_sclist(MWRITEFILE, "M-B", 0, backup_file_void, 0);
#ifndef DISABLE_BROWSER
add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", to_files_void, 0);
add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files_void, 0);
#endif
add_to_sclist(MINSERTFILE|MEXTCMD, "^X", flip_execute_void, 0);
add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", new_buffer_void, 0);
add_to_sclist(MINSERTFILE|MEXTCMD, "^X", 0, flip_execute_void, 0);
add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", 0, new_buffer_void, 0);
}
add_to_sclist(MHELP|MBROWSER, "^C", do_exit, 0);
add_to_sclist(MHELP|MBROWSER, "^C", 0, do_exit, 0);
/* Allow exiting from the file browser and the help viewer with
* the same key as they were entered. */
#ifndef DISABLE_BROWSER
add_to_sclist(MBROWSER, "^T", do_exit, 0);
add_to_sclist(MBROWSER, "^T", 0, do_exit, 0);
#endif
#ifndef DISABLE_HELP
add_to_sclist(MHELP, "^G", do_exit, 0);
add_to_sclist(MHELP, "Home", do_first_line, 0);
add_to_sclist(MHELP, "End", do_last_line, 0);
add_to_sclist(MHELP, "^G", 0, do_exit, 0);
add_to_sclist(MHELP, "Home", KEY_HOME, do_first_line, 0);
add_to_sclist(MHELP, "End", KEY_END, do_last_line, 0);
#endif
add_to_sclist(MMOST, "^I", do_tab, 0);
add_to_sclist(MMOST, "Tab", do_tab, 0);
add_to_sclist(MMOST, "^M", do_enter, 0);
add_to_sclist(MMOST, "Enter", do_enter, 0);
add_to_sclist(MMOST, "^D", do_delete, 0);
add_to_sclist(MMOST, "Del", do_delete, 0);
add_to_sclist(MMOST, "^H", do_backspace, 0);
add_to_sclist(MMOST, "Bsp", do_backspace, 0);
add_to_sclist(MMOST, "^I", 0, do_tab, 0);
add_to_sclist(MMOST, "Tab", TAB_CODE, do_tab, 0);
add_to_sclist(MMOST, "^M", 0, do_enter, 0);
add_to_sclist(MMOST, "Enter", KEY_ENTER, do_enter, 0);
add_to_sclist(MMOST, "^D", 0, do_delete, 0);
add_to_sclist(MMOST, "Del", 0, do_delete, 0);
add_to_sclist(MMOST, "^H", 0, do_backspace, 0);
add_to_sclist(MMOST, "Bsp", KEY_BACKSPACE, do_backspace, 0);
#ifdef DEBUG
print_sclist();
@@ -1366,6 +1352,8 @@ const char *flagtostr(int flag)
return N_("No conversion from DOS/Mac format");
case SUSPEND:
return N_("Suspension");
case LINE_NUMBERS:
return N_("Line numbering");
default:
return "?????";
}
@@ -1377,9 +1365,11 @@ const char *flagtostr(int flag)
* shortcut struct with the corresponding function filled in. */
sc *strtosc(const char *input)
{
sc *s;
sc *s = nmalloc(sizeof(sc));
s = (sc *)nmalloc(sizeof(sc));
#ifndef NANO_TINY
s->toggle = 0;
#endif
#ifndef DISABLE_HELP
if (!strcasecmp(input, "help"))
@@ -1402,10 +1392,10 @@ sc *strtosc(const char *input)
s->scfunc = do_insertfile_void;
else if (!strcasecmp(input, "whereis"))
s->scfunc = do_search;
#ifndef NANO_TINY
else if (!strcasecmp(input, "searchagain") ||
!strcasecmp(input, "research"))
!strcasecmp(input, "research")) /* Deprecated. Remove in 2018. */
s->scfunc = do_research;
#ifndef NANO_TINY
else if (!strcasecmp(input, "findprevious"))
s->scfunc = do_findprevious;
else if (!strcasecmp(input, "findnext"))
@@ -1435,7 +1425,7 @@ sc *strtosc(const char *input)
s->scfunc = do_linter;
#endif
else if (!strcasecmp(input, "curpos") ||
!strcasecmp(input, "cursorpos"))
!strcasecmp(input, "cursorpos")) /* Deprecated. Remove in 2018. */
s->scfunc = do_cursorpos_void;
else if (!strcasecmp(input, "gotoline"))
s->scfunc = do_gotolinecolumn_void;
@@ -1531,15 +1521,13 @@ sc *strtosc(const char *input)
s->scfunc = do_suspend_void;
else if (!strcasecmp(input, "casesens"))
s->scfunc = case_sens_void;
#ifndef NANO_TINY
else if (!strcasecmp(input, "regexp") ||
!strcasecmp(input, "regex"))
!strcasecmp(input, "regex")) /* Deprecated. Remove in 2018. */
s->scfunc = regexp_void;
else if (!strcasecmp(input, "backwards"))
s->scfunc = backwards_void;
#endif
else if (!strcasecmp(input, "flipreplace") ||
!strcasecmp(input, "dontreplace"))
!strcasecmp(input, "dontreplace")) /* Deprecated. Remove in 2018. */
s->scfunc = flip_replace_void;
else if (!strcasecmp(input, "gototext"))
s->scfunc = gototext_void;
@@ -1565,7 +1553,7 @@ sc *strtosc(const char *input)
#endif
#ifndef DISABLE_MULTIBUFFER
else if (!strcasecmp(input, "flipnewbuffer") ||
!strcasecmp(input, "newbuffer"))
!strcasecmp(input, "newbuffer")) /* Deprecated. Remove in 2018. */
s->scfunc = new_buffer_void;
#endif
#ifndef DISABLE_BROWSER
@@ -1579,8 +1567,8 @@ sc *strtosc(const char *input)
else if (!strcasecmp(input, "lastfile"))
s->scfunc = do_last_file;
#endif
#ifndef NANO_TINY
else {
#ifndef NANO_TINY
s->scfunc = do_toggle_void;
if (!strcasecmp(input, "nohelp"))
s->toggle = NO_HELP;
@@ -1624,14 +1612,13 @@ sc *strtosc(const char *input)
s->toggle = NO_CONVERT;
else if (!strcasecmp(input, "suspendenable"))
s->toggle = SUSPEND;
else
#endif /* !NANO_TINY */
else {
{
free(s);
return NULL;
}
#ifndef NANO_TINY
}
#endif
return s;
}
@@ -1646,7 +1633,7 @@ int strtomenu(const char *input)
return MWHEREIS;
else if (!strcasecmp(input, "replace"))
return MREPLACE;
else if (!strcasecmp(input, "replace2") ||
else if (!strcasecmp(input, "replace2") || /* Deprecated. Remove in 2018. */
!strcasecmp(input, "replacewith"))
return MREPLACEWITH;
else if (!strcasecmp(input, "gotoline"))
@@ -1715,9 +1702,6 @@ void thanks_for_all_the_fish(void)
free(alt_speller);
#endif
free_filestruct(cutbuffer);
#ifndef DISABLE_JUSTIFY
free_filestruct(jusbuffer);
#endif
/* Free the memory associated with each open file buffer. */
while (openfile != openfile->next) {
openfile = openfile->next;

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* help.c *
* help.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, *
* 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -419,7 +419,11 @@ void help_init(void)
* but allow it to spill into the second, for "M-Space". */
if (scsfound == 1) {
sprintf(ptr, "%s ", s->keystr);
ptr += 6;
/* Unicode arrows take three bytes instead of one. */
if (s->keystr[1] == '\xE2')
ptr += 8;
else
ptr += 6;
} else {
ptr += sprintf(ptr, "(%s)\t", s->keystr);
break;

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* move.c *
* move.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -28,7 +28,7 @@
/* Move to the first line of the file. */
void do_first_line(void)
{
openfile->current = openfile->edittop = openfile->fileage;
openfile->current = openfile->fileage;
openfile->current_x = 0;
openfile->placewewant = 0;
@@ -41,6 +41,8 @@ void do_last_line(void)
openfile->current = openfile->filebot;
openfile->current_x = strlen(openfile->filebot->data);
openfile->placewewant = xplustabs();
/* Set the last line of the screen as the target for the cursor. */
openfile->current_y = editwinrows - 1;
refresh_needed = TRUE;
@@ -50,15 +52,15 @@ void do_last_line(void)
/* Move up one page. */
void do_page_up(void)
{
int i, skipped = 0;
int i, mustmove, skipped = 0;
/* If the cursor is less than a page away from the top of the file,
* put it at the beginning of the first line. */
if (openfile->current->lineno == 1 || (
#ifndef NANO_TINY
!ISSET(SOFTWRAP) &&
!ISSET(SOFTWRAP) &&
#endif
openfile->current->lineno <= editwinrows - 2)) {
openfile->current->lineno <= editwinrows - 2)) {
do_first_line();
return;
}
@@ -66,16 +68,16 @@ void do_page_up(void)
/* If we're not in smooth scrolling mode, put the cursor at the
* beginning of the top line of the edit window, as Pico does. */
#ifndef NANO_TINY
if (!ISSET(SMOOTH_SCROLL)) {
if (!ISSET(SMOOTH_SCROLL))
#endif
{
openfile->current = openfile->edittop;
openfile->placewewant = openfile->current_y = 0;
#ifndef NANO_TINY
}
#endif
for (i = editwinrows - 2; i - skipped > 0 && openfile->current !=
openfile->fileage; i--) {
mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
for (i = mustmove; i - skipped > 0 && openfile->current != openfile->fileage; i--) {
openfile->current = openfile->current->prev;
#ifndef NANO_TINY
if (ISSET(SOFTWRAP) && openfile->current) {
@@ -93,18 +95,18 @@ void do_page_up(void)
#ifdef DEBUG
fprintf(stderr, "do_page_up: openfile->current->lineno = %lu, skipped = %d\n",
(unsigned long)openfile->current->lineno, skipped);
(unsigned long)openfile->current->lineno, skipped);
#endif
/* Scroll the edit window up a page. */
edit_update(STATIONARY);
adjust_viewport(STATIONARY);
refresh_needed = TRUE;
}
/* Move down one page. */
void do_page_down(void)
{
int i;
int i, mustmove;
/* If the cursor is less than a page away from the bottom of the file,
* put it at the end of the last line. */
@@ -116,16 +118,16 @@ void do_page_down(void)
/* If we're not in smooth scrolling mode, put the cursor at the
* beginning of the top line of the edit window, as Pico does. */
#ifndef NANO_TINY
if (!ISSET(SMOOTH_SCROLL)) {
if (!ISSET(SMOOTH_SCROLL))
#endif
{
openfile->current = openfile->edittop;
openfile->placewewant = openfile->current_y = 0;
#ifndef NANO_TINY
}
#endif
for (i = maxrows - 2; i > 0 && openfile->current !=
openfile->filebot; i--) {
mustmove = (maxrows < 3) ? 1 : maxrows - 2;
for (i = mustmove; i > 0 && openfile->current != openfile->filebot; i--) {
openfile->current = openfile->current->next;
#ifdef DEBUG
fprintf(stderr, "do_page_down: moving to line %lu\n", (unsigned long)openfile->current->lineno);
@@ -137,7 +139,7 @@ void do_page_down(void)
openfile->placewewant);
/* Scroll the edit window down a page. */
edit_update(STATIONARY);
adjust_viewport(STATIONARY);
refresh_needed = TRUE;
}
@@ -147,7 +149,7 @@ void do_page_down(void)
* afterwards. */
void do_para_begin(bool allow_update)
{
filestruct *current_save = openfile->current;
filestruct *was_current = openfile->current;
if (openfile->current != openfile->fileage) {
do {
@@ -159,7 +161,7 @@ void do_para_begin(bool allow_update)
openfile->current_x = 0;
if (allow_update)
edit_redraw(current_save);
edit_redraw(was_current);
}
/* Move up to the beginning of the last beginning-of-paragraph line
@@ -177,7 +179,7 @@ void do_para_begin_void(void)
* paragraph or isn't in a paragraph. */
void do_para_end(bool allow_update)
{
filestruct *const current_save = openfile->current;
filestruct *was_current = openfile->current;
while (openfile->current != openfile->filebot &&
!inpar(openfile->current))
@@ -197,7 +199,7 @@ void do_para_end(bool allow_update)
openfile->current_x = strlen(openfile->current->data);
if (allow_update)
edit_redraw(current_save);
edit_redraw(was_current);
}
/* Move down to the beginning of the last line of the current paragraph.
@@ -209,7 +211,6 @@ void do_para_end_void(void)
}
#endif /* !DISABLE_JUSTIFY */
#ifndef NANO_TINY
/* Move to the preceding block of text in the file. */
void do_prev_block(void)
{
@@ -255,7 +256,7 @@ void do_next_block(void)
* screen afterwards. */
void do_prev_word(bool allow_punct, bool allow_update)
{
filestruct *current_save = openfile->current;
filestruct *was_current = openfile->current;
bool seen_a_word = FALSE, step_forward = FALSE;
assert(openfile->current != NULL && openfile->current->data != NULL);
@@ -295,7 +296,7 @@ void do_prev_word(bool allow_punct, bool allow_update)
/* If allow_update is TRUE, update the screen. */
if (allow_update) {
focusing = FALSE;
edit_redraw(current_save);
edit_redraw(was_current);
}
}
@@ -312,7 +313,7 @@ void do_prev_word_void(void)
* otherwise. */
bool do_next_word(bool allow_punct, bool allow_update)
{
filestruct *current_save = openfile->current;
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;
@@ -347,7 +348,7 @@ bool do_next_word(bool allow_punct, bool allow_update)
/* If allow_update is TRUE, update the screen. */
if (allow_update) {
focusing = FALSE;
edit_redraw(current_save);
edit_redraw(was_current);
}
/* Return whether we started on a word. */
@@ -360,7 +361,19 @@ void do_next_word_void(void)
{
do_next_word(ISSET(WORD_BOUNDS), TRUE);
}
#endif /* !NANO_TINY */
/* Make sure that the current line, when it is partially scrolled off the
* screen in softwrap mode, is scrolled fully into view. */
void ensure_line_is_visible(void)
{
#ifndef NANO_TINY
if (ISSET(SOFTWRAP) && strlenpt(openfile->current->data) / editwincols +
openfile->current_y >= editwinrows) {
adjust_viewport(ISSET(SMOOTH_SCROLL) ? FLOWING : CENTERING);
refresh_needed = TRUE;
}
#endif
}
/* Move to the beginning of the current line. If the SMART_HOME flag is
* set, move to the first non-whitespace character of the current line
@@ -368,7 +381,7 @@ void do_next_word_void(void)
* if we are. */
void do_home(void)
{
size_t pww_save = openfile->placewewant;
size_t was_column = xplustabs();
#ifndef NANO_TINY
if (ISSET(SMART_HOME)) {
@@ -385,32 +398,30 @@ void do_home(void)
openfile->placewewant = xplustabs();
if (need_screen_update(pww_save))
if (need_horizontal_scroll(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
}
/* Move to the end of the current line. */
void do_end(void)
{
size_t pww_save = openfile->placewewant;
size_t was_column = xplustabs();
openfile->current_x = strlen(openfile->current->data);
openfile->placewewant = xplustabs();
if (need_screen_update(pww_save))
if (need_horizontal_scroll(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
ensure_line_is_visible();
}
/* If scroll_only is FALSE, move up one line. If scroll_only is TRUE,
* scroll up one line without scrolling the cursor. */
void do_up(
#ifndef NANO_TINY
bool scroll_only
#else
void
#endif
)
void do_up(bool scroll_only)
{
size_t was_column = xplustabs();
/* If we're at the top of the file, or if scroll_only is TRUE and
* the top of the file is onscreen, get out. */
if (openfile->current == openfile->fileage
@@ -427,63 +438,39 @@ void do_up(
openfile->current_x = actual_x(openfile->current->data,
openfile->placewewant);
/* If scroll_only is FALSE and if we're on the first line of the
* edit window, scroll the edit window up one line if we're in
* smooth scrolling mode, or up half a page if we're not. If
* scroll_only is TRUE, scroll the edit window up one line
* unconditionally. */
if (openfile->current_y == 0
#ifndef NANO_TINY
|| (ISSET(SOFTWRAP) && openfile->edittop->lineno == openfile->current->next->lineno) || scroll_only
#endif
)
edit_scroll(UPWARD,
#ifndef NANO_TINY
(ISSET(SMOOTH_SCROLL) || scroll_only) ? 1 :
#endif
editwinrows / 2 + 1);
/* When the cursor was on the first line of the edit window (or when just
* scrolling without moving the cursor), scroll the edit window up -- one
* line if we're in smooth scrolling mode, and half a page otherwise. */
if (openfile->current->next == openfile->edittop || scroll_only)
edit_scroll(UPWARD, (ISSET(SMOOTH_SCROLL) || scroll_only) ?
1 : editwinrows / 2 + 1);
/* If we're not on the first line of the edit window, and the target
* column is beyond the screen or the mark is on, redraw the prior
* and current lines. */
if (openfile->current_y > 0 && need_screen_update(0)) {
update_line(openfile->current->next, 0);
update_line(openfile->current, openfile->current_x);
/* If the lines weren't already redrawn, see if they need to be. */
if (openfile->current_y > 0) {
/* Redraw the prior line if it was horizontally scrolled. */
if (need_horizontal_scroll(was_column, 0))
update_line(openfile->current->next, 0);
/* Redraw the current line if it needs to be horizontally scrolled. */
if (need_horizontal_scroll(0, xplustabs()))
update_line(openfile->current, openfile->current_x);
}
}
/* Move up one line. */
void do_up_void(void)
{
do_up(
#ifndef NANO_TINY
FALSE
#endif
);
do_up(FALSE);
}
#ifndef NANO_TINY
/* Scroll up one line without scrolling the cursor. */
void do_scroll_up(void)
{
do_up(TRUE);
}
#endif
/* If scroll_only is FALSE, move down one line. If scroll_only is TRUE,
* scroll down one line without scrolling the cursor. */
void do_down(
#ifndef NANO_TINY
bool scroll_only
#else
void
#endif
)
void do_down(bool scroll_only)
{
#ifndef NANO_TINY
int amount = 0, enough;
filestruct *topline;
#endif
size_t was_column = xplustabs();
/* If we're at the bottom of the file, get out. */
if (openfile->current == openfile->filebot)
@@ -496,18 +483,20 @@ void do_down(
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
/* Compute the number of lines to scroll. */
amount = strlenpt(openfile->current->data) / COLS - xplustabs() / COLS +
strlenpt(openfile->current->next->data) / COLS +
amount = strlenpt(openfile->current->data) / editwincols -
xplustabs() / editwincols +
strlenpt(openfile->current->next->data) / editwincols +
openfile->current_y - editwinrows + 2;
topline = openfile->edittop;
/* Reduce the amount when there are overlong lines at the top. */
for (enough = 1; enough < amount; enough++) {
amount -= strlenpt(topline->data) / COLS;
if (amount <= 0) {
amount -= strlenpt(topline->data) / editwincols;
if (amount > 0)
topline = topline->next;
if (amount < enough) {
amount = enough;
break;
}
topline = topline->next;
}
}
#endif
@@ -522,47 +511,48 @@ void do_down(
* smooth scrolling mode, or down half a page if we're not. If
* scroll_only is TRUE, scroll the edit window down one line
* unconditionally. */
if (openfile->current_y == editwinrows - 1
#ifndef NANO_TINY
|| amount > 0 || scroll_only
#endif
) {
#ifndef NANO_TINY
if (openfile->current_y == editwinrows - 1 || amount > 0 || scroll_only) {
if (amount < 1 || scroll_only)
amount = 1;
#endif
edit_scroll(DOWNWARD,
#ifndef NANO_TINY
(ISSET(SMOOTH_SCROLL) || scroll_only) ? amount :
#endif
editwinrows / 2 + 1);
edit_scroll(DOWNWARD, (ISSET(SMOOTH_SCROLL) || scroll_only) ?
amount : editwinrows / 2 + 1);
if (ISSET(SOFTWRAP)) {
refresh_needed = TRUE;
return;
}
}
#else
if (openfile->current_y == editwinrows - 1)
edit_scroll(DOWNWARD, editwinrows / 2 + 1);
#endif
/* If we're not on the last line of the edit window, and the target
* column is beyond the screen or the mark is on, redraw the prior
* and current lines. */
if (openfile->current_y < editwinrows - 1 && need_screen_update(0)) {
update_line(openfile->current->prev, 0);
update_line(openfile->current, openfile->current_x);
/* If the lines weren't already redrawn, see if they need to be. */
if (openfile->current_y < editwinrows - 1) {
/* Redraw the prior line if it was horizontally scrolled. */
if (need_horizontal_scroll(was_column, 0))
update_line(openfile->current->prev, 0);
/* Redraw the current line if it needs to be horizontally scrolled. */
if (need_horizontal_scroll(0, xplustabs()))
update_line(openfile->current, openfile->current_x);
}
}
/* Move down one line. */
void do_down_void(void)
{
do_down(
#ifndef NANO_TINY
FALSE
#endif
);
do_down(FALSE);
}
#ifndef NANO_TINY
/* Scroll up one line without scrolling the cursor. */
void do_scroll_up(void)
{
do_up(TRUE);
}
/* Scroll down one line without scrolling the cursor. */
void do_scroll_down(void)
{
@@ -573,7 +563,7 @@ void do_scroll_down(void)
/* Move left one character. */
void do_left(void)
{
size_t pww_save = openfile->placewewant;
size_t was_column = xplustabs();
if (openfile->current_x > 0)
openfile->current_x = move_mbleft(openfile->current->data,
@@ -585,14 +575,14 @@ void do_left(void)
openfile->placewewant = xplustabs();
if (need_screen_update(pww_save))
if (need_horizontal_scroll(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
}
/* Move right one character. */
void do_right(void)
{
size_t pww_save = openfile->placewewant;
size_t was_column = xplustabs();
assert(openfile->current_x <= strlen(openfile->current->data));
@@ -600,12 +590,20 @@ void do_right(void)
openfile->current_x = move_mbright(openfile->current->data,
openfile->current_x);
else if (openfile->current != openfile->filebot) {
do_down_void();
openfile->current_x = 0;
#ifndef NANO_TINY
if (ISSET(SOFTWRAP))
openfile->current_y -= strlenpt(openfile->current->data) / COLS;
#endif
}
openfile->placewewant = xplustabs();
if (need_screen_update(pww_save))
if (need_horizontal_scroll(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
if (openfile->current_x == 0)
do_down_void();
else
ensure_line_is_visible();
}

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* nano.c *
* nano.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -395,7 +395,7 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
/* If the top of the edit window was inside the old partition, put
* it in range of current. */
if (edittop_inside) {
edit_update(STATIONARY);
adjust_viewport(STATIONARY);
refresh_needed = TRUE;
}
@@ -603,49 +603,46 @@ void die(const char *msg, ...)
vfprintf(stderr, msg, ap);
va_end(ap);
/* Save the current file buffer if it's been modified. */
#ifndef NANO_TINY
/* If the current buffer has a lockfile, remove it. */
if (openfile && ISSET(LOCKING) && openfile->lock_filename)
delete_lockfile(openfile->lock_filename);
#endif
/* If the current file buffer was modified, save it. */
if (openfile && openfile->modified) {
/* If we've partitioned the filestruct, unpartition it now. */
/* If the filestruct is partitioned, unpartition it first. */
if (filepart != NULL)
unpartition_filestruct(&filepart);
die_save_file(openfile->filename
#ifndef NANO_TINY
, openfile->current_stat
#endif
);
die_save_file(openfile->filename, openfile->current_stat);
}
#ifndef DISABLE_MULTIBUFFER
/* Save all of the other modified file buffers, if any. */
if (openfile != NULL) {
openfilestruct *tmp = openfile;
openfilestruct *firstone = openfile;
while (tmp != openfile->next) {
while (openfile->next != firstone) {
openfile = openfile->next;
/* Save the current file buffer if it's been modified. */
if (openfile->modified)
die_save_file(openfile->filename
#ifndef NANO_TINY
, openfile->current_stat
if (ISSET(LOCKING) && openfile->lock_filename)
delete_lockfile(openfile->lock_filename);
#endif
);
if (openfile->modified)
die_save_file(openfile->filename, openfile->current_stat);
}
}
#endif
/* Get out. */
/* 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
#ifndef NANO_TINY
, struct stat *die_stat
#endif
)
void die_save_file(const char *die_filename, struct stat *die_stat)
{
char *targetname;
bool failed = TRUE;
@@ -689,37 +686,37 @@ void die_save_file(const char *die_filename
free(targetname);
}
#define TOP_ROWS (ISSET(MORE_SPACE) ? 1 : 2)
#define BOTTOM_ROWS (ISSET(NO_HELP) ? 1 : 3)
/* Initialize the three window portions nano uses. */
void window_init(void)
{
/* If the screen height is too small, get out. */
editwinrows = LINES - TOP_ROWS - BOTTOM_ROWS;
if (COLS < MIN_EDITOR_COLS || editwinrows < MIN_EDITOR_ROWS)
die(_("Window size is too small for nano...\n"));
/* First delete existing windows, in case of resizing. */
delwin(topwin);
topwin = NULL;
delwin(edit);
delwin(bottomwin);
#ifndef DISABLE_WRAPJUSTIFY
/* Set up fill, based on the screen width. */
fill = wrap_at;
if (fill <= 0)
fill += COLS;
if (fill < 0)
fill = 0;
#endif
/* If the terminal is very flat, don't set up a titlebar. */
if (LINES < 3) {
editwinrows = 1;
/* Set up two subwindows. If the terminal is just one line,
* edit window and statusbar window will cover each other. */
edit = newwin(1, COLS, 0, 0);
bottomwin = newwin(1, COLS, LINES - 1, 0);
} else {
int toprows = (ISSET(MORE_SPACE) ? 1 : (LINES < 6) ? 1 : 2);
int bottomrows = (ISSET(NO_HELP) ? 1 : (LINES < 5) ? 1 : 3);
if (topwin != NULL)
delwin(topwin);
if (edit != NULL)
delwin(edit);
if (bottomwin != NULL)
delwin(bottomwin);
editwinrows = LINES - toprows - bottomrows;
/* Set up the windows. */
topwin = newwin(TOP_ROWS, COLS, 0, 0);
edit = newwin(editwinrows, COLS, TOP_ROWS, 0);
bottomwin = newwin(BOTTOM_ROWS, COLS, TOP_ROWS + editwinrows, 0);
/* Set up the normal three subwindows. */
topwin = newwin(toprows, COLS, 0, 0);
edit = newwin(editwinrows, COLS, toprows, 0);
bottomwin = newwin(bottomrows, COLS, toprows + editwinrows, 0);
}
/* In case the terminal shrunk, make sure the status line is clear. */
blank_statusbar();
wnoutrefresh(bottomwin);
/* Turn the keypad on for the windows, if necessary. */
if (!ISSET(REBIND_KEYPAD)) {
@@ -727,6 +724,15 @@ void window_init(void)
keypad(edit, TRUE);
keypad(bottomwin, TRUE);
}
#ifndef DISABLE_WRAPJUSTIFY
/* Set up the wrapping point, accounting for screen width when negative. */
fill = wrap_at;
if (fill <= 0)
fill += COLS;
if (fill < 0)
fill = 0;
#endif
}
#ifndef DISABLE_MOUSE
@@ -791,13 +797,11 @@ void print_opt_full(const char *shortflag
void usage(void)
{
printf(_("Usage: nano [OPTIONS] [[+LINE,COLUMN] FILE]...\n\n"));
printf(
#ifdef HAVE_GETOPT_LONG
_("Option\t\tGNU long option\t\tMeaning\n")
printf(_("Option\t\tGNU long option\t\tMeaning\n"));
#else
_("Option\t\tMeaning\n")
printf(_("Option\t\tMeaning\n"));
#endif
);
print_opt(_("+LINE,COLUMN"), "",
/* TRANSLATORS: The next forty or so strings are option descriptions
* for the --help output. Try to keep them at most 40 characters. */
@@ -862,7 +866,7 @@ void usage(void)
#ifndef NANO_TINY
print_opt("-W", "--wordbounds",
N_("Detect word boundaries more accurately"));
print_opt("-X", "--wordchars",
print_opt(_("-X <str>"), _("--wordchars=<str>"),
N_("Which other characters are word parts"));
#endif
#ifndef DISABLE_COLOR
@@ -878,6 +882,9 @@ void usage(void)
print_opt("-i", "--autoindent", N_("Automatically indent new lines"));
print_opt("-k", "--cut", N_("Cut from cursor to end of line"));
#endif
#ifdef ENABLE_LINENUMBERS
print_opt("-l", "--linenumbers", N_("Show line numbers in front of the text"));
#endif
#ifndef DISABLE_MOUSE
print_opt("-m", "--mouse", N_("Enable the use of the mouse"));
#endif
@@ -923,9 +930,9 @@ void usage(void)
void version(void)
{
#ifdef REVISION
printf(" nano from git, %s\n", REVISION);
printf(" GNU nano from git, %s\n", REVISION);
#else
printf(_(" nano, version %s\n"), VERSION);
printf(_(" GNU nano, version %s\n"), VERSION);
#endif
printf(" (C) 1999..2016 Free Software Foundation, Inc.\n");
printf(_(" (C) 2014..%s the contributors to nano\n"), "2016");
@@ -956,6 +963,9 @@ void version(void)
#ifdef HAVE_LIBMAGIC
printf(" --enable-libmagic");
#endif
#ifdef ENABLE_LINENUMBERS
printf(" --enable-linenumbers");
#endif
#ifndef DISABLE_MOUSE
printf(" --enable-mouse");
#endif
@@ -1002,6 +1012,9 @@ void version(void)
#ifndef HAVE_LIBMAGIC
printf(" --disable-libmagic");
#endif
#ifndef ENABLE_LINENUMBERS
printf(" --disable-linenumbers");
#endif
#ifdef DISABLE_MOUSE
printf(" --disable-mouse");
#endif
@@ -1172,9 +1185,9 @@ void stdin_pager(void)
tcsetattr(0, TCSANOW, &oldterm);
fprintf(stderr, _("Reading from stdin, ^C to abort\n"));
#ifndef NANO_TINY
/* Enable interpretation of the special control keys so that
* we get SIGINT when Ctrl-C is pressed. */
#ifndef NANO_TINY
enable_signals();
#endif
@@ -1294,7 +1307,7 @@ RETSIGTYPE do_continue(int signal)
/* Restore the terminal to its previous state. */
terminal_init();
/* Redraw the contents of the windows that need it. */
/* Wipe statusbar; redraw titlebar and edit window (and help lines). */
blank_statusbar();
wnoutrefresh(bottomwin);
total_refresh();
@@ -1334,6 +1347,7 @@ void regenerate_screen(void)
COLS = win.ws_col;
LINES = win.ws_row;
#endif
editwincols = COLS - margin;
#ifdef USE_SLANG
/* Slang curses emulation brain damage, part 1: If we just do what
@@ -1407,9 +1421,12 @@ void do_toggle(int flag)
break;
#ifndef DISABLE_COLOR
case NO_COLOR_SYNTAX:
#endif
#ifdef ENABLE_LINENUMBERS
case LINE_NUMBERS:
#endif
case SOFTWRAP:
edit_refresh();
refresh_needed = TRUE;
break;
}
@@ -1428,13 +1445,13 @@ void do_toggle(int flag)
statusline(HUSH, "%s %s", _(flagtostr(flag)),
enabled ? _("enabled") : _("disabled"));
}
#endif /* !NANO_TINY */
/* Bleh. */
void do_toggle_void(void)
{
;
}
#endif /* !NANO_TINY */
/* Disable extended input and output processing in our terminal
* settings. */
@@ -1536,10 +1553,23 @@ void terminal_init(void)
#endif
}
#ifdef HAVE_KEY_DEFINED
/* Ask ncurses for a keycode, or assign a default one. */
int get_keycode(const char *keyname, const int standard)
{
const char *keyvalue = tigetstr(keyname);
if (keyvalue == 0 || keyvalue == (char *)-1)
return standard;
else
return key_defined(keyvalue);
}
#endif
/* Say that an unbound key was struck, and if possible which one. */
void unbound_key(int code)
{
if (func_key)
if (!is_byte(code))
statusline(ALERT, _("Unbound key"));
else if (meta_key) {
if (code == '[')
@@ -1577,7 +1607,7 @@ int do_input(bool allow_funcs)
#endif
#ifndef DISABLE_MOUSE
if (func_key && input == KEY_MOUSE) {
if (input == KEY_MOUSE) {
/* We received a mouse click. */
if (do_mouse() == 1)
/* The click was on a shortcut -- read in the character
@@ -1599,95 +1629,110 @@ int do_input(bool allow_funcs)
/* If we got a non-high-bit control key, a meta key sequence, or a
* function key, and it's not a shortcut or toggle, throw it out. */
if (!have_shortcut) {
if (is_ascii_cntrl_char(input) || meta_key || func_key) {
if (is_ascii_cntrl_char(input) || meta_key || !is_byte(input)) {
unbound_key(input);
meta_key = FALSE;
func_key = FALSE;
input = ERR;
}
}
if (allow_funcs) {
/* If the keystroke isn't a shortcut nor a toggle, it's a normal text
* character: add the character to the input buffer -- or display a
* warning when we're in view mode. */
if (input != ERR && !have_shortcut) {
if (ISSET(VIEW_MODE))
print_view_warning();
else {
/* Store the byte, and leave room for a terminating zero. */
puddle = charealloc(puddle, depth + 2);
puddle[depth++] = (char)input;
}
}
if (!allow_funcs)
return input;
/* If we got a shortcut or toggle, or if there aren't any other
* characters waiting after the one we read in, we need to output
* all available characters in the input puddle. Note that this
* puddle will be empty if we're in view mode. */
if (have_shortcut || get_key_buffer_len() == 0) {
/* If the keystroke isn't a shortcut nor a toggle, it's a normal text
* character: add the character to the input buffer -- or display a
* warning when we're in view mode. */
if (input != ERR && !have_shortcut) {
if (ISSET(VIEW_MODE))
print_view_warning();
else {
/* Store the byte, and leave room for a terminating zero. */
puddle = charealloc(puddle, depth + 2);
puddle[depth++] = (char)input;
}
#ifndef NANO_TINY
if (openfile->mark_set && openfile->kind_of_mark == SOFTMARK) {
openfile->mark_set = FALSE;
refresh_needed = TRUE;
}
#endif
}
/* If we got a shortcut or toggle, or if there aren't any other
* characters waiting after the one we read in, we need to output
* all available characters in the input puddle. Note that this
* puddle will be empty if we're in view mode. */
if (have_shortcut || get_key_buffer_len() == 0) {
#ifndef DISABLE_WRAPPING
/* If we got a shortcut or toggle, and it's not the shortcut
* for verbatim input, turn off prepending of wrapped text. */
if (have_shortcut && s->scfunc != do_verbatim_input)
wrap_reset();
/* If we got a shortcut or toggle, and it's not the shortcut
* for verbatim input, turn off prepending of wrapped text. */
if (have_shortcut && s->scfunc != do_verbatim_input)
wrap_reset();
#endif
if (puddle != NULL) {
/* Insert all bytes in the input buffer into the edit buffer
* at once, filtering out any low control codes. */
puddle[depth] = '\0';
do_output(puddle, depth, FALSE);
if (puddle != NULL) {
/* Insert all bytes in the input buffer into the edit buffer
* at once, filtering out any low control codes. */
puddle[depth] = '\0';
do_output(puddle, depth, FALSE);
/* Empty the input buffer. */
free(puddle);
puddle = NULL;
depth = 0;
}
/* Empty the input buffer. */
free(puddle);
puddle = NULL;
depth = 0;
}
}
if (have_shortcut) {
const subnfunc *f = sctofunc(s);
if (ISSET(VIEW_MODE) && f && !f->viewok) {
print_view_warning();
return ERR;
}
if (have_shortcut) {
const subnfunc *f = sctofunc(s);
/* If the function associated with this shortcut is
* cutting or copying text, remember this. */
if (s->scfunc == do_cut_text_void
/* If the function associated with this shortcut is
* cutting or copying text, remember this. */
if (s->scfunc == do_cut_text_void
#ifndef NANO_TINY
|| s->scfunc == do_copy_text || s->scfunc == do_cut_till_eof
#endif
)
preserve = TRUE;
preserve = TRUE;
if (s->scfunc == NULL) {
statusbar("Internal error: shortcut without function!");
return ERR;
}
if (ISSET(VIEW_MODE) && f && !f->viewok)
print_view_warning();
else {
#ifndef NANO_TINY
if (s->scfunc == do_toggle_void) {
do_toggle(s->toggle);
if (s->toggle != CUT_TO_END)
preserve = TRUE;
} else
if (s->scfunc == do_toggle_void) {
do_toggle(s->toggle);
if (s->toggle != CUT_TO_END)
preserve = TRUE;
} else
#endif
{
/* Execute the function of the shortcut. */
s->scfunc();
#ifndef DISABLE_COLOR
if (f && !f->viewok)
reset_multis(openfile->current, FALSE);
#endif
if (refresh_needed) {
#ifdef DEBUG
fprintf(stderr, "running edit_refresh() as refresh_needed is true\n");
#endif
edit_refresh();
refresh_needed = FALSE;
} else if (s->scfunc == do_delete || s->scfunc == do_backspace)
update_line(openfile->current, openfile->current_x);
}
{
#ifndef NANO_TINY
/* If Shifted movement occurs, set the mark. */
if (shift_held && !openfile->mark_set) {
openfile->mark_set = TRUE;
openfile->mark_begin = openfile->current;
openfile->mark_begin_x = openfile->current_x;
openfile->kind_of_mark = SOFTMARK;
}
#endif
/* Execute the function of the shortcut. */
s->scfunc();
#ifndef NANO_TINY
/* If Shiftless movement occurred, discard a soft mark. */
if (openfile->mark_set && !shift_held &&
openfile->kind_of_mark == SOFTMARK) {
openfile->mark_set = FALSE;
openfile->mark_begin = NULL;
refresh_needed = TRUE;
}
#endif
#ifndef DISABLE_COLOR
if (f && !f->viewok)
reset_multis(openfile->current, FALSE);
#endif
if (!refresh_needed && (s->scfunc == do_delete || s->scfunc == do_backspace))
update_line(openfile->current, openfile->current_x);
}
}
@@ -1845,8 +1890,11 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
continue;
/* If we're adding to the magicline, create a new magicline. */
if (!ISSET(NO_NEWLINES) && openfile->filebot == openfile->current)
if (!ISSET(NO_NEWLINES) && openfile->filebot == openfile->current) {
new_magicline();
if (margin > 0)
refresh_needed = TRUE;
}
assert(openfile->current_x <= current_len);
@@ -1886,6 +1934,8 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
}
#ifndef NANO_TINY
ensure_line_is_visible();
/* Well, we might also need a full refresh if we've changed the
* line length to be a new multiple of COLS. */
if (ISSET(SOFTWRAP) && refresh_needed == FALSE)
@@ -1901,10 +1951,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
reset_multis(openfile->current, FALSE);
#endif
if (refresh_needed == TRUE) {
edit_refresh();
refresh_needed = FALSE;
} else
if (!refresh_needed)
update_line(openfile->current, openfile->current_x);
}
@@ -1949,7 +1996,13 @@ int main(int argc, char **argv)
#endif
{"constantshow", 0, NULL, 'c'},
{"rebinddelete", 0, NULL, 'd'},
#ifndef DISABLE_BROWSER
{"showcursor", 0, NULL, 'g'},
#endif
{"help", 0, NULL, 'h'},
#ifdef ENABLE_LINENUMBERS
{"linenumbers", 0, NULL, 'l'},
#endif
#ifndef DISABLE_MOUSE
{"mouse", 0, NULL, 'm'},
#endif
@@ -2043,7 +2096,6 @@ int main(int argc, char **argv)
case 'b':
case 'e':
case 'f':
case 'g':
case 'j':
/* Pico compatibility flags. */
break;
@@ -2152,6 +2204,9 @@ int main(int argc, char **argv)
case 'd':
SET(REBIND_DELETE);
break;
case 'g':
SET(SHOW_CURSOR);
break;
#ifndef NANO_TINY
case 'i':
SET(AUTOINDENT);
@@ -2228,6 +2283,11 @@ int main(int argc, char **argv)
case '$':
SET(SOFTWRAP);
break;
#endif
#ifdef ENABLE_LINENUMBERS
case 'l':
SET(LINE_NUMBERS);
break;
#endif
case 'h':
usage();
@@ -2487,6 +2547,11 @@ int main(int argc, char **argv)
/* Set up the terminal state. */
terminal_init();
#ifdef __linux__
/* Check whether we're running on a Linux console. */
console = (getenv("DISPLAY") == NULL);
#endif
#ifdef DEBUG
fprintf(stderr, "Main: set up windows\n");
#endif
@@ -2495,6 +2560,8 @@ int main(int argc, char **argv)
* dimensions. */
window_init();
editwincols = COLS;
/* Set up the signal handlers. */
signal_init();
@@ -2507,26 +2574,30 @@ int main(int argc, char **argv)
set_colorpairs();
#else
interface_color_pair[TITLE_BAR] = hilite_attribute;
interface_color_pair[LINE_NUMBER] = hilite_attribute;
interface_color_pair[STATUS_BAR] = hilite_attribute;
interface_color_pair[KEY_COMBO] = hilite_attribute;
interface_color_pair[FUNCTION_TAG] = A_NORMAL;
#endif
#if !defined(NANO_TINY) && defined(HAVE_KEY_DEFINED)
const char *keyvalue;
#ifdef HAVE_KEY_DEFINED
/* Ask ncurses for the key codes for Control+Left/Right/Up/Down. */
keyvalue = tigetstr("kLFT5");
if (keyvalue != 0 && keyvalue != (char *)-1)
controlleft = key_defined(keyvalue);
keyvalue = tigetstr("kRIT5");
if (keyvalue != 0 && keyvalue != (char *)-1)
controlright = key_defined(keyvalue);
keyvalue = tigetstr("kUP5");
if (keyvalue != 0 && keyvalue != (char *)-1)
controlup = key_defined(keyvalue);
keyvalue = tigetstr("kDN5");
if (keyvalue != 0 && keyvalue != (char *)-1)
controldown = key_defined(keyvalue);
controlleft = get_keycode("kLFT5", CONTROL_LEFT);
controlright = get_keycode("kRIT5", CONTROL_RIGHT);
controlup = get_keycode("kUP5", CONTROL_UP);
controldown = get_keycode("kDN5", CONTROL_DOWN);
#endif
#if !defined(NANO_TINY) && defined(HAVE_KEY_DEFINED)
/* Ask for the codes for Shift+Control+Left/Right/Up/Down. */
shiftcontrolleft = get_keycode("kLFT6", SHIFT_CONTROL_LEFT);
shiftcontrolright = get_keycode("kRIT6", SHIFT_CONTROL_RIGHT);
shiftcontrolup = get_keycode("kUP6", SHIFT_CONTROL_UP);
shiftcontroldown = get_keycode("kDN6", SHIFT_CONTROL_DOWN);
/* Ask for the codes for Shift+Alt+Left/Right/Up/Down. */
shiftaltleft = get_keycode("kLFT4", SHIFT_ALT_LEFT);
shiftaltright = get_keycode("kRIT4", SHIFT_ALT_RIGHT);
shiftaltup = get_keycode("kUP4", SHIFT_ALT_UP);
shiftaltdown = get_keycode("kDN4", SHIFT_ALT_DOWN);
#endif
#ifndef USE_SLANG
@@ -2546,6 +2617,7 @@ int main(int argc, char **argv)
optind++;
}
/* If one of the arguments is a dash, read text from standard input. */
if (optind < argc && !strcmp(argv[optind], "-")) {
stdin_pager();
set_modified();
@@ -2622,12 +2694,30 @@ int main(int argc, char **argv)
#endif
#ifdef DEBUG
fprintf(stderr, "Main: bottom win, top win and edit win\n");
fprintf(stderr, "Main: show buffer contents, and enter main loop\n");
#endif
display_buffer();
while (TRUE) {
#ifdef ENABLE_LINENUMBERS
int needed_margin = digits(openfile->filebot->lineno) + 1;
/* Only enable line numbers when there is enough room for them. */
if (ISSET(LINE_NUMBERS) && needed_margin < COLS - 3) {
if (needed_margin != margin) {
margin = needed_margin;
editwincols = COLS - margin;
/* The margin has changed -- schedule a full refresh. */
refresh_needed = TRUE;
}
} else
#endif
{
margin = 0;
editwincols = COLS;
}
if (currmenu != MMAIN)
display_main_list();
@@ -2643,10 +2733,14 @@ int main(int argc, char **argv)
/* Forget any earlier statusbar x position. */
reinit_statusbar_x();
/* Place the cursor in the edit window and make it visible. */
reset_cursor();
curs_set(1);
wnoutrefresh(edit);
/* Refresh either the entire edit window or just the cursor. */
if (refresh_needed)
edit_refresh();
else {
reset_cursor();
curs_set(1);
wnoutrefresh(edit);
}
/* Read in and interpret keystrokes. */
do_input(TRUE);

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* nano.h *
* nano.h -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -179,6 +179,10 @@ typedef enum {
OVERWRITE, APPEND, PREPEND
} kind_of_writing_type;
typedef enum {
SOFTMARK, HARDMARK
} mark_type;
typedef enum {
UPWARD, DOWNWARD
} scroll_dir;
@@ -187,10 +191,6 @@ typedef enum {
CENTERING, FLOWING, STATIONARY
} update_type;
typedef enum {
CONTROL, META, FKEY, RAWINPUT
} key_type;
typedef enum {
ADD, DEL, BACK, CUT, CUT_EOF, REPLACE,
#ifndef DISABLE_WRAPPING
@@ -397,6 +397,8 @@ typedef struct openfilestruct {
/* The file's y-coordinate position. */
bool modified;
/* Whether the file has been modified. */
struct stat *current_stat;
/* The file's current stat information. */
#ifndef NANO_TINY
bool mark_set;
/* Whether the mark is on in this file. */
@@ -404,10 +406,10 @@ typedef struct openfilestruct {
/* The file's line where the mark is, if any. */
size_t mark_begin_x;
/* The file's mark's x-coordinate position, if any. */
mark_type kind_of_mark;
/* Whether this is a soft or a hard mark. */
file_format fmt;
/* The file's format. */
struct stat *current_stat;
/* The file's current stat information. */
undo *undotop;
/* The top of the undo list. */
undo *current_undo;
@@ -439,21 +441,23 @@ typedef struct rcoption {
#endif
typedef struct sc {
char *keystr;
/* The shortcut key for a function, ASCII version. */
key_type type;
/* What kind of command key it is, for convenience later. */
int seq;
/* The actual sequence to check once the type is determined. */
const char *keystr;
/* The string that describes a keystroke, like "^C" or "M-R". */
bool meta;
/* Whether this is a Meta keystroke. */
int keycode;
/* The integer that, together with meta, identifies the keystroke. */
int menus;
/* Which menus this applies to. */
void (*scfunc)(void);
/* The function we're going to run. */
#ifndef NANO_TINY
int toggle;
/* If a toggle, what we're toggling. */
int ordinal;
/* The how-manieth toggle this is, in order to be able to
* keep them in sequence. */
#endif
struct sc *next;
/* Next in the list. */
} sc;
@@ -484,6 +488,7 @@ typedef struct subnfunc {
enum
{
TITLE_BAR = 0,
LINE_NUMBER,
STATUS_BAR,
KEY_COMBO,
FUNCTION_TAG,
@@ -531,7 +536,9 @@ enum
LOCKING,
NOREAD_MODE,
MAKE_IT_UNIX,
JUSTIFY_TRIM
JUSTIFY_TRIM,
SHOW_CURSOR,
LINE_NUMBERS
};
/* Flags for the menus in which a given function should be present. */
@@ -554,18 +561,28 @@ enum
#define MMOST (MMAIN|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE|MWRITEFILE|MINSERTFILE|\
MEXTCMD|MBROWSER|MWHEREISFILE|MGOTODIR|MSPELL|MLINTER)
/* Control key sequences. Changing these would be very, very bad. */
#define NANO_CONTROL_SPACE 0
#define NANO_CONTROL_I 9
#define NANO_CONTROL_3 27
#define NANO_CONTROL_7 31
#define NANO_CONTROL_8 127
/* Basic control codes. */
#define TAB_CODE 0x09
#define ESC_CODE 0x1B
#define DEL_CODE 0x7F
/* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
#define CONTROL_LEFT 0x401
#define CONTROL_RIGHT 0x402
#define CONTROL_UP 0x403
#define CONTROL_DOWN 0x404
#define SHIFT_CONTROL_LEFT 0x405
#define SHIFT_CONTROL_RIGHT 0x406
#define SHIFT_CONTROL_UP 0x407
#define SHIFT_CONTROL_DOWN 0x408
#define SHIFT_ALT_LEFT 0x409
#define SHIFT_ALT_RIGHT 0x40a
#define SHIFT_ALT_UP 0x40b
#define SHIFT_ALT_DOWN 0x40c
#define SHIFT_PAGEUP 0x40d
#define SHIFT_PAGEDOWN 0x40e
#define SHIFT_HOME 0x40f
#define SHIFT_END 0x410
#ifndef NANO_TINY
/* An imaginary key for when we get a SIGWINCH (window resize). */
@@ -582,11 +599,6 @@ enum
/* The maximum number of entries displayed in the main shortcut list. */
#define MAIN_VISIBLE (((COLS + 40) / 20) * 2)
/* The minimum editor window columns and rows required for nano to work
* correctly. Don't make these smaller than 4 and 1. */
#define MIN_EDITOR_COLS 4
#define MIN_EDITOR_ROWS 1
/* The default number of characters from the end of the line where
* wrapping occurs. */
#define CHARS_FROM_EOL 8

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* prompt.c *
* prompt.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -28,15 +28,12 @@
static char *prompt = NULL;
/* The prompt string used for statusbar questions. */
static size_t statusbar_x = (size_t)-1;
static size_t statusbar_x = HIGHEST_POSITIVE;
/* The cursor position in answer. */
static size_t statusbar_pww = (size_t)-1;
/* The place we want in answer. */
/* Read in a character, interpret it as a shortcut or toggle if
* necessary, and return it.
* Set ran_func to TRUE if we ran a function associated with a
* shortcut key, and set finished to TRUE if we're done after running
/* Read in a keystroke, interpret it if it is a shortcut or toggle, and
* return it. Set ran_func to TRUE if we ran a function associated with
* a shortcut key, and set finished to TRUE if we're done after running
* or trying to run a function associated with a shortcut key.
* refresh_func is the function we will call to refresh the edit window. */
int do_statusbar_input(bool *ran_func, bool *finished,
@@ -66,14 +63,11 @@ int do_statusbar_input(bool *ran_func, bool *finished,
#ifndef DISABLE_MOUSE
/* If we got a mouse click and it was on a shortcut, read in the
* shortcut character. */
if (func_key && input == KEY_MOUSE) {
if (input == KEY_MOUSE) {
if (do_statusbar_mouse() == 1)
input = get_kbinput(bottomwin);
else {
meta_key = FALSE;
func_key = FALSE;
input = ERR;
}
else
return ERR;
}
#endif
@@ -87,107 +81,100 @@ int do_statusbar_input(bool *ran_func, bool *finished,
/* If we got a non-high-bit control key, a meta key sequence, or a
* function key, and it's not a shortcut or toggle, throw it out. */
if (!have_shortcut) {
if (is_ascii_cntrl_char(input) || meta_key || func_key) {
if (is_ascii_cntrl_char(input) || meta_key || !is_byte(input)) {
beep();
meta_key = FALSE;
func_key = FALSE;
input = ERR;
}
}
/* If we got a character, and it isn't a shortcut or toggle,
* it's a normal text character. Display the warning if we're
* in view mode, or add the character to the input buffer if
* we're not. */
/* If the keystroke isn't a shortcut nor a toggle, it's a normal text
* character: add the it to the input buffer, when allowed. */
if (input != ERR && !have_shortcut) {
/* If we're using restricted mode, the filename isn't blank,
* and we're at the "Write File" prompt, disable text input. */
if (!ISSET(RESTRICTED) || openfile->filename[0] == '\0' ||
currmenu != MWRITEFILE) {
/* Only accept input when not in restricted mode, or when not at
* the "Write File" prompt, or when there is no filename yet. */
if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
openfile->filename[0] == '\0') {
kbinput_len++;
kbinput = (int *)nrealloc(kbinput, kbinput_len * sizeof(int));
kbinput[kbinput_len - 1] = input;
}
}
/* If we got a shortcut, or if there aren't any other characters
* waiting after the one we read in, we need to display all the
* characters in the input buffer if it isn't empty. */
if (have_shortcut || get_key_buffer_len() == 0) {
if (kbinput != NULL) {
/* Display all the characters in the input buffer at
* once, filtering out control characters. */
do_statusbar_output(kbinput, kbinput_len, TRUE, NULL);
/* If we got a shortcut, or if there aren't any other keystrokes waiting
* after the one we read in, we need to insert all the characters in the
* input buffer (if not empty) into the answer. */
if ((have_shortcut || get_key_buffer_len() == 0) && kbinput != NULL) {
/* Inject all characters in the input buffer at once, filtering out
* control characters. */
do_statusbar_output(kbinput, kbinput_len, TRUE, NULL);
/* Empty the input buffer. */
kbinput_len = 0;
free(kbinput);
kbinput = NULL;
}
/* Empty the input buffer. */
kbinput_len = 0;
free(kbinput);
kbinput = NULL;
}
if (have_shortcut) {
if (s->scfunc == do_tab || s->scfunc == do_enter)
;
else if (s->scfunc == total_refresh) {
total_redraw();
refresh_func();
} else if (s->scfunc == do_left)
do_statusbar_left();
else if (s->scfunc == do_right)
do_statusbar_right();
if (have_shortcut) {
if (s->scfunc == do_tab || s->scfunc == do_enter)
;
else if (s->scfunc == total_refresh) {
total_redraw();
refresh_func();
} else if (s->scfunc == do_left)
do_statusbar_left();
else if (s->scfunc == do_right)
do_statusbar_right();
#ifndef NANO_TINY
else if (s->scfunc == do_prev_word_void)
do_statusbar_prev_word();
else if (s->scfunc == do_next_word_void)
do_statusbar_next_word();
else if (s->scfunc == do_prev_word_void)
do_statusbar_prev_word();
else if (s->scfunc == do_next_word_void)
do_statusbar_next_word();
#endif
else if (s->scfunc == do_home)
do_statusbar_home();
else if (s->scfunc == do_end)
do_statusbar_end();
/* When in restricted mode at the "Write File" prompt and the
* filename isn't blank, disallow any input and deletion. */
else if (ISSET(RESTRICTED) && currmenu == MWRITEFILE &&
else if (s->scfunc == do_home)
do_statusbar_home();
else if (s->scfunc == do_end)
do_statusbar_end();
/* When in restricted mode at the "Write File" prompt and the
* filename isn't blank, disallow any input and deletion. */
else if (ISSET(RESTRICTED) && currmenu == MWRITEFILE &&
openfile->filename[0] != '\0' &&
(s->scfunc == do_verbatim_input ||
s->scfunc == do_cut_text_void ||
s->scfunc == do_delete ||
s->scfunc == do_backspace))
;
else if (s->scfunc == do_verbatim_input) {
bool got_newline = FALSE;
/* Whether we got a verbatim ^J. */
;
else if (s->scfunc == do_verbatim_input) {
bool got_newline = FALSE;
/* Whether we got a verbatim ^J. */
do_statusbar_verbatim_input(&got_newline);
do_statusbar_verbatim_input(&got_newline);
/* If we got a verbatim ^J, remove it from the input buffer,
* fake a press of Enter, and indicate that we're done. */
if (got_newline) {
get_input(NULL, 1);
input = sc_seq_or(do_enter, 0);
*finished = TRUE;
}
} else if (s->scfunc == do_cut_text_void) {
do_statusbar_cut_text();
} else if (s->scfunc == do_delete) {
do_statusbar_delete();
} else if (s->scfunc == do_backspace) {
do_statusbar_backspace();
} else {
/* Handle any other shortcut in the current menu, setting
* ran_func to TRUE if we try to run their associated
* functions and setting finished to TRUE to indicate
* that we're done after running or trying to run their
* associated functions. */
f = sctofunc(s);
if (s->scfunc != NULL) {
*ran_func = TRUE;
if (f && (!ISSET(VIEW_MODE) || f->viewok) &&
f->scfunc != do_gotolinecolumn_void)
f->scfunc();
}
/* If we got a verbatim ^J, remove it from the input buffer,
* fake a press of Enter, and indicate that we're done. */
if (got_newline) {
get_input(NULL, 1);
input = sc_seq_or(do_enter, 0);
*finished = TRUE;
}
} else if (s->scfunc == do_cut_text_void)
do_statusbar_cut_text();
else if (s->scfunc == do_delete)
do_statusbar_delete();
else if (s->scfunc == do_backspace)
do_statusbar_backspace();
else {
/* Handle any other shortcut in the current menu, setting
* ran_func to TRUE if we try to run their associated functions,
* and setting finished to TRUE to indicatethat we're done after
* running or trying to run their associated functions. */
f = sctofunc(s);
if (s->scfunc != NULL) {
*ran_func = TRUE;
if (f && (!ISSET(VIEW_MODE) || f->viewok) &&
f->scfunc != do_gotolinecolumn_void)
f->scfunc();
}
*finished = TRUE;
}
}
@@ -205,8 +192,6 @@ int do_statusbar_mouse(void)
if (retval == 0 && wmouse_trafo(bottomwin, &mouse_y, &mouse_x, FALSE)) {
size_t start_col;
assert(prompt != NULL);
start_col = strlenpt(prompt) + 2;
/* Move to where the click occurred. */
@@ -214,7 +199,7 @@ int do_statusbar_mouse(void)
statusbar_x = actual_x(answer,
get_statusbar_page_start(start_col, start_col +
statusbar_xplustabs()) + mouse_x - start_col);
update_bar_if_needed();
update_the_statusbar();
}
}
@@ -232,8 +217,6 @@ void do_statusbar_output(int *the_input, size_t input_len,
char *char_buf = charalloc(mb_cur_max());
int i, char_len;
assert(answer != NULL);
/* Copy the typed stuff so it can be treated. */
for (i = 0; i < input_len; i++)
output[i] = (char)the_input[i];
@@ -264,8 +247,6 @@ void do_statusbar_output(int *the_input, size_t input_len,
if (filtering && is_ascii_cntrl_char(*(output + i - char_len)))
continue;
assert(statusbar_x <= strlen(answer));
/* Insert the typed character into the existing answer string. */
answer = charealloc(answer, strlen(answer) + char_len + 1);
charmove(answer + statusbar_x + char_len, answer + statusbar_x,
@@ -278,23 +259,21 @@ void do_statusbar_output(int *the_input, size_t input_len,
free(char_buf);
free(output);
statusbar_pww = statusbar_xplustabs();
update_the_statusbar();
}
/* Move to the beginning of the prompt text. */
/* Move to the beginning of the answer. */
void do_statusbar_home(void)
{
statusbar_x = 0;
update_bar_if_needed();
update_the_statusbar();
}
/* Move to the end of the prompt text. */
/* Move to the end of the answer. */
void do_statusbar_end(void)
{
statusbar_x = strlen(answer);
update_bar_if_needed();
update_the_statusbar();
}
/* Move left one character. */
@@ -302,16 +281,16 @@ void do_statusbar_left(void)
{
if (statusbar_x > 0) {
statusbar_x = move_mbleft(answer, statusbar_x);
update_bar_if_needed();
update_the_statusbar();
}
}
/* Move right one character. */
void do_statusbar_right(void)
{
if (statusbar_x < strlen(answer)) {
if (answer[statusbar_x] != '\0') {
statusbar_x = move_mbright(answer, statusbar_x);
update_bar_if_needed();
update_the_statusbar();
}
}
@@ -327,13 +306,9 @@ void do_statusbar_backspace(void)
/* Delete one character. */
void do_statusbar_delete(void)
{
statusbar_pww = statusbar_xplustabs();
if (answer[statusbar_x] != '\0') {
int char_len = parse_mbchar(answer + statusbar_x, NULL, NULL);
assert(statusbar_x < strlen(answer));
charmove(answer + statusbar_x, answer + statusbar_x + char_len,
strlen(answer) - statusbar_x - char_len + 1);
align(&answer);
@@ -342,33 +317,23 @@ void do_statusbar_delete(void)
}
}
/* Move text from the prompt into oblivion. */
/* Zap some or all text from the answer. */
void do_statusbar_cut_text(void)
{
assert(answer != NULL);
#ifndef NANO_TINY
if (ISSET(CUT_TO_END))
null_at(&answer, statusbar_x);
else
#endif
{
null_at(&answer, 0);
if (!ISSET(CUT_TO_END))
statusbar_x = 0;
statusbar_pww = statusbar_xplustabs();
}
null_at(&answer, statusbar_x);
update_the_statusbar();
}
#ifndef NANO_TINY
/* Move to the next word in the prompt text. */
/* Move to the next word in the answer. */
void do_statusbar_next_word(void)
{
bool seen_space = !is_word_mbchar(answer + statusbar_x, FALSE);
assert(answer != NULL);
/* Move forward until we reach the start of a word. */
while (answer[statusbar_x] != '\0') {
statusbar_x = move_mbright(answer, statusbar_x);
@@ -381,16 +346,14 @@ void do_statusbar_next_word(void)
break;
}
update_bar_if_needed();
update_the_statusbar();
}
/* Move to the previous word in the prompt text. */
/* Move to the previous word in the answer. */
void do_statusbar_prev_word(void)
{
bool seen_a_word = FALSE, step_forward = FALSE;
assert(answer != NULL);
/* Move backward until we pass over the start of a word. */
while (statusbar_x != 0) {
statusbar_x = move_mbleft(answer, statusbar_x);
@@ -408,7 +371,7 @@ void do_statusbar_prev_word(void)
/* Move one character forward again to sit on the start of the word. */
statusbar_x = move_mbright(answer, statusbar_x);
update_bar_if_needed();
update_the_statusbar();
}
#endif /* !NANO_TINY */
@@ -427,95 +390,83 @@ void do_statusbar_verbatim_input(bool *got_newline)
do_statusbar_output(kbinput, kbinput_len, FALSE, got_newline);
}
/* Return the placewewant associated with statusbar_x, i.e. the
* zero-based column position of the cursor. The value will be no
* smaller than statusbar_x. */
/* Return the zero-based column position of the cursor in the answer. */
size_t statusbar_xplustabs(void)
{
return strnlenpt(answer, statusbar_x);
}
/* nano scrolls horizontally within a line in chunks. This function
* returns the column number of the first character displayed in the
* statusbar prompt when the cursor is at the given column with the
* prompt ending at start_col. Note that (0 <= column -
* get_statusbar_page_start(column) < COLS). */
size_t get_statusbar_page_start(size_t start_col, size_t column)
/* Return the column number of the first character of the answer that is
* displayed in the statusbar when the cursor is at the given column,
* with the available room for the answer starting at base. Note that
* (0 <= column - get_statusbar_page_start(column) < COLS). */
size_t get_statusbar_page_start(size_t base, size_t column)
{
if (column == start_col || column < COLS - 1 || COLS == start_col + 1)
if (column == base || column < COLS - 1)
return 0;
else if (COLS > base + 2)
return column - base - 1 - (column - base - 1) % (COLS - base - 2);
else
return column - start_col - (column - start_col) % (COLS -
start_col - 1);
return column - 2;
}
/* Reinitialize the cursor position in the status bar prompt. */
/* Reinitialize the cursor position in the answer. */
void reinit_statusbar_x(void)
{
statusbar_x = (size_t)-1;
statusbar_pww = (size_t)-1;
statusbar_x = HIGHEST_POSITIVE;
}
/* Put the cursor in the statusbar prompt at statusbar_x. */
/* Put the cursor in the answer at statusbar_x. */
void reset_statusbar_cursor(void)
{
size_t start_col = strlenpt(prompt) + 2;
size_t xpt = statusbar_xplustabs();
/* Work around a cursor-misplacement bug in VTEs. */
wmove(bottomwin, 0, 0);
wnoutrefresh(bottomwin);
doupdate();
wmove(bottomwin, 0, start_col + xpt -
get_statusbar_page_start(start_col, start_col + xpt));
get_statusbar_page_start(start_col, start_col + xpt));
wnoutrefresh(bottomwin);
}
/* Repaint the statusbar. */
void update_the_statusbar(void)
{
size_t start_col, index, page_start;
size_t base, the_page, end_page;
char *expanded;
assert(prompt != NULL && statusbar_x <= strlen(answer));
start_col = strlenpt(prompt) + 2;
index = strnlenpt(answer, statusbar_x);
page_start = get_statusbar_page_start(start_col, start_col + index);
base = strlenpt(prompt) + 2;
the_page = get_statusbar_page_start(base, base + strnlenpt(answer, statusbar_x));
end_page = get_statusbar_page_start(base, base + strlenpt(answer) - 1);
wattron(bottomwin, interface_color_pair[TITLE_BAR]);
blank_statusbar();
mvwaddnstr(bottomwin, 0, 0, prompt, actual_x(prompt, COLS - 2));
mvwaddstr(bottomwin, 0, 0, prompt);
waddch(bottomwin, ':');
waddch(bottomwin, (page_start == 0) ? ' ' : '$');
waddch(bottomwin, (the_page == 0) ? ' ' : '<');
expanded = display_string(answer, page_start, COLS - start_col - 1, FALSE);
expanded = display_string(answer, the_page, COLS - base - 1, FALSE);
waddstr(bottomwin, expanded);
free(expanded);
waddch(bottomwin, (the_page >= end_page) ? ' ' : '>');
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
statusbar_pww = statusbar_xplustabs();
reset_statusbar_cursor();
wnoutrefresh(bottomwin);
}
/* Update the statusbar line /if/ the placewewant changes page. */
void update_bar_if_needed(void)
{
size_t start_col = strlenpt(prompt) + 2;
size_t was_pww = statusbar_pww;
statusbar_pww = statusbar_xplustabs();
if (get_statusbar_page_start(start_col, start_col + statusbar_pww) !=
get_statusbar_page_start(start_col, start_col + was_pww))
update_the_statusbar();
}
/* Get a string of input at the statusbar prompt. */
functionptrtype get_prompt_string(int *actual, bool allow_tabs,
functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
#ifndef DISABLE_TABCOMP
bool allow_files, bool *listed,
#endif
const char *curranswer,
#ifndef DISABLE_HISTORIES
filestruct **history_list,
#endif
@@ -543,15 +494,11 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
#endif
#endif /* !DISABLE_HISTORIES */
answer = mallocstrcpy(answer, curranswer);
if (statusbar_x > strlen(answer)) {
if (statusbar_x > strlen(answer))
statusbar_x = strlen(answer);
statusbar_pww = statusbar_xplustabs();
}
#ifdef DEBUG
fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %lu\n", answer, (unsigned long) statusbar_x);
fprintf(stderr, "acquiring: answer = \"%s\", statusbar_x = %lu\n", answer, (unsigned long) statusbar_x);
#endif
update_the_statusbar();
@@ -560,25 +507,24 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
wnoutrefresh(edit);
wnoutrefresh(bottomwin);
/* If we're using restricted mode, we aren't allowed to change the
* name of the current file once it has one, because that would
* allow writing to files not specified on the command line. In
* this case, disable all keys that would change the text if the
* filename isn't blank and we're at the "Write File" prompt. */
while (TRUE) {
/* Ensure the cursor is on when waiting for input. */
/* Ensure the cursor is shown when waiting for input. */
curs_set(1);
kbinput = do_statusbar_input(&ran_func, &finished, refresh_func);
assert(statusbar_x <= strlen(answer));
#ifndef NANO_TINY
/* If the window size changed, go reformat the prompt string. */
if (kbinput == KEY_WINCH) {
refresh_func();
update_the_statusbar();
continue;
}
*actual = KEY_WINCH;
#ifndef DISABLE_HISTORIES
free(magichistory);
#endif
return NULL;
}
#endif /* !NANO_TINY */
func = func_from_key(&kbinput);
if (func == do_cancel || func == do_enter)
@@ -591,7 +537,7 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
if (func == do_tab) {
#ifndef DISABLE_HISTORIES
if (history_list != NULL) {
if (last_kbinput != sc_seq_or(do_tab, NANO_CONTROL_I))
if (last_kbinput != sc_seq_or(do_tab, TAB_CODE))
complete_len = strlen(answer);
if (complete_len > 0) {
@@ -604,8 +550,6 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
if (allow_tabs)
answer = input_tab(answer, allow_files, &statusbar_x,
&tabbed, refresh_func, listed);
update_the_statusbar();
} else
#endif /* !DISABLE_TABCOMP */
#ifndef DISABLE_HISTORIES
@@ -623,8 +567,6 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
statusbar_x = strlen(answer);
}
update_the_statusbar();
/* This key has a shortcut-list entry when it's used to
* move to an older search, which means that finished has
* been set to TRUE. Set it back to FALSE here, so that
@@ -649,8 +591,6 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
statusbar_x = strlen(answer);
}
update_the_statusbar();
/* This key has a shortcut-list entry when it's used to
* move to a newer search, which means that finished has
* been set to TRUE. Set it back to FALSE here, so that
@@ -660,8 +600,6 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
} else
#endif /* !DISABLE_HISTORIES */
if (func == do_help_void) {
update_the_statusbar();
/* This key has a shortcut-list entry when it's used to go to
* the help browser or display a message indicating that help
* is disabled, which means that finished has been set to TRUE.
@@ -675,11 +613,11 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
if (finished)
break;
update_the_statusbar();
#if !defined(DISABLE_HISTORIES) && !defined(DISABLE_TABCOMP)
last_kbinput = kbinput;
#endif
reset_statusbar_cursor();
wnoutrefresh(bottomwin);
}
#ifndef DISABLE_HISTORIES
@@ -718,42 +656,48 @@ int do_prompt(bool allow_tabs,
{
va_list ap;
int retval;
functionptrtype func;
functionptrtype func = NULL;
#ifndef DISABLE_TABCOMP
bool listed = FALSE;
#endif
/* Save a possible current statusbar x position. */
size_t was_statusbar_x = statusbar_x;
size_t was_pww = statusbar_pww;
prompt = charalloc(((COLS - 4) * mb_cur_max()) + 1);
bottombars(menu);
va_start(ap, msg);
vsnprintf(prompt, (COLS - 4) * mb_cur_max(), msg, ap);
va_end(ap);
null_at(&prompt, actual_x(prompt, COLS - 4));
answer = mallocstrcpy(answer, curranswer);
func = get_prompt_string(&retval, allow_tabs,
#ifndef NANO_TINY
redo_theprompt:
#endif
prompt = charalloc((COLS * mb_cur_max()) + 1);
va_start(ap, msg);
vsnprintf(prompt, COLS * mb_cur_max(), msg, ap);
va_end(ap);
/* Reserve five columns for colon plus angles plus answer, ":<aa>". */
null_at(&prompt, actual_x(prompt, (COLS < 5) ? 0 : COLS - 5));
func = acquire_an_answer(&retval, allow_tabs,
#ifndef DISABLE_TABCOMP
allow_files, &listed,
#endif
curranswer,
#ifndef DISABLE_HISTORIES
history_list,
history_list,
#endif
refresh_func);
refresh_func);
free(prompt);
prompt = NULL;
#ifndef NANO_TINY
if (retval == KEY_WINCH)
goto redo_theprompt;
#endif
/* If we're done with this prompt, restore the x position to what
* it was at a possible previous prompt. */
if (func == do_cancel || func == do_enter) {
if (func == do_cancel || func == do_enter)
statusbar_x = was_statusbar_x;
statusbar_pww = was_pww;
}
/* If we left the prompt via Cancel or Enter, set the return value
* properly. */

View File

@@ -1,22 +1,21 @@
/**************************************************************************
* proto.h *
* proto.h -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -30,17 +29,37 @@
extern volatile sig_atomic_t sigwinch_counter;
#endif
#ifdef __linux__
extern bool console;
#endif
extern bool meta_key;
extern bool func_key;
extern bool shift_held;
extern bool focusing;
extern int margin;
extern int editwincols;
#ifdef ENABLE_LINENUMBERS
extern int last_drawn_line;
extern int last_line_y;
#endif
extern message_type lastmessage;
#ifndef NANO_TINY
extern int controlleft;
extern int controlright;
extern int controlup;
extern int controldown;
#ifndef NANO_TINY
extern int shiftcontrolleft;
extern int shiftcontrolright;
extern int shiftcontrolup;
extern int shiftcontroldown;
extern int shiftaltleft;
extern int shiftaltright;
extern int shiftaltup;
extern int shiftaltdown;
#endif
#ifndef DISABLE_WRAPJUSTIFY
@@ -61,9 +80,6 @@ extern int maxrows;
extern filestruct *cutbuffer;
extern filestruct *cutbottom;
#ifndef DISABLE_JUSTIFY
extern filestruct *jusbuffer;
#endif
extern partition *filepart;
extern openfilestruct *openfile;
@@ -184,6 +200,7 @@ bool nisblank(int c);
bool niswblank(wchar_t wc);
#endif
bool is_byte(int c);
bool is_alpha_mbchar(const char *c);
bool is_alnum_mbchar(const char *c);
bool is_blank_mbchar(const char *c);
bool is_ascii_cntrl_char(int c);
@@ -212,16 +229,12 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n);
char *nstrcasestr(const char *haystack, const char *needle);
#endif
char *mbstrcasestr(const char *haystack, const char *needle);
#if !defined(NANO_TINY) || !defined(DISABLE_TABCOMP)
char *revstrstr(const char *haystack, const char *needle, const char
*rev_start);
#endif
#ifndef NANO_TINY
char *revstrcasestr(const char *haystack, const char *needle, const char
*rev_start);
char *mbrevstrcasestr(const char *haystack, const char *needle, const
char *rev_start);
#endif
size_t mbstrlen(const char *s);
#ifndef HAVE_STRNLEN
size_t nstrnlen(const char *s, size_t maxlen);
@@ -267,13 +280,7 @@ void cut_marked(void);
void cut_to_eol(void);
void cut_to_eof(void);
#endif
void do_cut_text(
#ifndef NANO_TINY
bool copy_text, bool cut_till_eof
#else
void
#endif
);
void do_cut_text(bool copy_text, bool cut_till_eof);
void do_cut_text_void(void);
#ifndef NANO_TINY
void do_copy_text(void);
@@ -298,13 +305,6 @@ filestruct *read_line(char *buf, size_t buf_len, filestruct *prevnode);
void read_file(FILE *f, int fd, const char *filename, bool undoable, bool checkwritable);
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(
#ifndef NANO_TINY
bool execute
#else
void
#endif
);
void do_insertfile_void(void);
char *get_full_path(const char *origpath);
char *check_writable_directory(const char *path);
@@ -362,8 +362,7 @@ size_t length_of_list(int menu);
const sc *first_sc_for(int menu, void (*func)(void));
int sc_seq_or(void (*func)(void), int defaultval);
functionptrtype func_from_key(int *kbinput);
key_type strtokeytype(const char *str);
void assign_keyinfo(sc *s);
void assign_keyinfo(sc *s, const char *keystring, const int keycode);
void print_sclist(void);
void shortcut_init(void);
#ifndef DISABLE_COLOR
@@ -398,36 +397,21 @@ void do_para_begin_void(void);
void do_para_end(bool allow_update);
void do_para_end_void(void);
#endif
#ifndef NANO_TINY
void do_prev_block(void);
void do_next_block(void);
void do_prev_word(bool allow_punct, bool allow_update);
void do_prev_word_void(void);
bool do_next_word(bool allow_punct, bool allow_update);
void do_next_word_void(void);
#endif
void ensure_line_is_visible(void);
void do_home(void);
void do_end(void);
void do_up(
#ifndef NANO_TINY
bool scroll_only
#else
void
#endif
);
void do_up(bool scroll_only);
void do_up_void(void);
#ifndef NANO_TINY
void do_scroll_up(void);
#endif
void do_down(
#ifndef NANO_TINY
bool scroll_only
#else
void
#endif
);
void do_down(bool scroll_only);
void do_down_void(void);
#ifndef NANO_TINY
void do_scroll_up(void);
void do_scroll_down(void);
#endif
void do_left(void);
@@ -458,11 +442,7 @@ void say_there_is_no_help(void);
#endif
void finish(void);
void die(const char *msg, ...);
void die_save_file(const char *die_filename
#ifndef NANO_TINY
, struct stat *die_stat
#endif
);
void die_save_file(const char *die_filename, struct stat *die_stat);
void window_init(void);
#ifndef DISABLE_MOUSE
void disable_mouse_support(void);
@@ -488,13 +468,7 @@ RETSIGTYPE handle_sigwinch(int signal);
void regenerate_screen(void);
void allow_sigwinch(bool allow);
void do_toggle(int flag);
#endif
void do_toggle_void(void);
void disable_extended_io(void);
#ifdef USE_SLANG
void disable_signals(void);
#endif
#ifndef NANO_TINY
void enable_signals(void);
#endif
void disable_flow_control(void);
@@ -532,16 +506,6 @@ size_t get_statusbar_page_start(size_t start_col, size_t column);
void reinit_statusbar_x(void);
void reset_statusbar_cursor(void);
void update_the_statusbar(void);
void update_bar_if_needed(void);
functionptrtype get_prompt_string(int *value, bool allow_tabs,
#ifndef DISABLE_TABCOMP
bool allow_files, bool *listed,
#endif
const char *curranswer,
#ifndef DISABLE_HISTORIES
filestruct **history_list,
#endif
void (*refresh_func)(void));
int do_prompt(bool allow_tabs,
#ifndef DISABLE_TABCOMP
bool allow_files,
@@ -584,31 +548,21 @@ void regexp_cleanup(void);
void not_found_msg(const char *str);
void search_replace_abort(void);
int search_init(bool replacing, bool use_answer);
int findnextstr(
#ifndef DISABLE_SPELLER
bool whole_word_only,
#endif
const filestruct *begin, size_t begin_x,
const char *needle, size_t *match_len);
int findnextstr(const char *needle, bool whole_word_only, size_t *match_len,
const filestruct *begin, size_t begin_x);
void do_search(void);
#ifndef NANO_TINY
void do_findprevious(void);
void do_findnext(void);
#endif
#if !defined(NANO_TINY) || !defined(DISABLE_BROWSER)
void do_research(void);
#endif
void go_looking(void);
#ifdef HAVE_REGEX_H
int replace_regexp(char *string, bool create);
#endif
char *replace_line(const char *needle);
ssize_t do_replace_loop(
#ifndef DISABLE_SPELLER
bool whole_word_only,
#endif
const filestruct *real_current, size_t *real_current_x,
const char *needle);
ssize_t do_replace_loop(const char *needle, bool whole_word_only,
const filestruct *real_current, size_t *real_current_x);
void do_replace(void);
void goto_line_posx(ssize_t line, size_t pos_x);
void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
@@ -649,11 +603,11 @@ void do_tab(void);
void do_indent(ssize_t cols);
void do_indent_void(void);
void do_unindent(void);
bool white_string(const char *s);
void do_undo(void);
void do_redo(void);
#endif
#ifndef DISABLE_COMMENT
bool white_string(const char *s);
#ifdef ENABLE_COMMENT
void do_comment(void);
#endif
void do_enter(void);
@@ -707,6 +661,7 @@ void do_verbatim_input(void);
/* All functions in utils.c. */
void get_homedir(void);
int digits(int n);
bool parse_num(const char *str, ssize_t *val);
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column);
void align(char **str);
@@ -764,7 +719,7 @@ void dump_filestruct_reverse(void);
void get_key_buffer(WINDOW *win);
size_t get_key_buffer_len(void);
void unget_input(int *input, size_t input_len);
void unget_kbinput(int kbinput, bool metakey, bool funckey);
void unget_kbinput(int kbinput, bool metakey);
int *get_input(WINDOW *win, size_t input_len);
int get_kbinput(WINDOW *win);
int parse_kbinput(WINDOW *win);
@@ -778,7 +733,7 @@ long get_unicode_kbinput(WINDOW *win, int kbinput);
int get_control_kbinput(int kbinput);
void unparse_kbinput(char *output, size_t output_len);
int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
int *parse_verbatim_kbinput(WINDOW *win, size_t *count);
#ifndef DISABLE_MOUSE
int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
#endif
@@ -801,11 +756,11 @@ void reset_cursor(void);
void edit_draw(filestruct *fileptr, const char *converted, int
line, size_t start);
int update_line(filestruct *fileptr, size_t index);
bool need_screen_update(size_t pww_save);
bool need_horizontal_scroll(const size_t old_column, const size_t new_column);
void edit_scroll(scroll_dir direction, ssize_t nlines);
void edit_redraw(filestruct *old_current);
void edit_refresh(void);
void edit_update(update_type location);
void adjust_viewport(update_type location);
void total_redraw(void);
void total_refresh(void);
void display_main_list(void);

View File

@@ -1,22 +1,23 @@
/**************************************************************************
* rcfile.c *
* rcfile.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, *
* 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014 Mike Frysinger *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -34,6 +35,9 @@
static const rcoption rcopts[] = {
{"boldtext", BOLD_TEXT},
#ifdef ENABLE_LINENUMBERS
{"linenumbers", LINE_NUMBERS},
#endif
#ifndef DISABLE_JUSTIFY
{"brackets", 0},
#endif
@@ -95,6 +99,7 @@ static const rcoption rcopts[] = {
{"noconvert", NO_CONVERT},
{"quickblank", QUICK_BLANK},
{"quiet", QUIET},
{"showcursor", SHOW_CURSOR},
{"smarthome", SMART_HOME},
{"smooth", SMOOTH_SCROLL},
{"softwrap", SOFTWRAP},
@@ -106,6 +111,7 @@ static const rcoption rcopts[] = {
#endif
#ifndef DISABLE_COLOR
{"titlecolor", 0},
{"numbercolor", 0},
{"statuscolor", 0},
{"keycolor", 0},
{"functioncolor", 0},
@@ -342,9 +348,7 @@ bool is_universal(void (*func))
{
if (func == do_left || func == do_right ||
func == do_home || func == do_end ||
#ifndef NANO_TINY
func == do_prev_word_void || func == do_next_word_void ||
#endif
func == do_verbatim_input || func == do_cut_text_void ||
func == do_delete || func == do_backspace ||
func == do_tab || func == do_enter)
@@ -399,7 +403,12 @@ void parse_binding(char *ptr, bool dobind)
else if (keycopy[0] != '^' && keycopy[0] != 'M' && keycopy[0] != 'F') {
rcfile_error(N_("Key name must begin with \"^\", \"M\", or \"F\""));
goto free_copy;
} else if (keycopy[0] == '^' && (keycopy[1] < 64 || keycopy[1] > 127)) {
} else if ((keycopy[0] == 'M' && keycopy[1] != '-') ||
(keycopy[0] == '^' && ((keycopy[1] < 'A' || keycopy[1] > 'z') ||
keycopy[1] == '[' || keycopy[1] == '`' ||
(strlen(keycopy) > 2 && strcmp(keycopy, "^Space") != 0))) ||
(strlen(keycopy) > 3 && strcmp(keycopy, "^Space") != 0 &&
strcmp(keycopy, "M-Space") != 0)) {
rcfile_error(N_("Key name %s is invalid"), keycopy);
goto free_copy;
}
@@ -454,9 +463,11 @@ void parse_binding(char *ptr, bool dobind)
if (f->scfunc == newsc->scfunc)
mask = mask | f->menus;
#ifndef NANO_TINY
/* Handle the special case of the toggles. */
if (newsc->scfunc == do_toggle_void)
mask = MMAIN;
#endif
/* Now limit the given menu to those where the function exists. */
if (is_universal(newsc->scfunc))
@@ -470,20 +481,18 @@ void parse_binding(char *ptr, bool dobind)
goto free_copy;
}
newsc->keystr = keycopy;
newsc->menus = menu;
newsc->type = strtokeytype(newsc->keystr);
assign_keyinfo(newsc);
assign_keyinfo(newsc, keycopy, 0);
/* Do not allow rebinding the equivalent of the Escape key. */
if (newsc->type == META && newsc->seq == 91) {
/* Do not allow rebinding a frequent escape-sequence starter: Esc [. */
if (newsc->meta && newsc->keycode == 91) {
rcfile_error(N_("Sorry, keystroke \"%s\" may not be rebound"), newsc->keystr);
free(newsc);
goto free_copy;
}
#ifdef DEBUG
fprintf(stderr, "s->keystr = \"%s\"\n", newsc->keystr);
fprintf(stderr, "s->seq = \"%d\"\n", newsc->seq);
fprintf(stderr, "s->keycode = \"%d\"\n", newsc->keycode);
#endif
}
@@ -498,6 +507,7 @@ void parse_binding(char *ptr, bool dobind)
}
if (dobind) {
#ifndef NANO_TINY
/* If this is a toggle, copy its sequence number. */
if (newsc->scfunc == do_toggle_void) {
for (s = sclist; s != NULL; s = s->next)
@@ -505,6 +515,7 @@ void parse_binding(char *ptr, bool dobind)
newsc->ordinal = s->ordinal;
} else
newsc->ordinal = 0;
#endif
/* Add the new shortcut at the start of the list. */
newsc->next = sclist;
sclist = newsc;
@@ -1111,6 +1122,8 @@ void parse_rcfile(FILE *rcstream
#ifndef DISABLE_COLOR
if (strcasecmp(rcopts[i].name, "titlecolor") == 0)
specified_color_combo[TITLE_BAR] = option;
else if (strcasecmp(rcopts[i].name, "numbercolor") == 0)
specified_color_combo[LINE_NUMBER] = option;
else if (strcasecmp(rcopts[i].name, "statuscolor") == 0)
specified_color_combo[STATUS_BAR] = option;
else if (strcasecmp(rcopts[i].name, "keycolor") == 0)

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* search.c *
* search.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -47,11 +47,8 @@ bool regexp_init(const char *regexp)
assert(!regexp_compiled);
rc = regcomp(&search_regexp, fixbounds(regexp), NANO_REG_EXTENDED
#ifndef NANO_TINY
| (ISSET(CASE_SENSITIVE) ? 0 : REG_ICASE)
#endif
);
rc = regcomp(&search_regexp, fixbounds(regexp),
NANO_REG_EXTENDED | (ISSET(CASE_SENSITIVE) ? 0 : REG_ICASE));
if (rc != 0) {
size_t len = regerror(rc, &search_regexp, NULL, 0);
@@ -155,32 +152,26 @@ int search_init(bool replacing, bool use_answer)
/* This is now one simple call. It just does a lot. */
i = do_prompt(FALSE,
#ifndef DISABLE_TABCOMP
TRUE,
TRUE,
#endif
replacing ? MREPLACE : MWHEREIS, backupstring,
replacing ? MREPLACE : MWHEREIS, backupstring,
#ifndef DISABLE_HISTORIES
&search_history,
&search_history,
#endif
/* TRANSLATORS: This is the main search prompt. */
edit_refresh, "%s%s%s%s%s%s", _("Search"),
#ifndef NANO_TINY
/* TRANSLATORS: The next three strings are modifiers of the search prompt. */
ISSET(CASE_SENSITIVE) ? _(" [Case Sensitive]") :
#endif
"",
/* TRANSLATORS: This is the main search prompt. */
edit_refresh, "%s%s%s%s%s%s", _("Search"),
/* TRANSLATORS: The next three modify the search prompt. */
ISSET(CASE_SENSITIVE) ? _(" [Case Sensitive]") : "",
#ifdef HAVE_REGEX_H
ISSET(USE_REGEXP) ? _(" [Regexp]") :
ISSET(USE_REGEXP) ? _(" [Regexp]") :
#endif
"",
"",
ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") : "", replacing ?
#ifndef NANO_TINY
ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") :
/* TRANSLATORS: The next two modify the search prompt. */
openfile->mark_set ? _(" (to replace) in selection") :
#endif
"", replacing ?
#ifndef NANO_TINY
/* TRANSLATORS: The next two strings are modifiers of the search prompt. */
openfile->mark_set ? _(" (to replace) in selection") :
#endif
_(" (to replace)") : "", buf);
_(" (to replace)") : "", buf);
/* Release buf now that we don't need it anymore. */
free(buf);
@@ -214,7 +205,6 @@ int search_init(bool replacing, bool use_answer)
func = func_from_key(&i);
#ifndef NANO_TINY
if (func == case_sens_void) {
TOGGLE(CASE_SENSITIVE);
backupstring = mallocstrcpy(backupstring, answer);
@@ -224,7 +214,6 @@ int search_init(bool replacing, bool use_answer)
backupstring = mallocstrcpy(backupstring, answer);
return 1;
} else
#endif
#ifdef HAVE_REGEX_H
if (func == regexp_void) {
TOGGLE(USE_REGEXP);
@@ -248,12 +237,8 @@ int search_init(bool replacing, bool use_answer)
* where we first started searching, at column begin_x. Return 1 when we
* found something, 0 when nothing, and -2 on cancel. When match_len is
* not NULL, set it to the length of the found string, if any. */
int findnextstr(
#ifndef DISABLE_SPELLER
bool whole_word_only,
#endif
const filestruct *begin, size_t begin_x,
const char *needle, size_t *match_len)
int findnextstr(const char *needle, bool whole_word_only, size_t *match_len,
const filestruct *begin, size_t begin_x)
{
size_t found_len;
/* The length of the match we find. */
@@ -270,12 +255,13 @@ int findnextstr(
* will return immediately and say that no match was found, and
* rev_start will be properly set when the search continues on the
* previous or next line. */
rev_start +=
#ifndef NANO_TINY
ISSET(BACKWARDS_SEARCH) ?
((openfile->current_x == 0) ? -1 : move_mbleft(fileptr->data, openfile->current_x)) :
#endif
move_mbright(fileptr->data, openfile->current_x);
if (ISSET(BACKWARDS_SEARCH)) {
if (openfile->current_x == 0)
rev_start += -1;
else
rev_start += move_mbleft(fileptr->data, openfile->current_x);
} else
rev_start += move_mbright(fileptr->data, openfile->current_x);
enable_nodelay();
@@ -343,11 +329,9 @@ int findnextstr(
}
/* Move to the previous or next line in the file. */
#ifndef NANO_TINY
if (ISSET(BACKWARDS_SEARCH))
fileptr = fileptr->prev;
else
#endif
fileptr = fileptr->next;
/* If we've reached the start or end of the buffer, wrap around. */
@@ -359,11 +343,9 @@ int findnextstr(
return 0;
}
#endif
#ifndef NANO_TINY
if (ISSET(BACKWARDS_SEARCH))
fileptr = openfile->filebot;
else
#endif
fileptr = openfile->fileage;
statusbar(_("Search Wrapped"));
@@ -377,23 +359,15 @@ int findnextstr(
/* Set the starting x to the start or end of the line. */
rev_start = fileptr->data;
#ifndef NANO_TINY
if (ISSET(BACKWARDS_SEARCH))
rev_start += strlen(fileptr->data);
#endif
}
found_x = found - fileptr->data;
/* Ensure that the found occurrence is not beyond the starting x. */
if (came_full_circle &&
#ifndef NANO_TINY
((!ISSET(BACKWARDS_SEARCH) && found_x > begin_x) ||
(ISSET(BACKWARDS_SEARCH) && found_x < begin_x))
#else
found_x > begin_x
#endif
) {
if (came_full_circle && ((!ISSET(BACKWARDS_SEARCH) && found_x > begin_x) ||
(ISSET(BACKWARDS_SEARCH) && found_x < begin_x))) {
not_found_msg(needle);
disable_nodelay();
return 0;
@@ -425,10 +399,8 @@ void do_search(void)
search_replace_abort();
else if (i == -2) /* Do a replace instead. */
do_replace();
#if !defined(NANO_TINY) || defined(HAVE_REGEX_H)
else if (i == 1) /* Toggled something. */
do_search();
#endif
if (i == 0)
go_looking();
@@ -459,7 +431,6 @@ void do_findnext(void)
}
#endif /* !NANO_TINY */
#if !defined(NANO_TINY) || !defined(DISABLE_BROWSER)
/* Search for the last string without prompting. */
void do_research(void)
{
@@ -485,7 +456,6 @@ void do_research(void)
go_looking();
}
#endif /* !NANO_TINY */
/* Search for the global string 'last_search'. Inform the user when
* the string occurs only once. */
@@ -494,14 +464,14 @@ void go_looking(void)
filestruct *was_current = openfile->current;
size_t was_current_x = openfile->current_x;
int didfind;
#ifdef DEBUG
clock_t start = clock();
#endif
came_full_circle = FALSE;
didfind = findnextstr(
#ifndef DISABLE_SPELLER
FALSE,
#endif
openfile->current, openfile->current_x, last_search, NULL);
didfind = findnextstr(last_search, FALSE, NULL,
openfile->current, openfile->current_x);
/* If we found something, and we're back at the exact same spot
* where we started searching, then this is the only occurrence. */
@@ -509,6 +479,10 @@ void go_looking(void)
openfile->current_x == was_current_x)
statusbar(_("This is the only occurrence"));
#ifdef DEBUG
statusline(HUSH, "Took: %.2f", (double)(clock() - start) / CLOCKS_PER_SEC);
#endif
edit_redraw(was_current);
search_replace_abort();
}
@@ -606,12 +580,8 @@ char *replace_line(const char *needle)
* allow the cursor position to be updated when a word before the cursor
* is replaced by a shorter word. Return -1 if needle isn't found, -2 if
* the seeking is aborted, else the number of replacements performed. */
ssize_t do_replace_loop(
#ifndef DISABLE_SPELLER
bool whole_word_only,
#endif
const filestruct *real_current, size_t *real_current_x,
const char *needle)
ssize_t do_replace_loop(const char *needle, bool whole_word_only,
const filestruct *real_current, size_t *real_current_x)
{
ssize_t numreplaced = -1;
size_t match_len;
@@ -645,11 +615,8 @@ ssize_t do_replace_loop(
while (TRUE) {
int i = 0;
int result = findnextstr(
#ifndef DISABLE_SPELLER
whole_word_only,
#endif
real_current, *real_current_x, needle, &match_len);
int result = findnextstr(needle, whole_word_only, &match_len,
real_current, *real_current_x);
/* If nothing more was found, or the user aborted, stop looping. */
if (result < 1) {
@@ -750,9 +717,7 @@ ssize_t do_replace_loop(
/* Set the cursor at the last character of the replacement
* text, so that searching will continue /after/ it. Note
* that current_x might be set to (size_t)-1 here. */
#ifndef NANO_TINY
if (!ISSET(BACKWARDS_SEARCH))
#endif
openfile->current_x += match_len + length_change - 1;
/* Update the file size, and put the changed line into place. */
@@ -827,14 +792,14 @@ void do_replace(void)
i = do_prompt(FALSE,
#ifndef DISABLE_TABCOMP
TRUE,
TRUE,
#endif
MREPLACEWITH, NULL,
MREPLACEWITH, NULL,
#ifndef DISABLE_HISTORIES
&replace_history,
&replace_history,
#endif
/* TRANSLATORS: This is a prompt. */
edit_refresh, _("Replace with"));
/* TRANSLATORS: This is a prompt. */
edit_refresh, _("Replace with"));
#ifndef DISABLE_HISTORIES
/* If the replace string is not "", add it to the replace history list. */
@@ -855,11 +820,7 @@ void do_replace(void)
begin = openfile->current;
begin_x = openfile->current_x;
numreplaced = do_replace_loop(
#ifndef DISABLE_SPELLER
FALSE,
#endif
begin, &begin_x, last_search);
numreplaced = do_replace_loop(last_search, FALSE, begin, &begin_x);
/* Restore where we were. */
openfile->edittop = edittop_save;
@@ -963,9 +924,9 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
openfile->placewewant = column - 1;
/* When the position was manually given, center the target line. */
if (interactive) {
edit_update(CENTERING);
edit_refresh();
if (interactive || ISSET(SOFTWRAP)) {
adjust_viewport(CENTERING);
refresh_needed = TRUE;
} else {
/* If the target line is close to the tail of the file, put the last
* line of the file on the bottom line of the screen; otherwise, just
@@ -974,9 +935,9 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
editwinrows / 2) {
openfile->current_y = editwinrows - openfile->filebot->lineno +
openfile->current->lineno - 1;
edit_update(STATIONARY);
adjust_viewport(STATIONARY);
} else
edit_update(CENTERING);
adjust_viewport(CENTERING);
}
}

View File

@@ -1,22 +1,24 @@
/**************************************************************************
* text.c *
* text.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2014, 2015 Mark Majeres *
* Copyright (C) 2016 Mike Scalora *
* Copyright (C) 2015, 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -40,8 +42,10 @@ static bool prepend_wrap = FALSE;
/* Should we prepend wrapped text to the next line? */
#endif
#ifndef DISABLE_JUSTIFY
static filestruct *jusbuffer = NULL;
/* The buffer where we store unjustified text. */
static filestruct *jusbottom = NULL;
/* Pointer to the end of the justify buffer. */
/* A pointer to the end of the buffer with unjustified text. */
#endif
#ifndef NANO_TINY
@@ -49,16 +53,18 @@ static filestruct *jusbottom = NULL;
void do_mark(void)
{
openfile->mark_set = !openfile->mark_set;
if (openfile->mark_set) {
statusbar(_("Mark Set"));
openfile->mark_begin = openfile->current;
openfile->mark_begin_x = openfile->current_x;
openfile->kind_of_mark = HARDMARK;
} else {
statusbar(_("Mark Unset"));
openfile->mark_begin = NULL;
openfile->mark_begin_x = 0;
edit_refresh();
}
edit_refresh();
}
#endif /* !NANO_TINY */
@@ -165,6 +171,8 @@ void do_deletion(undo_type action)
return;
#ifndef NANO_TINY
ensure_line_is_visible();
if (ISSET(SOFTWRAP) && refresh_needed == FALSE)
if (strlenpt(openfile->current->data) / COLS != orig_lenpt / COLS)
refresh_needed = TRUE;
@@ -431,7 +439,6 @@ void do_unindent(void)
}
#endif /* !NANO_TINY */
#ifdef ENABLE_COMMENT
/* Test whether the string is empty or consists of only blanks. */
bool white_string(const char *s)
{
@@ -441,6 +448,7 @@ bool white_string(const char *s)
return !*s;
}
#ifdef ENABLE_COMMENT
/* Comment or uncomment the current line or the marked lines. */
void do_comment()
{
@@ -2509,35 +2517,28 @@ void do_justify(bool full_justify)
|| func == do_undo
#endif
) {
/* Splice the justify buffer back into the file, but only if we
* actually justified something. */
/* If we actually justified something, then splice the preserved
* unjustified text back into the file, */
if (first_par_line != NULL) {
filestruct *top_save;
/* Partition the filestruct so that it contains only the
* text of the justified paragraph. */
filepart = partition_filestruct(first_par_line, 0,
last_par_line, filebot_inpar ?
strlen(last_par_line->data) : 0);
/* Remove the text of the justified paragraph, and
* replace it with the text in the justify buffer. */
/* Throw away the justified paragraph, and replace it with
* the preserved unjustified text. */
free_filestruct(openfile->fileage);
openfile->fileage = jusbuffer;
openfile->filebot = jusbottom;
top_save = openfile->fileage;
/* Unpartition the filestruct so that it contains all the
* text again. Note that the justified paragraph has been
* replaced with the unjustified paragraph. */
/* Unpartition the filestruct, to contain the entire text again. */
unpartition_filestruct(&filepart);
/* Renumber, starting with the beginning line of the old
* partition. */
renumber(top_save);
/* Renumber, from the beginning of the unjustified part. */
renumber(jusbuffer);
/* Restore the justify we just did (ungrateful user!). */
/* Restore the old position, the size, and the mark. */
openfile->edittop = edittop_save;
openfile->current = current_save;
openfile->current_x = current_x_save;
@@ -2549,17 +2550,14 @@ void do_justify(bool full_justify)
}
#endif
openfile->modified = modified_save;
/* Clear the justify buffer. */
jusbuffer = NULL;
if (!openfile->modified)
titlebar(NULL);
refresh_needed = TRUE;
}
} else {
/* Put the keystroke back into the queue. */
unget_kbinput(kbinput, meta_key, func_key);
unget_kbinput(kbinput, meta_key);
/* Set the desired screen column (always zero, except at EOF). */
openfile->placewewant = xplustabs();
@@ -2570,11 +2568,13 @@ void do_justify(bool full_justify)
discard_until(NULL, openfile);
openfile->current_undo = NULL;
#endif
/* Blow away the text in the justify buffer. */
/* Blow away the unjustified text. */
free_filestruct(jusbuffer);
jusbuffer = NULL;
}
/* Mark the buffer for unjustified text as empty. */
jusbuffer = NULL;
blank_statusbar();
/* Display the shortcut list with UnCut. */
@@ -2626,10 +2626,9 @@ bool do_int_spell_fix(const char *word)
/* Make sure spell-check is case sensitive. */
SET(CASE_SENSITIVE);
#ifndef NANO_TINY
/* Make sure spell-check goes forward only. */
UNSET(BACKWARDS_SEARCH);
#endif
#ifdef HAVE_REGEX_H
/* Make sure spell-check doesn't use regular expressions. */
UNSET(USE_REGEXP);
@@ -2664,16 +2663,17 @@ bool do_int_spell_fix(const char *word)
}
/* Find the first whole occurrence of word. */
result = findnextstr(TRUE, NULL, 0, word, NULL);
result = findnextstr(word, TRUE, NULL, NULL, 0);
/* The word must exist; if not, something is wrong. */
if (result == 0)
statusline(ALERT, "Internal error: "
"speller listed unfindable word: %s", word);
else if (result == 1) {
/* If the word isn't found, alert the user; if it is, allow correction. */
if (result == 0) {
statusline(ALERT, _("Unfindable word: %s"), word);
lastmessage = HUSH;
proceed = TRUE;
napms(2800);
} else if (result == 1) {
exp_word = display_string(openfile->current->data, xplustabs(),
strlenpt(word), FALSE);
edit_refresh();
spotlight(TRUE, exp_word);
@@ -2700,7 +2700,7 @@ bool do_int_spell_fix(const char *word)
/* Replacements should happen only in the marked region. */
openfile->mark_set = old_mark_set;
#endif
do_replace_loop(TRUE, current_save, &current_x_save, word);
do_replace_loop(word, TRUE, current_save, &current_x_save);
/* TRANSLATORS: Shown after fixing misspellings in one word. */
statusbar(_("Next word..."));
@@ -2926,6 +2926,7 @@ const char *do_alt_speller(char *tempfile_name)
{
int alt_spell_status;
size_t current_x_save = openfile->current_x;
size_t pww_save = openfile->placewewant;
ssize_t current_y_save = openfile->current_y;
ssize_t lineno_save = openfile->current->lineno;
struct stat spellfileinfo;
@@ -3074,7 +3075,8 @@ const char *do_alt_speller(char *tempfile_name)
/* Go back to the old position. */
goto_line_posx(lineno_save, current_x_save);
openfile->current_y = current_y_save;
edit_update(STATIONARY);
openfile->placewewant = pww_save;
adjust_viewport(STATIONARY);
/* Stat the temporary file again, and mark the buffer as modified only
* if this file was changed since it was written. */
@@ -3550,7 +3552,7 @@ void do_formatter(void)
goto_line_posx(lineno_save, current_x_save);
openfile->current_y = current_y_save;
openfile->placewewant = pww_save;
edit_update(STATIONARY);
adjust_viewport(STATIONARY);
set_modified();

View File

@@ -1,22 +1,22 @@
/**************************************************************************
* utils.c *
* utils.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option) *
* any later version. *
* Copyright (C) 2016 Benno Schulenberg *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301, USA. *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
@@ -52,6 +52,39 @@ void get_homedir(void)
}
}
#ifdef ENABLE_LINENUMBERS
/* Return the number of digits that the given integer n takes up. */
int digits(int n)
{
if (n < 100000) {
if (n < 1000) {
if (n < 100)
return 2;
else
return 3;
} else {
if (n < 10000)
return 4;
else
return 5;
}
} else {
if (n < 10000000) {
if (n < 1000000)
return 6;
else
return 7;
}
else {
if (n < 100000000)
return 8;
else
return 9;
}
}
}
#endif
/* Read a ssize_t from str, and store it in *val (if val is not NULL).
* On error, we return FALSE and don't change *val. Otherwise, we
* return TRUE. */
@@ -290,12 +323,11 @@ bool is_separate_word(size_t position, size_t length, const char *buf)
parse_mbchar(buf + move_mbleft(buf, position), before, NULL);
parse_mbchar(buf + word_end, after, NULL);
/* If we're at the beginning of the line or the character before the
* word isn't a non-punctuation "word" character, and if we're at
* the end of the line or the character after the word isn't a
* non-punctuation "word" character, we have a whole word. */
retval = (position == 0 || !is_alnum_mbchar(before)) &&
(word_end == strlen(buf) || !is_alnum_mbchar(after));
/* If the word starts at the beginning of the line OR the character before
* the word isn't a letter, and if the word ends at the end of the line OR
* the character after the word isn't a letter, we have a whole word. */
retval = (position == 0 || !is_alpha_mbchar(before)) &&
(word_end == strlen(buf) || !is_alpha_mbchar(after));
free(before);
free(after);
@@ -322,10 +354,9 @@ const char *strstrwrapper(const char *haystack, const char *needle,
#ifdef HAVE_REGEX_H
if (ISSET(USE_REGEXP)) {
#ifndef NANO_TINY
if (ISSET(BACKWARDS_SEARCH)) {
if (regexec(&search_regexp, haystack, 1, regmatches,
0) == 0 && haystack + regmatches[0].rm_so <= start) {
if (regexec(&search_regexp, haystack, 1, regmatches, 0) == 0 &&
haystack + regmatches[0].rm_so <= start) {
const char *retval = haystack + regmatches[0].rm_so;
/* Search forward until there are no more matches. */
@@ -339,10 +370,8 @@ const char *strstrwrapper(const char *haystack, const char *needle,
regexec(&search_regexp, retval, 10, regmatches, 0);
return retval;
}
} else
#endif /* !NANO_TINY */
if (regexec(&search_regexp, start, 10, regmatches,
(start > haystack) ? REG_NOTBOL : 0) == 0) {
} else if (regexec(&search_regexp, start, 10, regmatches,
(start > haystack) ? REG_NOTBOL : 0) == 0) {
const char *retval = start + regmatches[0].rm_so;
regexec(&search_regexp, retval, 10, regmatches, 0);
@@ -351,20 +380,14 @@ const char *strstrwrapper(const char *haystack, const char *needle,
return NULL;
}
#endif /* HAVE_REGEX_H */
#if !defined(NANO_TINY) || !defined(DISABLE_SPELLER)
if (ISSET(CASE_SENSITIVE)) {
#ifndef NANO_TINY
if (ISSET(BACKWARDS_SEARCH))
return revstrstr(haystack, needle, start);
else
#endif
return strstr(start, needle);
}
#endif /* !DISABLE_SPELLER || !NANO_TINY */
#ifndef NANO_TINY
else if (ISSET(BACKWARDS_SEARCH))
} else if (ISSET(BACKWARDS_SEARCH))
return mbrevstrcasestr(haystack, needle, start);
#endif
return mbstrcasestr(start, needle);
}
@@ -440,12 +463,12 @@ char *free_and_assign(char *dest, char *src)
* get_page_start(column) < COLS). */
size_t get_page_start(size_t column)
{
if (column == 0 || column < COLS - 1)
if (column == 0 || column < editwincols - 1)
return 0;
else if (COLS > 8)
return column - 7 - (column - 7) % (COLS - 8);
else if (editwincols > 8)
return column - 7 - (column - 7) % (editwincols - 8);
else
return column - (COLS - 2);
return column - (editwincols - 2);
}
/* Return the placewewant associated with current_x, i.e. the zero-based

File diff suppressed because it is too large Load Diff