Compare commits

...

236 Commits

Author SHA1 Message Date
Benno Schulenberg
d646a3b97b po: update translations and regenerate POT file and PO files 2017-11-27 19:21:00 +01:00
Benno Schulenberg
800a997008 bump version numbers and add a news item for the 2.9.1 release 2017-11-27 19:06:26 +01:00
Benno Schulenberg
c17a8a9836 undo: discarding the stack does not always lose information
When some or all edits have been undone, and the user starts to make
new edits, the old part of the undo stack is discarded, but this does
not mean that the undo stack doesn't go back to the very beginning.

This really fixes https://savannah.gnu.org/bugs/?52504.
2017-11-27 16:19:28 +01:00
Benno Schulenberg
20aa167c14 files: always update the stat info when the entire file is written
This fixes https://savannah.gnu.org/bugs/?52519.
2017-11-26 20:57:30 +01:00
Benno Schulenberg
0c9905dbd0 undo: clear the Modified state when the very first edit is undone
This also means that no question needs to be asked when exiting.

This fixes https://savannah.gnu.org/bugs/?52504.
Reported-by: Peter Passchier <peter@passchier.net>
2017-11-26 19:55:44 +01:00
Benno Schulenberg
73c7f1cbdc history: make nano's state directory accessible for the user only 2017-11-26 19:54:47 +01:00
Benno Schulenberg
4200ed3003 history: create the path '~/.local/share/' when it is needed
On a freshly installed system, or for a new user, the default
XDG data directory may not exist yet.  So, create it when not.

Reported-by: Brand Huntsman <alpha@qzx.com>
2017-11-26 19:54:47 +01:00
Benno Schulenberg
2b314ed18f selecting: let a justification cancel a softmark
Otherwise a second justification will cancel it, which is weird.
2017-11-26 19:54:29 +01:00
Benno Schulenberg
88a0bb9685 selecting: do not cancel the softmark when the cursor is not moved
The softmark is now only cancelled when the cursor is moved without
Shift being held, not for things like ^L (Refresh), ^C (Position),
or ^G (Help).

This addresses https://savannah.gnu.org/bugs/?52470.
2017-11-26 19:41:14 +01:00
Benno Schulenberg
1e718cec35 tweaks: reshuffle a couple of lines, to put similar things together 2017-11-26 18:01:02 +01:00
Benno Schulenberg
5487551ce9 history: save the positions file also when a record was deleted
When a file is closed with the cursor on line 1, column 1, this
position is not recorded in file-positions history file -- if a
record for the file existed, it is deleted.  In the latter case
the history file needs to be saved, so that other instances of
nano will know about the deletion.

This fixes https://savannah.gnu.org/bugs/?52505.
2017-11-26 09:28:36 +01:00
Benno Schulenberg
763bf2ed26 gnulib: update to its current upstream state 2017-11-23 18:00:18 +01:00
Benno Schulenberg
cf63a2910a files: save the marked region only when we've prompted for a file name
Otherwise we would overwrite the current file with just the selection.

This fixes https://savannah.gnu.org/bugs/?52482.
2017-11-22 20:56:37 +01:00
Benno Schulenberg
7c3c942097 tweaks: adjust indentation after previous change 2017-11-22 19:43:50 +01:00
Benno Schulenberg
77d24300f3 tweaks: reshuffle a couple of lines, and frob a comment or two 2017-11-22 19:36:33 +01:00
Benno Schulenberg
d33b5f3dab tweaks: rename, rewrap, and reshuffle some stuff, and frob some comments 2017-11-21 21:17:08 +01:00
Benno Schulenberg
c24e95e3d6 tweaks: elide the 'mark_set' boolean -- the 'mark' pointer is enough
The pointer not being NULL is enough indication that the mark is set.

Also, rename the pointer from 'mark_begin' to simply 'mark', since
the former is kind of pleonastic.
2017-11-21 21:14:33 +01:00
Benno Schulenberg
c42489d946 linting: switch the mark off when the linter starts
Because the highlighting hinders the display of affected lines,
and, more importantly, only the highlighted part would be written
if the file was modified and the user answers yes to the "Save?"
prompt.

This fixes https://savannah.gnu.org/bugs/?52474.
2017-11-21 21:12:16 +01:00
Benno Schulenberg
2b438e6ef4 input: make the macro key discoverable by giving feedback when undefined 2017-11-20 19:57:33 +01:00
Benno Schulenberg
8165b20fc1 build: fix compilation with --disable-browser --disable-tabcomp
While doing that, move the affected function to the utils.c file
and tweak it a bit.

This fixes https://savannah.gnu.org/bugs/?52468.
2017-11-20 19:37:08 +01:00
Benno Schulenberg
bacb0f717d syntax: adjust the magic strings for the changes since file-5.10
Since file-5.10 (end of 2011), libmagic identifies a C file in most
cases as "C source" instead of as "C program".  Nano's magic strings
for some other files didn't match any more what file-5.32 currently
produces, either.  So, they have been adjusted, new ones added, and
old ones deleted.

This fixes https://savannah.gnu.org/bugs/?52445.
2017-11-19 11:24:30 +01:00
Benno Schulenberg
11a3bc484c po: update translations and regenerate POT file and PO files 2017-11-18 12:11:52 +01:00
Benno Schulenberg
0465adb9ce bump version numbers and add a news item for the 2.9.0 release 2017-11-18 11:33:28 +01:00
Benno Schulenberg
7ea13d4269 tweaks: correct two minor things in the documentation 2017-11-17 21:52:31 +01:00
Benno Schulenberg
06049f5141 docs: update references to the nanorc files for the XDG changes 2017-11-17 21:40:54 +01:00
Benno Schulenberg
4220854367 docs: mention that macros work correctly only on terminal emulators 2017-11-13 21:08:36 +01:00
Benno Schulenberg
f6e83438da tweaks: elide a comment, and improve a couple of others 2017-11-13 19:58:29 +01:00
David Lawrence Ramsey
169da09424 files: don't change file format when inserting into an existing buffer
This fixes https://savannah.gnu.org/bugs/?52392.
2017-11-13 19:42:44 +01:00
Benno Schulenberg
e6a92b1406 painting: evade an ncurses bug by adding the A_PROTECT attribute
Adding the obscure A_PROTECT attribute to every color prevents an
occasional miscoloring of the first few rows on the screen -- when
ncurses is version 6.0 and dates from before October 17, 2015.

Original-idea-by: Brand Huntsman <alpha@qzx.com>
Tested-by: Brand Huntsman <alpha@qzx.com>

This fixes https://savannah.gnu.org/bugs/?52182.
2017-11-13 19:38:28 +01:00
Benno Schulenberg
ab14df074f search: wipe reassuring feedback as soon as searching has finished
When there are no help lines, there won't be any call to update the
actual contents of the bottom window, so... do it immediately after
blanking the row.

This fixes https://savannah.gnu.org/bugs/?52377.
2017-11-13 19:37:39 +01:00
Benno Schulenberg
5198c1f139 tweaks: frob a couple of comments 2017-11-12 20:08:28 +01:00
Benno Schulenberg
1e292141f3 docs: make it clearer that a Signed-off-by is wanted on patches 2017-11-12 11:54:17 +01:00
Benno Schulenberg
8649c78e1e tweaks: drop the ineffective cgitrc -- sorting by "age" does not work 2017-11-12 10:51:41 +01:00
Benno Schulenberg
5239e7c52b copyright: update some years, and standardize on the dashed format 2017-11-12 10:46:20 +01:00
Benno Schulenberg
f6b6e6c3ff tweaks: reshuffle a bit of code and elide an unneeded variable 2017-11-11 21:10:49 +01:00
Benno Schulenberg
0c2b54a276 tweaks: rename a function plus two parameters, to be more fitting 2017-11-11 20:58:56 +01:00
Benno Schulenberg
a7f5907b43 tweaks: move a general function to the utils.c file 2017-11-11 11:34:39 +01:00
Benno Schulenberg
dfcb1268ca tweaks: adjust a comment, and condense a fragment of code 2017-11-10 20:06:13 +01:00
Benno Schulenberg
2122a1a2b5 tweaks: constify the result strings of getenv(), as a reminder
Also, remove an unneeded pair of braces.
2017-11-10 20:03:07 +01:00
Marco Diego Aurélio Mesquita
e2d3bba86c general: do not free strings gotten from getenv(), to avoid a crash
Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
2017-11-10 19:55:44 +01:00
Benno Schulenberg
4567360d01 gnulib: update to its current upstream state 2017-11-10 19:40:23 +01:00
Benno Schulenberg
478e34a80c ouch: set the positions-file name also when using the legacy state dir
One should test a change before pushing, also when it worked last time.
2017-11-08 21:15:28 +01:00
Benno Schulenberg
ea47879911 tweaks: don't construct the positions-history filename time and again 2017-11-08 20:38:34 +01:00
Brand Huntsman
bfc53f308c history: prevent overwriting of positions between multiple instances
Whenever a buffer is closed, check whether the positions file on disk
was modified, and if so, reload it.  Then update the position for the
closed buffer and write out the positions file to disk.

Signed-off-by: Brand Huntsman <alpha@qzx.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2017-11-08 20:38:34 +01:00
Lion Yang
f0d3685591 input: ensure that standard input uses blocking mode
The function get_key_buffer() assumes waiting_mode = TRUE, but stdin
can be in non-blocking mode when a program (before nano) turned stdin
to non-blocking mode and did not change it back (possibly because it
crashed).  So, explicitly set stdin to blocking mode at startup.

Signed-off-by: Lion Yang <lion@aosc.io>
2017-11-08 20:28:26 +01:00
Benno Schulenberg
7e6bb91593 tweaks: add a translator hint, and adjust two others 2017-11-07 19:39:00 +01:00
Benno Schulenberg
7b133aa6f9 tweaks: change some mayday messages, to urge the user to report a bug
Also, diversify them, and no longer mark them for translation.
2017-11-07 19:14:33 +01:00
David Lawrence Ramsey
477b246771 tweaks: use printf's z modifier for most of the size_t/ssize_t types
Also, properly refer to numreplaced as signed, since it's ssize_t
(even though it's only shown when positive).
2017-11-07 17:55:21 +01:00
David Lawrence Ramsey
7d653e5a17 history: fix the check for an existing $HOME/.nano/ directory
This fixes https://savannah.gnu.org/bugs/?52339.
2017-11-05 20:35:52 +01:00
Simon Ochsenreither
c16e79b612 startup: look for nanorc and history files also in the XDG directories
When not finding a .nanorc file in the user's home directory, nano will
look for a nanorc file in $XDG_CONFIG_HOME and in the ~/.config/nano/
fallback directory.  And when not finding a .nano/ subdir in the user's
home directory, nano will look for (or create) the history files in
$XDG_DATA_HOME or in the ~/.local/share/nano/ fallback directory.

This is a partial implementation of the XDG Base Directory Specification:
https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html,
for the purpose of reducing the clutter in a user's home directory, and
to make it easier to back up just the configuration files.

Signed-off-by: Simon Ochsenreither <simon@ochsenreither.de>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2017-11-04 20:11:57 +01:00
Benno Schulenberg
1463781247 startup: when an rcfile contains errors, report this on the status bar
Suggested-by: Brand Huntsman <alpha@qzx.com>
2017-11-02 17:30:14 +01:00
Benno Schulenberg
c3a11fb7ed options: remove '--quiet' and 'set quiet', because they hide problems
If the user uses a single version of nano, they have no need for
--quiet.  If they do sometimes use an older version and don't want
to see the warnings, they can use 2>/dev/null (they could make an
alias for that and put it before the call of nano).
2017-11-02 17:27:53 +01:00
Benno Schulenberg
953c2b8e79 startup: don't ask the user to press Enter upon an rcfile error
The user told nano to start, thus nano should *start* -- without
halting and without nagging the user.
2017-11-02 17:22:21 +01:00
Benno Schulenberg
d054044d30 tweaks: transform the token DISABLE_EXTRA to ENABLE_EXTRA 2017-11-01 20:33:14 +01:00
Benno Schulenberg
9dc72cf3ba tweaks: avoid an unused-variable warning with --disable-nanorc 2017-11-01 20:08:55 +01:00
Benno Schulenberg
d5ac1ed395 tweaks: transform the token DISABLE_COLOR to ENABLE_COLOR 2017-11-01 19:45:50 +01:00
Benno Schulenberg
2a4fc9591f tweaks: transform the token DISABLE_SPELLER to ENABLE_SPELLER 2017-10-31 19:32:42 +01:00
Benno Schulenberg
f034992ed6 tweaks: transform the token DISABLE_WRAPJUSTIFY to ENABLED_WRAPORJUSTIFY 2017-10-31 17:40:54 +01:00
Benno Schulenberg
db0b849f9b tweaks: transform the token DISABLE_JUSTIFY to ENABLE_JUSTIFY 2017-10-31 17:40:44 +01:00
Benno Schulenberg
c4d2a92d4c tweaks: reshuffle some code in order to elide a variable
Initialize 'breaking_col' to what it needs to be when the current chunk
consists of only a tab -- a tab that spreads across both start and end
of the chunk -- so that the last 'if' can move into the preceding one,
which allows the elision of 'char_len'.
2017-10-30 21:02:23 +01:00
Benno Schulenberg
4e03a245ac tweaks: adjust two comments, and correct and a few cosmetic mistakes 2017-10-30 19:12:22 +01:00
Benno Schulenberg
028d12f4fb tweaks: transform the token DISABLE_OPERATINGDIR to ENABLE_OPERATINGDIR 2017-10-29 21:08:07 +01:00
Benno Schulenberg
a5974bd1ec tweaks: transform the token DISABLE_WRAPPING to ENABLE_WRAPPING 2017-10-29 21:00:09 +01:00
Benno Schulenberg
87da3ecbe0 tweaks: remove another bit of conditional compilation 2017-10-29 20:42:20 +01:00
Benno Schulenberg
ff35a61355 tweaks: transform the token DISABLE_HISTORIES to ENABLE_HISTORIES 2017-10-29 19:43:05 +01:00
Benno Schulenberg
3f27c312c4 tweaks: get rid of some cluttering conditional compilation
In the tiny version, do_prompt() will now have an extra NULL
parameter, which will cost maybe twenty extra bytes of code.
That is acceptable when it saves thirty lines in the source.
2017-10-29 11:39:27 +01:00
Benno Schulenberg
ab6e4e36e2 tweaks: fix compilation with --enable-tiny --enable-histories 2017-10-29 10:49:08 +01:00
Benno Schulenberg
84c650b80a files: avoid an abortion when excuting a command in a new buffer
The key sequence ^R ^X M-F <Enter> would cause nano to abort, because
it would try to add an empty string to a history list.  (Furthermore,
simply don't execute an empty command, because it is pointless.)

Reported-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
2017-10-28 12:33:03 +02:00
Benno Schulenberg
42497f77e2 tweaks: rename some constants, to follow the same underscoreless scheme 2017-10-28 12:32:54 +02:00
Benno Schulenberg
86ef9db363 tweaks: remove a useless prefix from a hundred constants
And use a better word to describe the concise descriptions that
these constants refer to -- they are not messages.
2017-10-28 12:32:47 +02:00
Benno Schulenberg
160ababa55 tweaks: rename a macro, to make a little more sense 2017-10-28 12:32:36 +02:00
Benno Schulenberg
d84fb8d209 tweaks: remove a superfluous no-op function call
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-10-28 12:32:27 +02:00
Benno Schulenberg
14bf53ddfc syntax: default: use colors that are readable also on dark backgrounds 2017-10-26 21:07:11 +02:00
Benno Schulenberg
ded02d858f search: suppress the "Search Wrapped" message when doing replacements
This completes the fix for https://savannah.gnu.org/bugs/?52282.
Reported-by: Chime Hart <chime@hubert-humphrey.com>
2017-10-26 21:07:06 +02:00
Benno Schulenberg
d4945c67a4 search: suppress the "not found" message when replacements were made
After any replacements were made, the "not found" message is pointless
because it will be overwritten rightaway by "Replaced xx occurrences".
The message is confusing and annoying when using speech output.

This partially fixes https://savannah.gnu.org/bugs/?52282.
Reported-by: Chime Hart <chime@hubert-humphrey.com>
2017-10-26 21:06:54 +02:00
David Lawrence Ramsey
ddd300af5f help: allow firstline and lastline to work at the search prompt
This addresses https://savannah.gnu.org/bugs/?52257.
2017-10-25 19:35:41 +02:00
David Lawrence Ramsey
d344c3d042 display: don't cut off zero-width characters at the end of a chunk
This fixes https://savannah.gnu.org/bugs/?52258.
Reported-by: Peter Passchier <peter@passchier.net>
2017-10-25 19:07:38 +02:00
Benno Schulenberg
3018ab4706 moving: don't slither and slide over tabs when they are overlong
This fixes https://savannah.gnu.org/bugs/?52183.

Tested-by: David Lawrence Ramsey <pooka109@gmail.com>
Improved-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-10-25 17:46:39 +02:00
David Lawrence Ramsey
2356693b81 docs: document the more everyday names of three bindable functions
List "browser", "pageup" and "pagedown" in the manuals; the first
because it matches "speller", and the latter two because they are
what these functions are commonly known by.  The names "tofiles",
"prevpage" and "nextpage" are now undocumented, but they are still
recognized by the code, as they match the tags for these functions.
2017-10-25 17:44:13 +02:00
David Lawrence Ramsey
4d35835189 docs: decribe the bindable functions 'recordmacro' and 'runmacro' 2017-10-19 21:37:41 +02:00
David Lawrence Ramsey
f8c75c43ed search: don't bother saving and restoring the search direction
Most people who make use of 'do_findprevious' and 'do_findnext'
will not make use of 'do_search' (the default binding of M-W),
so for them it is superfluous to remember the state of the
Backwards toggle in the Search menu.  For the people that do
mix the usage of Alt+Up/Down with M-W, it means that M-W will
always search in the same direction as the last search.  It is
a small change in behavior.
2017-10-19 21:21:31 +02:00
Benno Schulenberg
af20d45bc1 bindings: don't allow calling help when searching in the help viewer
This fixes https://savannah.gnu.org/bugs/?52246.
2017-10-18 21:46:34 +02:00
Brand Huntsman
08b49534d5 bindings: allow exiting from the help viewer with F1, like with ^G
Signed-off-by: Brand Huntsman <alpha@qzx.com>
2017-10-18 21:10:06 +02:00
Benno Schulenberg
57899550aa tweaks: change the arrows to triangles also for searching in file browser 2017-10-18 20:55:43 +02:00
Benno Schulenberg
e1e6c5f612 bindings: make the search function rebindable again in help and browser
Adjust to the changed meaning of 'whereis': it is no longer do_search()
but do_search_forward().

Hinted-at-by: Brand Huntsman <alpha@qzx.com>
2017-10-18 20:55:09 +02:00
Benno Schulenberg
58ecc034d0 tweaks: change the help-text arrows to triangles, to be more visible
Requested-by: Brand Huntsman <alpha@qzx.com>
2017-10-15 21:23:33 +02:00
Marco Diego Aurélio Mesquita
501d05c5d1 new feature: the ability to record and play back a series of keystrokes
Allow the user to record and run a single macro.  The default binding
for starting and stopping the recording is M-: (Alt + colon) and for
running the macro M-; (Alt + semicolon).

This fulfills https://savannah.gnu.org/bugs/?50314.
Requested-by: Peter Passchier <peter@passchier.net>

Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2017-10-15 20:40:40 +02:00
Benno Schulenberg
fc36ff7275 options: retire 'set backwards' -- it's still recognized but a no-op 2017-10-15 10:45:22 +02:00
Benno Schulenberg
3f735d22a1 bindings: make ^W start always a forward search (as there is ^Q now)
It would be silly for ^W to do a backward search too after using ^Q
once.
2017-10-14 20:34:51 +02:00
Benno Schulenberg
ba65cd48cc bindings: make ^Q and ^S do something useful by default
^S will be the first thing people will try for saving a file,
and ^Q is somewhat mnemonic because it is to the left of ^W:
it searches backward.

Make these keystrokes available also in the tiny version.
2017-10-14 20:34:43 +02:00
Benno Schulenberg
c7eecd74de new feature: a bindable function that starts always a backward search 2017-10-14 20:30:46 +02:00
Benno Schulenberg
a7fa174438 tweaks: adjust indentation and comments after the previous change 2017-10-14 11:58:28 +02:00
Viorel Bota
217cfbf362 files: check for a changed disk file also for 'savefile' and --tempfile
Before writing a file out, nano should check that the file on disk
hasn't been modified since it was read -- not only for the normal
"Write Out" action (^O), but also for "Save File" (future ^S) and
for "Save and Exit" (^X when --tempfile is used).

When writing fails and --tempfile is in effect, don't go on to prompt
for a file name; instead let the user decide what she wants to do.

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

Signed-off-by: Viorel Bota <botaviorel@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2017-10-13 20:24:10 +02:00
Benno Schulenberg
80ed2568fc tweaks: remove a comment from the docs that is no longer accurate
Date and version are updated to match each release, so the user does
not have to wonder whether the man page really describes the binary.

Also remove a bit of superfluous markup.
2017-10-12 21:17:39 +02:00
Benno Schulenberg
7a3a45e6ac moving: prevent the cursor sticking on or skipping over overwide tabs
When we've landed on a tab and we are moving down and the tab starts
before the current chunk, then push the index forward -- otherwise we
would not advance.  When instead we're moving up and the end of the
preceding row is on the same tab as the target column AND the end of
the current row is not on that same tab, then there is some character
on this row that we can put the cursor on, so push the index forward
-- otherwise we would skip a usable row.

This fixes https://savannah.gnu.org/bugs/?52125
and fixes https://savannah.gnu.org/bugs/?52139.
2017-10-12 20:47:06 +02:00
Benno Schulenberg
4436815725 help: don't fall back to other syntaxes if there is no nanohelp one
Also, an absent nanohelp syntax is not an error, so keep mum.

This fixes https://savannah.gnu.org/bugs/?52147.
2017-10-12 19:15:24 +02:00
Benno Schulenberg
d0119833c1 tweaks: reshuffle some regexes, for order and compactness 2017-10-11 21:52:18 +02:00
Brand Huntsman
d4074ca85b syntax: nanohelp: colorize Up, Down, Left and Right (when not in UTF-8)
Signed-off-by: Brand Huntsman <alpha@qzx.com>
2017-10-11 21:50:47 +02:00
Benno Schulenberg
ca8317e820 tweaks: reduce a bit of code duplication
This also removes a call of ungetch(), as it does not seem to be
needed any more: nano does not lose a character when waking from
suspension.
2017-10-04 21:51:47 +02:00
Benno Schulenberg
1bd17c44b0 display: keep the cursor switched on when resizing the screen
This fixes https://savannah.gnu.org/bugs/?52149.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-10-04 21:38:46 +02:00
Benno Schulenberg
762fb4bec5 display: switch off the cursor early on during startup
So the cursor won't be visible at the end of the status-bar message
while reading in a large file.
2017-10-04 21:34:44 +02:00
Benno Schulenberg
a2b4f00a27 tweaks: fix compilation when configured with --disable-histories 2017-10-03 21:39:09 +02:00
Benno Schulenberg
15738c6b39 history: remove the migration service for the old searches file
The code has been there for the last thirty releases -- for six
whole years -- more than enough time to have served its purpose.
2017-10-03 21:18:38 +02:00
David Lawrence Ramsey
ede44e16ff build: add history.c to the list of files with translatable strings
The recent migration of the history routines forgot to add the new
file to the list of files from which strings should be extracted.

This fixes https://savannah.gnu.org/bugs/?52122.
2017-09-27 20:42:24 +02:00
Benno Schulenberg
c8a2f36e87 input: recognize Option+Arrow keys on iTerm2 in "xterm mode"
Inspired-by: Mike Frysinger <vapier@gentoo.org>

This kind of addresses https://savannah.gnu.org/bugs/?51685.
2017-09-26 21:44:01 +02:00
Benno Schulenberg
f2f7498f12 tweaks: rename two variables, for contrast, and frob some comments 2017-09-26 20:54:04 +02:00
Benno Schulenberg
762f997244 tweaks: elide two variables by using a pointer instead of an index 2017-09-26 20:39:58 +02:00
David Lawrence Ramsey
504a97256b softwrap: break before multi-column Unicode blanks when they overshoot
In atblanks mode, if a softwrapped chunk ends with a double-width space
character (say, Unicode 003000, Ideographic Space), and that would put
half of the character past the edge of the screen, break before it.

This fixes https://savannah.gnu.org/bugs/?51671.
2017-09-26 19:56:48 +02:00
David Lawrence Ramsey
3f35e9670f syntax: nanorc: properly color valid arguments of 'selectedcolor'
This fixes https://savannah.gnu.org/bugs/?52114.
2017-09-26 19:35:55 +02:00
Benno Schulenberg
b5346bccb3 tweaks: rename a variable, to avoid a possible confusion
Or rather, to make searching for the PRESERVE option easier.
2017-09-24 21:06:08 +02:00
Benno Schulenberg
7c3c3cbb3b tweaks: discard some obsolete debugging stuff 2017-09-22 21:59:51 +02:00
Benno Schulenberg
b27ab4f0a1 browser: place the cursor properly on the selected file when -g is used
Simply redraw the browser screen upon every keystroke when --showcursor
is in effect, to be certain that the cursor will be placed again at the
correct spot.

This fixes https://savannah.gnu.org/bugs/?52078
and fixes https://savannah.gnu.org/bugs/?52079.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-09-22 21:52:41 +02:00
Benno Schulenberg
c74d2632bb tweaks: make the switching on and off of the cursor a bit more compact 2017-09-22 21:31:01 +02:00
Benno Schulenberg
ae34825f58 display: rework the switching on and off of the cursor
The basic idea is that the cursor is always off, except when it needs
to be on: when waiting for text input, and in a few other cases: when
something was searched and found in the help viewer, and in the file
browser when option -g is in effect.

This fixes https://savannah.gnu.org/bugs/?51923.
Reported-by: Mike Frysinger <vapier@gentoo.org>
2017-09-20 21:35:25 +02:00
Benno Schulenberg
f6b396f206 tweaks: chuck an assert, and then condense the code and a comment 2017-09-19 21:14:05 +02:00
David Lawrence Ramsey
5561d22f19 search: trim a failed search string for width instead of length
When reducing the search string to at most half the screen width,
it should employ its width in columns, not its length in bytes.

Also adjust the type of a variable.

This fixes http://savannah.gnu.org/bugs/?52057.
2017-09-19 21:08:05 +02:00
Benno Schulenberg
aa45994bbb build: let git ignore also the generated PDF file 2017-09-19 20:56:04 +02:00
Benno Schulenberg
2d13afda40 display: stop the help viewer from turning on the multibuffer indicator
This fixes https://savannah.gnu.org/bugs/?52060.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-09-19 20:42:47 +02:00
Benno Schulenberg
fd86696658 tweaks: rename one variable once more
So that it is not a substring of some other name.
2017-09-17 21:40:59 +02:00
Benno Schulenberg
09ab91c79c tweaks: strip four unneeded checks
The functions to read and write history files will not even be called
when the home directory is missing, so there is no need to check for
that eventuality again.
2017-09-17 21:34:16 +02:00
Benno Schulenberg
5f4fb8e513 tweaks: frob some comments and rename a few variables and a function 2017-09-17 20:17:13 +02:00
Benno Schulenberg
7a9d010186 tweaks: rename two variables, to be more indicative of what they do 2017-09-17 17:48:03 +02:00
Benno Schulenberg
231fe4bf01 tweaks: rename a function and swap its two parameters 2017-09-17 17:29:43 +02:00
Benno Schulenberg
067a920517 tweaks: improve some comments, and rename a variable for symmetry 2017-09-17 17:16:36 +02:00
Benno Schulenberg
36e88032cb tweaks: rename two variables, to make a little more sense 2017-09-17 16:54:45 +02:00
Benno Schulenberg
e0a73f58f3 tweaks: drop a bunch of outdated asserts 2017-09-17 12:48:13 +02:00
Benno Schulenberg
1be8eb3b30 tweaks: elide an unneeded check
When history has changed, not all three listst can be empty.
2017-09-17 12:47:28 +02:00
Benno Schulenberg
fb9c180bae history: after loading the lists, mark them as unchanged
Populating the search, replace, and execute lists makes use of the
function update_history() which sets history_changed to TRUE, which
meant that the search_history file would always get written even if
nothing had changed.
2017-09-17 12:47:11 +02:00
Benno Schulenberg
c10a1e54dc tweaks: elide an unneeded function now that stuff is grouped together 2017-09-17 12:46:49 +02:00
Benno Schulenberg
a1c73317f7 organization: move all history-related stuff to its own file 2017-09-17 12:46:36 +02:00
Marco Diego Aurélio Mesquita
a75bf0a1d1 history: remember the list of executed commands across sessions
Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
2017-09-17 12:46:09 +02:00
David Lawrence Ramsey
5f70229c7e moving: set the preferred column properly when doing a smart home
This fixes http://savannah.gnu.org/bugs/?52042.
Reported-by: Mike Frysinger <vapier@gentoo.org>
2017-09-15 21:24:48 +02:00
Marco Diego Aurélio Mesquita
c8363a0d0b history: remember the commands that were executed during this session
Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
2017-09-14 20:10:22 +02:00
Benno Schulenberg
4aec1649f5 docs: remove another remark about indenting lacking undo capability 2017-09-13 19:44:31 +02:00
Benno Schulenberg
153dea1732 tweaks: discard another set of useless asserts 2017-09-13 19:34:45 +02:00
Benno Schulenberg
bb8d65e89c tweaks: reshuffle some code, and rename a variable 2017-09-13 19:34:28 +02:00
Benno Schulenberg
f9bf320fd5 titlebar: don't show nano's name and version when in the file browser 2017-09-13 19:34:14 +02:00
Benno Schulenberg
9738c7997b titlebar: drop the prefix "File: " from before the filename 2017-09-13 19:30:07 +02:00
Benno Schulenberg
cbf4f77d6b titlebar: don't reshow version when dropping back to a single buffer
When multiple files were open and [x/n] was being shown in the title
bar, don't show nano's name and version number when just one buffer
remains open, but show [1/1] instead.  It is less surprising.
2017-09-13 19:29:56 +02:00
Marco Diego Aurélio Mesquita
3fc89e0853 new feature: show current and total number of open buffers in title bar
When multiple buffers are open, replace nano's name and version number
with an indication how many buffers are open preceded by the sequence
number of the current buffer.

Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2017-09-13 19:29:38 +02:00
Benno Schulenberg
ac8eb42a4f tweaks: elide a superfluous allocation 2017-09-12 20:46:14 +02:00
David Lawrence Ramsey
6c2c6b58a4 docs: remove man page reference to indent/unindent lacking undo/redo
This is no longer accurate.
2017-09-12 20:08:50 +02:00
David Lawrence Ramsey
19a1129698 text: hook up indenting and unindenting to the undo/redo code
This is modeled after the comment/uncomment code.  Each line's
individual indent is saved in the string array of the undo
group structure.

This fixes http://savannah.gnu.org/bugs/?46860.
2017-09-12 20:08:30 +02:00
David Lawrence Ramsey
f722c53223 undo: generalize update_comment_undo() into update_multiline_undo()
The function does not contain any comment-specific code, so it can
be used to handle any kind of multiline undo item.

Also, extend the undo group structure to contain an array of strings,
one for each line in the group.  When indent/unindent is hooked up to
the undo/redo code, this will allow the latter to restore the exact
original indents.
2017-09-12 19:49:44 +02:00
Benno Schulenberg
ffc550521c tweaks: chuck a bunch of asserts -- they have lost their usefulness 2017-09-10 14:08:24 +02:00
Benno Schulenberg
8d229cb712 tweaks: rename a variable, to make more sense
Also, remove an unneeded null_at() -- the null byte has been copied,
and reallocating the string would recover very little memory.

Also, call charmove() without using the & operator.
2017-09-10 13:28:13 +02:00
Benno Schulenberg
abf7ac48a1 tweaks: rename three variables, for more contrast 2017-09-10 13:04:03 +02:00
David Lawrence Ramsey
fc0e16f6bc text: move the unindenting of a single line into its own function 2017-09-10 12:59:04 +02:00
David Lawrence Ramsey
57d7f8852d text: move the indenting of a single line into its own function
This is modeled after the undo/redo code for commenting.  do_indent() now
calls indent_a_line() on each line it covers.  The latter function will
eventually be used by the undo/redo code.
2017-09-10 12:43:10 +02:00
Benno Schulenberg
ae25e15d61 startup: don't produce more than three consecutive beeps
This fixes https://savannah.gnu.org/bugs/?51918.
2017-09-02 15:31:02 +02:00
Benno Schulenberg
21ffa883f7 tweaks: use mnemonic constants instead of TRUE and FALSE
And use these constants in another context too.
2017-08-31 22:14:06 +02:00
Benno Schulenberg
98ec41b4fa tweaks: rename three functions, to be shorter or clearer 2017-08-31 22:00:53 +02:00
Benno Schulenberg
a4a32b910a tweaks: reshuffle a couple of lines, and trim some comments 2017-08-31 21:55:10 +02:00
Benno Schulenberg
28cfab7580 tweaks: fix compilation when configured with --enable-tiny
When moving the cursor to the top-left corner, it is not necessary
to compute leftedge because firstcolumn IS the relevant leftedge.

Reported-by: Jordi Mallach <jordi@debian.org>
2017-08-29 19:28:44 +02:00
Benno Schulenberg
758b4e66db po: update translations and regenerate POT file and PO files 2017-08-27 10:31:28 +02:00
Benno Schulenberg
a09eedf0a3 bump version numbers and add a news item for the 2.8.7 release 2017-08-27 09:37:01 +02:00
Benno Schulenberg
1a7ceb8774 tweaks: oops -- use the correct keyword for recency... "age" 2017-08-26 11:11:40 +02:00
Benno Schulenberg
69fcb001ea tweaks: attempt to order the branches on Savannah's cgit by recency 2017-08-26 11:09:39 +02:00
David Lawrence Ramsey
59451da3ac softwrap: correctly move vertically through overwide tabs
Don't skip rows that contain something when moving up, and do put
the cursor in the desired column whenever possible when moving down.

This fixes http://savannah.gnu.org/bugs/?51827
and fixes http://savannah.gnu.org/bugs/?51828.
2017-08-26 10:14:01 +02:00
David Lawrence Ramsey
a850bb2513 moving: redraw not just the new current line but also the prior one
This fixes http://savannah.gnu.org/bugs/?51821.
2017-08-22 19:21:47 +02:00
Benno Schulenberg
047cf9be9c moving: improve retention of the target column somewhat
It's not yet good enough: when proper_x() pushes the index forward,
maybe it should also increase leftedge?  Or go_forward_chunks()?
2017-08-22 16:11:20 +02:00
Benno Schulenberg
97896d30f1 moving: use the correct formula for pushing the index forward
This helps to fix https://savannah.gnu.org/bugs/?51787.
Correction-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-22 16:11:11 +02:00
Benno Schulenberg
fc367a32eb moving: don't push x forward when backward movement lands on a split tab
This fixes https://savannah.gnu.org/bugs/?51809.
2017-08-22 16:05:44 +02:00
David Lawrence Ramsey
5e10528759 display: revamp how screen updates are done in the movement code
When the screen is narrower than a tab is wide, the cursor does not need
to be on the first/last line of the window before an <Up>/<Down> could
need to scroll the screen.

This fixes http://savannah.gnu.org/bugs/?51776.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-21 21:25:55 +02:00
Benno Schulenberg
243380c4a2 mouse: one click of the wheel should move three lines, not three pages
This fixes https://savannah.gnu.org/bugs/?51802.
2017-08-20 20:45:56 +02:00
Benno Schulenberg
49fb755cfc moving: get <Up> unstuck when trying to pass over a sprawling tab
This is a temporary fix.  The resultant movement is erratic and
not what is desired (which is: to stay in the same screen column
as much as possible).
2017-08-20 20:26:05 +02:00
Benno Schulenberg
24a64d37dd softwrap: properly move up and down over tabs that are split over rows
Also, move home to the first character after the tab if the current
chunk starts with a partial tab.

This fixes https://savannah.gnu.org/bugs/?51800.
Original-idea-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-20 20:24:58 +02:00
Benno Schulenberg
a56a881c4b browser: correct the inverted search behavior for Alt+Up/Alt+Down
This should have been added and amended in the previous commit --
my mistake.
2017-08-20 09:22:19 +02:00
David Lawrence Ramsey
633343de24 browser: allow backward/forward re-searches with Alt+Up/Alt+Down
Also bind 'N' to a backward re-search, while retaining 'n' for a
forward one,  This matches the functionality in the help viewer.
2017-08-19 21:49:32 +02:00
David Lawrence Ramsey
5fcda555ea display: constrain line numbers on softwrapped lines with sprawling tabs
Check the column number, not the character index, when suppressing the
line number on chunks other than the first, since the index can be zero
when in fact we're on a later chunk.

This fixes https://savannah.gnu.org/bugs/index.php?51790.
2017-08-19 20:50:01 +02:00
Benno Schulenberg
873f99d96a tweaks: show "where is next" in the help lines of the file browser 2017-08-19 18:11:59 +02:00
Benno Schulenberg
b38b020d18 tweaks: fix compilation with --enable-{tiny,help,multibuffer}
This fixes https://savannah.gnu.org/bugs/?51777.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-19 17:35:58 +02:00
Benno Schulenberg
54a92614b2 tweaks: group all movement routines in corresponding pairs 2017-08-18 22:20:32 +02:00
Benno Schulenberg
86e71fa09d tweaks: specify more directly in what manner to move the viewport 2017-08-18 21:46:55 +02:00
David Lawrence Ramsey
5237a42d65 weeding: remove the unused be_clever parameter from do_home()/do_end() 2017-08-18 20:44:46 +02:00
David Lawrence Ramsey
46ccc9ba6a softwrap: improve left/right navigation across line boundaries
Using do_up() and do_end() when the user types <Left> at the start of
a line, and do_down() and do_home() when typing <Right> at line's end
can be problematic when tabs are wider than the screen, because those
functions convert indexes to columns and back again twice, thus causing
inaccuracies.  Therefore, simply adjust current and current_x directly,
and then redraw the screen.

This fixes https://savannah.gnu.org/bugs/index.php?51778.
2017-08-18 20:04:23 +02:00
David Lawrence Ramsey
e09dbf18b1 display: do show the visible character for a tab when it starts a row
Regardless of whether the row start is at a multiple of the tab size.

This completes the fix for https://savannah.gnu.org/bugs/?51669.
2017-08-17 20:09:50 +02:00
David Lawrence Ramsey
f08d169aa1 softwrap: make sure char_len is set when a tab is wider than a chunk
This fixes https://savannah.gnu.org/bugs/?51770,
and fixes https://savannah.gnu.org/bugs/?51768.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-17 19:39:51 +02:00
Benno Schulenberg
cf14ee2ef3 moving: the current chunk is always 0 when not in softwrap mode
This is a partial fix for https://savannah.gnu.org/bugs/?51770.
Analysis-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-17 19:33:43 +02:00
Benno Schulenberg
8555820afc tweaks: rename a label, to better match its task 2017-08-16 22:00:10 +02:00
Benno Schulenberg
e7bdfebdf4 rcfile: don't leak a shortcut when something goes wrong [coverity scan] 2017-08-16 21:56:56 +02:00
Benno Schulenberg
4bbbb1859b tweaks: adjust the indentation after the previous change
Also rename a variable, to match the saving routine.
2017-08-16 21:46:39 +02:00
Benno Schulenberg
6645351bfc tweaks: avoid trying to stat a file that might be NULL [coverity scan] 2017-08-16 21:39:41 +02:00
Benno Schulenberg
a5981ab043 tweaks: don't close a descriptor when its stream has already been closed 2017-08-16 20:31:38 +02:00
Benno Schulenberg
807f5c2e69 tweaks: do not leak the indentation when all lines are empty 2017-08-16 17:16:18 +02:00
Benno Schulenberg
1b2a091de9 tweaks: condense or improve some comments
Also reshuffle an initialization and drop two useless asserts.
2017-08-16 17:10:40 +02:00
Benno Schulenberg
bd770ea2e7 text: properly unindent lines that consist of only whitespace
The preceding 'for' loop has already established that all the lines are
either unindentable or composed of only blanks.  So if now a line cannot
be unindented, it means it is fully blank, so it can be simply skipped.

This fixes https://savannah.gnu.org/bugs/?51760.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-16 16:42:44 +02:00
Benno Schulenberg
c3de3ece32 gnulib: update to its current upstream state 2017-08-15 22:00:14 +02:00
Benno Schulenberg
8b86af3fef tweaks: adjust the indentation after the previous change 2017-08-15 19:13:22 +02:00
Benno Schulenberg
21a5978027 tweaks: reshuffle some code to harmonize two related functions 2017-08-15 18:05:06 +02:00
Benno Schulenberg
b4fd08fa5e tweaks: keep the const qualifier of the syntax name [coverity scan]
Also, reduce the scope of the 'line' variable.
2017-08-15 17:20:07 +02:00
Benno Schulenberg
252dc138a2 tweaks: reshuffle some declarations and trim a few comments 2017-08-15 14:15:23 +02:00
Benno Schulenberg
de57d8b722 files: don't try to open a negative file descriptor [coverity scan] 2017-08-15 13:48:25 +02:00
Benno Schulenberg
dbbe267d71 files: don't close a file descriptor when opening failed [coverity scan]
Also, don't depend on statting the relative path, because if that would
fail, we would try to open a NULL pointer.
2017-08-15 13:06:31 +02:00
Benno Schulenberg
eed0090e32 tweaks: close a file also in the error path [coverity scan] 2017-08-15 12:24:18 +02:00
Benno Schulenberg
52e2e52db3 tweaks: allow enough space for the Y/N/A characters [coverity scan] 2017-08-15 12:04:52 +02:00
Benno Schulenberg
3f0e42c13b syntax: c: give labels some color too 2017-08-15 11:00:31 +02:00
Benno Schulenberg
d8e5799e84 tweaks: adjust the indentation after the previous change
Also, trim or improve some comments.
2017-08-15 10:38:58 +02:00
David Lawrence Ramsey
0f4716e168 text: make unindenting remove from the beginning of the line
Also, only unindent when all selected lines can be unindented,
which means that the relative indentation will be preserved.
For this purpose, it ignores empty lines and lines consisting
of only whitespace.

When unindenting is not possible, a message is shown.

This fixes https://savannah.gnu.org/bugs/?47684.
2017-08-15 10:38:58 +02:00
David Lawrence Ramsey
749b1b3d79 text: make indenting add to the beginning of the line
Instead of inserting the extra whitespace after the current indentation
of a line, add it to the start of the line.  This causes a fixed amount
of visual whitespace to be added regardless of whether --tabstospaces
is used or not.

This fixes http://savannah.gnu.org/bugs/?51438,
and its ancestor https://savannah.gnu.org/bugs/?51408.
2017-08-15 10:38:58 +02:00
David Lawrence Ramsey
566a2daf12 tweaks: remove unneeded parentheses and blank line and braces 2017-08-14 21:46:25 +02:00
Benno Schulenberg
9f6c3a6269 display: don't doubly show tabs that cross a chunk boundary
This fixes https://savannah.gnu.org/bugs/?51669.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-14 21:31:55 +02:00
Benno Schulenberg
6273768797 tweaks: renumber the special key codes, to be in sequence and grouped 2017-08-14 10:42:09 +02:00
Benno Schulenberg
4562401505 bindings: hard-bind Alt+Up and Alt+Down to findprevious and findnext
So that these functions have bindings by default, and easy bindings.
Add them to the help viewer too, so that searching backward becomes
possible there.
2017-08-14 10:34:15 +02:00
Urja Rannikko
1cc030f7c1 bindings: hard-bind Alt+Left and Alt+Right to buffer switching
This also fixes https://savannah.gnu.org/bugs/?51735.
Reported-by: Urja Rannikko <urjaman@gmail.com>

Signed-off-by: Urja Rannikko <urjaman@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2017-08-14 10:06:29 +02:00
David Lawrence Ramsey
65d1655134 softwrap: don't push a straddling tab to the next chunk
Tabs are of variable length depending on position, so allow them
to be displayed partially on one chunk and partially on another.

This fixes http://savannah.gnu.org/bugs/?51621.
2017-08-13 21:06:23 +02:00
David Lawrence Ramsey
8e779b6e85 softwrap: properly update the viewport when adding text at firstcolumn
Adding text plus whitespace while the cursor is at or near the topleft
corner of the edit window can cause a change in the preceding chunk,
throwing firstcolumn out of alignment.  Catch this special case.

This fixes http://savannah.gnu.org/bugs/?51743.
2017-08-13 13:46:49 +02:00
Benno Schulenberg
3ab943c49a tweaks: condense some logic, to elide a variable and a comment 2017-08-13 10:09:02 +02:00
Benno Schulenberg
ec20e3a7a8 tweaks: rename a function, to let it make more sense
Further, slightly reword an error message so it is appropriate also
when an out-of-bounds file is specified on the command line.
2017-08-13 10:08:50 +02:00
Benno Schulenberg
dd88842d5a tweaks: elide the global variable 'full_operating_dir'
There is no need to retain the (relative) path that the user
specified, so we can simply reuse that variable.
2017-08-13 10:08:37 +02:00
Benno Schulenberg
751e7f0fbe files: do not silently ignore an invalid backup directory, but die
It would be horrible if the user expects to find numbered backups
of all the files that were changed but they are NOT there because
the config file contains a typo or the relevant directory was moved
or renamed or something.  So... if the specified backup directory
is not usable, nano should complain and simply not start up.
2017-08-13 10:08:29 +02:00
Benno Schulenberg
ee3254b614 tweaks: simply set the proper scrolling mode, instead of imitating it 2017-08-10 12:28:39 +02:00
Benno Schulenberg
938aa63dfa tweaks: drop some debugging stuff 2017-08-08 22:09:22 +02:00
Benno Schulenberg
06ffcfaf40 display: catch all cases where the cursor can be pushed offscreen
Discarding (in commit 6f9bb53b) the cap on the number of chunks to
move backwards had as an unforeseen side effect that the screen can
fail to scroll when the cursor is somehow pushed offscreen.

Fix this by setting the target row (for smooth scrolling) always to
the bottom row of the edit window when nano notices that the cursor
has gone offscreen.

This fixes https://savannah.gnu.org/bugs/?51676.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-08 22:06:55 +02:00
Benno Schulenberg
f2317cc64e tweaks: a comma does not end a sentence, and is not part of a variable 2017-08-08 21:45:21 +02:00
Benno Schulenberg
b281fd7a9d tweaks: snip a superfluous clearing of the bottom bars after help
The edit subwindow will be completely redrawn twelve lines down,
and window_init() takes care of clearing the status bar.
2017-08-08 19:56:00 +02:00
David Lawrence Ramsey
7e334c95cb tweaks: harmonize some prototypes with their functions
Match three variable names in the prototypes
to the changd ones in their functions in utils.c.
2017-08-06 21:39:38 +02:00
Benno Schulenberg
11072ed587 tweaks: sort the includes, so it's a little easier to see what is there 2017-08-06 19:40:30 +02:00
Benno Schulenberg
67915f5dae tweaks: restore an include that is necessary on some platforms
This fixes https://savannah.gnu.org/bugs/?51674.
Reported-by: David Lawrence Ramsey <pooka109@gmail.com>
2017-08-06 19:34:16 +02:00
Benno Schulenberg
884d410d9d syntax: python: don't require a character after an opening triple quote
The succeeding character was needed to avoid miscolorings due to nano
getting confused about starts and ends.  But since commit 7ef5c532,
nano should be getting the starts and ends always right, so... undo
"temporary" commit 7b2ea405 from two years ago.

This addresses https://savannah.gnu.org/bugs/?51526.
Reported-by: <exodus6395@googlemail.com>
2017-08-06 09:50:34 +02:00
David Lawrence Ramsey
1c1cbae6bc small addition: allow customizing the color of selected text
The new option 'set selectedcolor' applies to marked text, to the
currently selected file in the file browser, and to the highlighted
match during interactive search-and-replace.
2017-08-06 09:30:32 +02:00
Benno Schulenberg
276ab2c85e tweaks: reshuffle code and frob comments, to reduce the number of lines 2017-08-06 09:08:45 +02:00
Benno Schulenberg
80686bb525 tweaks: remove includes that appear to be superfluous
Without them, nano still compiles for me, with everything enabled,
even when using --enable-debug, --enable-utf8, and --with-slang.
2017-08-06 09:08:30 +02:00
David Lawrence Ramsey
969e99bc85 tweaks: adjust spacing and wording in sample.nanorc 2017-08-06 09:08:02 +02:00
Benno Schulenberg
94b484ea97 syntax: html: don't bother coloring tags that cross line boundaries
Prefer speed above being fully correct.

This addresses https://savannah.gnu.org/bugs/?51644.
2017-08-03 21:18:34 +02:00
David Lawrence Ramsey
ac2c81fad1 tweaks: correct a comment typo and an indentation error 2017-07-31 21:42:39 +02:00
Rishabh Dave
829a1a5050 new feature: allow pasting at all input prompts
Include the shortcut for 'Uncut' into most menus, and add an uncut
function for the status bar, so that it becomes possible to paste
the first line of the cutbuffer at any text-input prompt.

This fulfills https://savannah.gnu.org/bugs/?48501.
Requested-by: Benno Schulenberg <bensberg@telfort.nl>
Signed-off-by: Rishabh Dave <rishabhddave@gmail.com>
2017-07-29 13:48:22 +02:00
Benno Schulenberg
5dcf375f33 linting: skip the introductory message produced by 'gcc -fshow-column'
Assume that a linter line that contains an actual error message or
warning includes a colon followed by a space -- something that that
opening message from a modern gcc lacks.
2017-07-29 13:15:22 +02:00
Benno Schulenberg
50379cc4ff tweaks: elide an unneeded pointer 2017-07-27 22:05:19 +02:00
David Lawrence Ramsey
e2d3ee2364 tweaks: replace a misplaced tab with a space 2017-07-27 21:58:00 +02:00
David Lawrence Ramsey
beae2da10d weeding: remove redundant casts of nmalloc()
A cast on the same line as a variable declaration is superfluous,
because it effectively defines the type of the variable twice.
2017-07-27 21:54:37 +02:00
Benno Schulenberg
79c836b11b tweaks: drop some debugging stuff, and frob two comments 2017-07-27 21:45:53 +02:00
Benno Schulenberg
c24432edc4 linting: don't try to put the cursor at a negative x position
Human column numbers are one-based, whereas x positions are zero-based.
Converting from the one to the other involves subtracting one.  But when
the linter message does not provide a column number, the latter defaults
to zero.  Catch that case and change the number to one.

This fixes https://savannah.gnu.org/bugs/?51550.
2017-07-26 21:31:41 +02:00
David Lawrence Ramsey
85bffcfeb9 tweaks: use charalloc() instead of (char *)nmalloc() * sizeof(char)
The charalloc() macro does exactly this.
2017-07-25 21:50:13 +02:00
David Lawrence Ramsey
381a386b01 weeding: drop the forreal parameter from place_the_cursor()
Commit 28beb3f added the 'forreal' parameter to prevent spotlight() from
placing the cursor wrongly due to an invalid placewewant.  However, since
the variable-width softwrap overhaul (specifically, since commit 8490f4a),
place_the_cursor() no longer checks placewewant, so the parameter is no
longer needed.

Furthermore, dropping 'forreal' and thus always setting current_y won't
affect the operation of spotlight(), since the only functions that use
spotlight() (do_replace_loop() and do_int_spell_fix()) both call
edit_refresh() beforehand, which means that current_y will already
have been set to the value it will be set to again.
2017-07-24 21:07:42 +02:00
David Lawrence Ramsey
6f9bb53b2d tweaks: set the target row for smooth scrolling more directly
The function place_the_cursor() assumes that the viewport is up to date,
i.e., that current is in range of edittop.  When uncutting or inserting,
however, place_the_cursor() gets called on the out-of-date viewport
first, and then a screen refresh is scheduled (which would put the
viewport up to date).  This is backwards: the refresh should come before
the cursor placement, and the only reason it works anyway is because the
cap on the number of chunks to move backward papers over the problem by
keeping current_y in screen range regardless.

Fix this properly by simply setting current_y to the bottom row of the
screen instead of calling place_the_cursor().  This value of current_y
is only ever used when in smooth scrolling mode and the insertion (or
paste) pushed the cursor offscreen.  In other situations, this value is
overridden when place_the_cursor() gets called after a screen refresh.

After that fix, the cap on the number of chunks to move backward is no
longer needed.
2017-07-23 12:16:59 +02:00
92 changed files with 26956 additions and 25177 deletions

267
ChangeLog
View File

@@ -1,3 +1,270 @@
Changes between v2.9.0 and v2.9.1:
----------------------------------
Benno Schulenberg (20):
build: fix compilation with --disable-browser --disable-tabcomp
bump version numbers and add a news item for the 2.9.1 release
files: always update the stat info when the entire file is written
files: save the marked region only when we've prompted for a file name
gnulib: update to its current upstream state
history: create the path '~/.local/share/' when it is needed
history: make nano's state directory accessible for the user only
history: save the positions file also when a record was deleted
input: make the macro key discoverable by giving feedback when undefined
linting: switch the mark off when the linter starts
selecting: do not cancel the softmark when the cursor is not moved
selecting: let a justification cancel a softmark
syntax: adjust the magic strings for the changes since file-5.10
tweaks: adjust indentation after previous change
tweaks: elide the 'mark_set' boolean -- the 'mark' pointer is enough
tweaks: rename, rewrap, and reshuffle some stuff, and frob some comments
tweaks: reshuffle a couple of lines, and frob a comment or two
tweaks: reshuffle a couple of lines, to put similar things together
undo: clear the Modified state when the very first edit is undone
undo: discarding the stack does not always lose information
Changes between v2.8.7 and v2.9.0:
----------------------------------
Benno Schulenberg (103):
bindings: don't allow calling help when searching in the help viewer
bindings: make ^Q and ^S do something useful by default
bindings: make the search function rebindable again in help and browser
bindings: make ^W start always a forward search (as there is ^Q now)
browser: place the cursor properly on the selected file when -g is used
build: let git ignore also the generated PDF file
bump version numbers and add a news item for the 2.9.0 release
copyright: update some years, and standardize on the dashed format
display: keep the cursor switched on when resizing the screen
display: rework the switching on and off of the cursor
display: stop the help viewer from turning on the multibuffer indicator
display: switch off the cursor early on during startup
docs: make it clearer that a Signed-off-by is wanted on patches
docs: mention that macros work correctly only on terminal emulators
docs: remove another remark about indenting lacking undo capability
docs: update references to the nanorc files for the XDG changes
files: avoid an abortion when excuting a command in a new buffer
gnulib: update to its current upstream state
help: don't fall back to other syntaxes if there is no nanohelp one
history: after loading the lists, mark them as unchanged
history: remove the migration service for the old searches file
input: recognize Option+Arrow keys on iTerm2 in "xterm mode"
moving: don't slither and slide over tabs when they are overlong
moving: prevent the cursor sticking on or skipping over overwide tabs
new feature: a bindable function that starts always a backward search
options: remove '--quiet' and 'set quiet', because they hide problems
options: retire 'set backwards' -- it's still recognized but a no-op
organization: move all history-related stuff to its own file
ouch: set the positions-file name also when using the legacy state dir
painting: evade an ncurses bug by adding the A_PROTECT attribute
search: suppress the "not found" message when replacements were made
search: suppress the "Search Wrapped" message when doing replacements
search: wipe reassuring feedback as soon as searching has finished
startup: don't ask the user to press Enter upon an rcfile error
startup: don't produce more than three consecutive beeps
startup: when an rcfile contains errors, report this on the status bar
syntax: default: use colors that are readable also on dark backgrounds
titlebar: don't reshow version when dropping back to a single buffer
titlebar: don't show nano's name and version when in the file browser
titlebar: drop the prefix "File: " from before the filename
tweaks: add a translator hint, and adjust two others
tweaks: adjust a comment, and condense a fragment of code
tweaks: adjust indentation and comments after the previous change
tweaks: adjust two comments, and correct and a few cosmetic mistakes
tweaks: avoid an unused-variable warning with --disable-nanorc
tweaks: change some mayday messages, to urge the user to report a bug
tweaks: change the arrows to triangles also for searching in file browser
tweaks: change the help-text arrows to triangles, to be more visible
tweaks: chuck a bunch of asserts -- they have lost their usefulness
tweaks: chuck an assert, and then condense the code and a comment
tweaks: constify the result strings of getenv(), as a reminder
tweaks: correct two minor things in the documentation
tweaks: discard another set of useless asserts
tweaks: discard some obsolete debugging stuff
tweaks: don't construct the positions-history filename time and again
tweaks: drop a bunch of outdated asserts
tweaks: drop the ineffective cgitrc -- sorting by "age" does not work
tweaks: elide a comment, and improve a couple of others
tweaks: elide an unneeded check
tweaks: elide an unneeded function now that stuff is grouped together
tweaks: elide a superfluous allocation
tweaks: elide two variables by using a pointer instead of an index
tweaks: fix compilation when configured with --disable-histories
tweaks: fix compilation when configured with --enable-tiny
tweaks: fix compilation with --enable-tiny --enable-histories
tweaks: frob a couple of comments
tweaks: frob some comments and rename a few variables and a function
tweaks: get rid of some cluttering conditional compilation
tweaks: improve some comments, and rename a variable for symmetry
tweaks: make the switching on and off of the cursor a bit more compact
tweaks: move a general function to the utils.c file
tweaks: reduce a bit of code duplication
tweaks: remove a comment from the docs that is no longer accurate
tweaks: remove another bit of conditional compilation
tweaks: remove a superfluous no-op function call
tweaks: remove a useless prefix from a hundred constants
tweaks: rename a function and swap its two parameters
tweaks: rename a function plus two parameters, to be more fitting
tweaks: rename a macro, to make a little more sense
tweaks: rename a variable, to avoid a possible confusion
tweaks: rename a variable, to make more sense
tweaks: rename one variable once more
tweaks: rename some constants, to follow the same underscoreless scheme
tweaks: rename three functions, to be shorter or clearer
tweaks: rename three variables, for more contrast
tweaks: rename two variables, for contrast, and frob some comments
tweaks: rename two variables, to be more indicative of what they do
tweaks: rename two variables, to make a little more sense
tweaks: reshuffle a bit of code and elide an unneeded variable
tweaks: reshuffle a couple of lines, and trim some comments
tweaks: reshuffle some code, and rename a variable
tweaks: reshuffle some code in order to elide a variable
tweaks: reshuffle some regexes, for order and compactness
tweaks: strip four unneeded checks
tweaks: transform the token DISABLE_COLOR to ENABLE_COLOR
tweaks: transform the token DISABLE_EXTRA to ENABLE_EXTRA
tweaks: transform the token DISABLE_HISTORIES to ENABLE_HISTORIES
tweaks: transform the token DISABLE_JUSTIFY to ENABLE_JUSTIFY
tweaks: transform the token DISABLE_OPERATINGDIR to ENABLE_OPERATINGDIR
tweaks: transform the token DISABLE_SPELLER to ENABLE_SPELLER
tweaks: transform the token DISABLE_WRAPJUSTIFY to ENABLED_WRAPORJUSTIFY
tweaks: transform the token DISABLE_WRAPPING to ENABLE_WRAPPING
tweaks: use mnemonic constants instead of TRUE and FALSE
Brand Huntsman (3):
bindings: allow exiting from the help viewer with F1, like with ^G
history: prevent overwriting of positions between multiple instances
syntax: nanohelp: colorize Up, Down, Left and Right (when not in UTF-8)
David Lawrence Ramsey (18):
build: add history.c to the list of files with translatable strings
display: don't cut off zero-width characters at the end of a chunk
docs: decribe the bindable functions 'recordmacro' and 'runmacro'
docs: document the more everyday names of three bindable functions
docs: remove man page reference to indent/unindent lacking undo/redo
files: don't change file format when inserting into an existing buffer
help: allow firstline and lastline to work at the search prompt
history: fix the check for an existing $HOME/.nano/ directory
moving: set the preferred column properly when doing a smart home
search: don't bother saving and restoring the search direction
search: trim a failed search string for width instead of length
softwrap: break before multi-column Unicode blanks when they overshoot
syntax: nanorc: properly color valid arguments of 'selectedcolor'
text: hook up indenting and unindenting to the undo/redo code
text: move the indenting of a single line into its own function
text: move the unindenting of a single line into its own function
tweaks: use printf's z modifier for most of the size_t/ssize_t types
undo: generalize update_comment_undo() into update_multiline_undo()
Lion Yang (1):
input: ensure that standard input uses blocking mode
Marco Diego Aurélio Mesquita (5):
general: do not free strings gotten from getenv(), to avoid a crash
history: remember the commands that were executed during this session
history: remember the list of executed commands across sessions
new feature: show current and total number of open buffers in title bar
new feature: the ability to record and play back a series of keystrokes
Simon Ochsenreither (1):
startup: look for nanorc and history files also in the XDG directories
Viorel Bota (1):
files: check for a changed disk file also for 'savefile' and --tempfile
Changes between v2.8.6 and v2.8.7:
----------------------------------
Benno Schulenberg (54):
bindings: hard-bind Alt+Up and Alt+Down to findprevious and findnext
browser: correct the inverted search behavior for Alt+Up/Alt+Down
bump version numbers and add a news item for the 2.8.7 release
display: catch all cases where the cursor can be pushed offscreen
display: don't doubly show tabs that cross a chunk boundary
files: do not silently ignore an invalid backup directory, but die
files: don't close a file descriptor when opening failed [coverity scan]
files: don't try to open a negative file descriptor [coverity scan]
gnulib: update to its current upstream state
linting: don't try to put the cursor at a negative x position
linting: skip the introductory message produced by 'gcc -fshow-column'
mouse: one click of the wheel should move three lines, not three pages
moving: don't push x forward when backward movement lands on a split tab
moving: get <Up> unstuck when trying to pass over a sprawling tab
moving: improve retention of the target column somewhat
moving: the current chunk is always 0 when not in softwrap mode
moving: use the correct formula for pushing the index forward
rcfile: don't leak a shortcut when something goes wrong [coverity scan]
softwrap: properly move up and down over tabs that are split over rows
syntax: c: give labels some color too
syntax: html: don't bother coloring tags that cross line boundaries
syntax: python: don't require a character after an opening triple quote
text: properly unindent lines that consist of only whitespace
tweaks: a comma does not end a sentence, and is not part of a variable
tweaks: adjust the indentation after the previous change
tweaks: adjust the indentation after the previous change
tweaks: adjust the indentation after the previous change
tweaks: allow enough space for the Y/N/A characters [coverity scan]
tweaks: avoid trying to stat a file that might be NULL [coverity scan]
tweaks: close a file also in the error path [coverity scan]
tweaks: condense or improve some comments
tweaks: condense some logic, to elide a variable and a comment
tweaks: do not leak the indentation when all lines are empty
tweaks: don't close a descriptor when its stream has already been closed
tweaks: drop some debugging stuff
tweaks: drop some debugging stuff, and frob two comments
tweaks: elide an unneeded pointer
tweaks: elide the global variable 'full_operating_dir'
tweaks: fix compilation with --enable-{tiny,help,multibuffer}
tweaks: group all movement routines in corresponding pairs
tweaks: keep the const qualifier of the syntax name [coverity scan]
tweaks: remove includes that appear to be superfluous
tweaks: rename a function, to let it make more sense
tweaks: rename a label, to better match its task
tweaks: renumber the special key codes, to be in sequence and grouped
tweaks: reshuffle code and frob comments, to reduce the number of lines
tweaks: reshuffle some code to harmonize two related functions
tweaks: reshuffle some declarations and trim a few comments
tweaks: restore an include that is necessary on some platforms
tweaks: show "where is next" in the help lines of the file browser
tweaks: simply set the proper scrolling mode, instead of imitating it
tweaks: snip a superfluous clearing of the bottom bars after help
tweaks: sort the includes, so it's a little easier to see what is there
tweaks: specify more directly in what manner to move the viewport
David Lawrence Ramsey (23):
browser: allow backward/forward re-searches with Alt+Up/Alt+Down
display: constrain line numbers on softwrapped lines with sprawling tabs
display: do show the visible character for a tab when it starts a row
display: revamp how screen updates are done in the movement code
moving: redraw not just the new current line but also the prior one
small addition: allow customizing the color of selected text
softwrap: correctly move vertically through overwide tabs
softwrap: don't push a straddling tab to the next chunk
softwrap: improve left/right navigation across line boundaries
softwrap: make sure char_len is set when a tab is wider than a chunk
softwrap: properly update the viewport when adding text at firstcolumn
text: make indenting add to the beginning of the line
text: make unindenting remove from the beginning of the line
tweaks: adjust spacing and wording in sample.nanorc
tweaks: correct a comment typo and an indentation error
tweaks: harmonize some prototypes with their functions
tweaks: remove unneeded parentheses and blank line and braces
tweaks: replace a misplaced tab with a space
tweaks: set the target row for smooth scrolling more directly
tweaks: use charalloc() instead of (char *)nmalloc() * sizeof(char)
weeding: drop the forreal parameter from place_the_cursor()
weeding: remove redundant casts of nmalloc()
weeding: remove the unused be_clever parameter from do_home()/do_end()
Rishabh Dave (1):
new feature: allow pasting at all input prompts
Urja Rannikko (1):
bindings: hard-bind Alt+Left and Alt+Right to buffer switching
Changes between v2.8.5 and v2.8.6:
----------------------------------

View File

@@ -1,7 +1,16 @@
Improvements in GNU nano
========================
Since 2.9.0:
- The ability to record and replay a series of keystrokes (a macro).
- Assigned functions to ^S (save file) and ^Q (start backward search).
- Indenting and unindenting have been integrated into the undo system.
- Support for $XDG_CONFIG_HOME for the nanorc file, and $XDG_DATA_HOME
for the history files (of search strings and cursor positions).
Since 2.8.0:
- Meta-Up/Meta-Down will search the previous/next occurrence.
- ^U pastes the first line of the cutbuffer at a prompt.
- Softwrapping can be done at whitespace (with --soft --atblanks).
- The ^G help texts have become searchable (with ^W and M-W).
- Ctrl+Home and Ctrl+End jump to start and end of file.

37
NEWS
View File

@@ -1,3 +1,36 @@
2017.11.27 - GNU nano 2.9.1 "Damyatta" fixes a bug where, when the mark
is on, ^S would overwrite the file with just the marked
region. This release further clears the "Modified" flag
when all edits are undone, adds or updates some magic
strings, and does not forget when the cursor was last
at line 1, column 1.
2017.11.18 - GNU nano 2.9.0 "Eta" introduces the ability to record and
replay keystrokes (M-: to start and stop recording, M-;
to play the macro back), makes ^Q and ^S do something
useful by default (^Q starts a backward search, and ^S
saves the current file), changes ^W to start always a
forward search, shows the number of open buffers (when
more than one) in the title bar, no longer asks to press
Enter when there are errors in an rc file, retires the
options '--quiet' and 'set quiet' and 'set backwards',
makes indenting and unindenting undoable, will look in
$XDG_CONFIG_HOME for a nanorc file and in $XDG_DATA_HOME
for the history files, adds a history stack for executed
commands (^R^X), does not overwrite the position-history
file of another nano, and fixes a score of tiny bugs.
2017.08.27 - GNU nano 2.8.7 "Fragrance" fixes a lockup when tabs are
wider than the screen, makes indenting + unindenting
more predictable by retaining relative indentations,
allows pasting (^U) at a prompt, allows triple quotes
in Python to not be followed by a character, does not
scroll three pages on a roll of the mouse wheel, binds
Alt+Up and Alt+Down to findprevious and findnext, and
fixes some hard-to-describe issues with softwrapping
and boundary-crossing tabs. Enjoy.
2017.07.21 - GNU nano 2.8.6 "Kekulé" offers a new feature: the ability
to do softwrapping between words -- at whitespace --
instead of always at the edge of the screen. This can
@@ -307,7 +340,7 @@
many many improvements to the core system, including
substantial improvements to the undo/redo code, UTF-8
handling, the configure script, and display of shortcuts
on very wide terminals, New features include the
on very wide terminals. New features include the
ability to write to named pipes (--noread), as well as
linter support (see the nanorc man page for details). Also
included are much improved syntax highlighting code, and
@@ -1617,7 +1650,7 @@
2000.02.02 - Okay, I hate to go back on what I said in the last release,
but I may be changing jobs very soon. I will release
version 0.8.2 as is (no i18n, no help menu (yet). I
version 0.8.2 as is (no i18n, no help menu (yet)). I
expect things to settle down by the end of next week,
and then I can try to start on the i18n support and help
menu; look for these new features in version 0.8.5 to

View File

@@ -93,12 +93,15 @@ 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:
Then change the code so it does what you want, and commit it together
with your Sign-off:
$ git commit -as
Then create a patch (or patches):
In the commit message (after the one-line summary) give a rationale
for the change. With your Signed-off-by you declare that the code is
yours, or that you are free to reuse it, and that you submit it under
the license that covers nano. Then create a patch (or patches):
$ git format-patch master

View File

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

View File

@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
AC_INIT([GNU nano], [2.8.6], [nano-devel@gnu.org], [nano])
AC_INIT([GNU nano], [2.9.1], [nano-devel@gnu.org], [nano])
AC_CONFIG_SRCDIR([src/nano.c])
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([1.14])
@@ -75,6 +75,15 @@ fi
AC_ARG_ENABLE(color,
AS_HELP_STRING([--disable-color], [Disable color and syntax highlighting]))
if test "x$enable_tiny" = xyes; then
if test "x$enable_color" = xyes; then
if test "x$enable_nanorc" != xyes; then
AC_MSG_ERROR([--enable-color needs --enable-nanorc to work])
fi
else
enable_color=no
fi
fi
if test "x$enable_nanorc" = xno; then
if test "x$enable_color" = xyes; then
AC_MSG_ERROR([--enable-color cannot work with --disable-nanorc])
@@ -83,9 +92,8 @@ if test "x$enable_nanorc" = xno; then
enable_color=no
fi
fi
if test "x$enable_color" = xno; then
AC_DEFINE(DISABLE_COLOR, 1, [Define this to disable syntax highlighting.])
else
if test "x$enable_color" != xno; then
AC_DEFINE(ENABLE_COLOR, 1, [Define this to have syntax highlighting.])
color_support=yes
fi
@@ -104,8 +112,13 @@ fi
AC_ARG_ENABLE(extra,
AS_HELP_STRING([--disable-extra], [Disable the Easter egg]))
if test "x$enable_extra" = xno; then
AC_DEFINE(DISABLE_EXTRA, 1, [Define this to disable extra stuff.])
if test "x$enable_tiny" = xyes; then
if test "x$enable_extra" != xyes; then
enable_extra=no
fi
fi
if test "x$enable_extra" != xno; then
AC_DEFINE(ENABLE_EXTRA, 1, [Define this to have an Easter egg.])
fi
AC_ARG_ENABLE(help,
@@ -133,14 +146,24 @@ fi
AC_ARG_ENABLE(histories,
AS_HELP_STRING([--disable-histories], [Disable search and position histories]))
if test "x$enable_histories" = xno; then
AC_DEFINE(DISABLE_HISTORIES, 1, [Define this to disable search and position histories.])
if test "x$enable_tiny" = xyes; then
if test "x$enable_histories" != xyes; then
enable_histories=no
fi
fi
if test "x$enable_histories" != xno; then
AC_DEFINE(ENABLE_HISTORIES, 1, [Define this to have search and position histories.])
fi
AC_ARG_ENABLE(justify,
AS_HELP_STRING([--disable-justify], [Disable the justify/unjustify functions]))
if test "x$enable_justify" = xno; then
AC_DEFINE(DISABLE_JUSTIFY, 1, [Define this to disable the justify routines.])
if test "x$enable_tiny" = xyes; then
if test "x$enable_justify" != xyes; then
enable_justify=no
fi
fi
if test "x$enable_justify" != xno; then
AC_DEFINE(ENABLE_JUSTIFY, 1, [Define this to have the routines for justifying.])
fi
AC_ARG_ENABLE(libmagic,
@@ -193,14 +216,24 @@ fi
AC_ARG_ENABLE(operatingdir,
AS_HELP_STRING([--disable-operatingdir], [Disable the setting of an operating directory]))
if test "x$enable_operatingdir" = xno; then
AC_DEFINE(DISABLE_OPERATINGDIR, 1, [Define this to disable the setting of an operating directory (a chroot of sorts).])
if test "x$enable_tiny" = xyes; then
if test "x$enable_operatingdir" != xyes; then
enable_operatingdir=no
fi
fi
if test "x$enable_operatingdir" != xno; then
AC_DEFINE(ENABLE_OPERATINGDIR, 1, [Define this to allow setting an operating directory (a chroot of sorts).])
fi
AC_ARG_ENABLE(speller,
AS_HELP_STRING([--disable-speller], [Disable the spell-checker functions]))
if test "x$enable_speller" = xno; then
AC_DEFINE(DISABLE_SPELLER, 1, [Define this to disable the spell-checker functions.])
if test "x$enable_tiny" = xyes; then
if test "x$enable_speller" != xyes; then
enable_speller=no
fi
fi
if test "x$enable_speller" != xno; then
AC_DEFINE(ENABLE_SPELLER, 1, [Define this to have the spell-checker functions.])
fi
AC_ARG_ENABLE(tabcomp,
@@ -229,8 +262,13 @@ fi
AC_ARG_ENABLE(wrapping,
AS_HELP_STRING([--disable-wrapping], [Disable all hard-wrapping of text]))
if test "x$enable_wrapping" = xno; then
AC_DEFINE(DISABLE_WRAPPING, 1, [Define this to disable all hard text wrapping.])
if test "x$enable_tiny" = xyes; then
if test "x$enable_wrapping" != xyes; then
enable_wrapping=no
fi
fi
if test "x$enable_wrapping" != xno; then
AC_DEFINE(ENABLE_WRAPPING, 1, [Define this to have hard text wrapping.])
fi
AC_ARG_ENABLE(wrapping-as-root,
@@ -251,35 +289,9 @@ AC_ARG_ENABLE(tiny,
AS_HELP_STRING([--enable-tiny], [Disable features for the sake of size]))
if test "x$enable_tiny" = xyes; then
AC_DEFINE(NANO_TINY, 1, [Define this to make the nano executable as small as possible.])
if test "x$enable_color" != xyes; then
AC_DEFINE(DISABLE_COLOR, 1, [Define this to disable syntax highlighting.])
color_support=no
else
if test "x$enable_nanorc" != xyes; then
AC_MSG_ERROR([--enable-color needs --enable-nanorc to work])
fi
fi
if test "x$enable_extra" != xyes; then
AC_DEFINE(DISABLE_EXTRA, 1, [Define this to disable extra stuff.])
fi
if test "x$enable_histories" != xyes; then
AC_DEFINE(DISABLE_HISTORIES, 1, [Define this to disable search and position histories.])
fi
if test "x$enable_justify" != xyes; then
AC_DEFINE(DISABLE_JUSTIFY, 1, [Define this to disable the justify routines.])
fi
if test "x$enable_libmagic" != xyes; then
enable_libmagic=no
fi
if test "x$enable_operatingdir" != xyes; then
AC_DEFINE(DISABLE_OPERATINGDIR, 1, [Define this to disable the setting of an operating directory (a chroot of sorts).])
fi
if test "x$enable_speller" != xyes; then
AC_DEFINE(DISABLE_SPELLER, 1, [Define this to disable the spell-checker functions.])
fi
if test "x$enable_wrapping" != xyes; then
AC_DEFINE(DISABLE_WRAPPING, 1, [Define this to disable all text wrapping.])
fi
fi
AM_CONDITIONAL(USE_COLOR, test x$color_support = xyes)

1
doc/.gitignore vendored
View File

@@ -4,4 +4,5 @@ nanorc.5.html
texinfo.tex
nano.info
nano.html
nano.pdf
sample.nanorc

View File

@@ -83,7 +83,7 @@
<h2><a name="1.3"></a>1.3. 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.4"></a>1.4. What is the current version of nano?</h2>
<blockquote><p>The current version of nano <i>should</i> be <b>2.8.6</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
<blockquote><p>The current version of nano <i>should</i> be <b>2.9.1</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
<h2><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h2>
<blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/latest/nano.1.html">here</a>.</p></blockquote>
<hr width="100%">

View File

@@ -16,8 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH NANO 1 "version 2.8.6" "July 2017"
.\" Please adjust this date whenever revising the manpage.
.TH NANO 1 "version 2.9.1" "November 2017"
.SH NAME
nano \- Nano's ANOther editor, an enhanced free Pico clone
@@ -61,7 +60,7 @@ stride.
.PP
The two lines at the bottom of the screen show some important commands;
the built-in help (\fB^G\fR) lists all the available ones.
The default key bindings can be changed via the .nanorc file -- see
The default key bindings can be changed via a \fInanorc\fR file -- see
.BR nanorc (5).
.SH OPTIONS
@@ -77,7 +76,7 @@ line.
When saving a file, back up the previous version of it, using the current
filename suffixed with a tilde (\fB~\fP).
.TP
.BR \-C\ \fIdirectory\fR ", " \-\-backupdir= \fIdirectory
.BR \-C\ \fIdirectory ", " \-\-backupdir= \fIdirectory
Make and keep not just one backup file, but make and keep a uniquely
numbered one every time a file is saved -- when backups are enabled (\fB\-B\fR).
The uniquely numbered files are stored in the specified \fIdirectory\fR.
@@ -95,11 +94,11 @@ Read a file into a new buffer by default.
Use vim-style file locking when editing files.
.TP
.BR \-H ", " \-\-historylog
Log search and replace strings to \fI~/.nano/search_history\fP, so they can be
retrieved in later sessions.
Save the last hundred search strings and replacement strings and
executed commands, so they can be easily reused in later sessions.
.TP
.BR \-I ", " \-\-ignorercfiles
Don't look at the system's \fBnanorc\fP nor at \fB~/.nanorc\fP.
Don't look at the system's \fInanorc\fR nor at the user's \fInanorc\fR.
.TP
.BR \-K ", " \-\-rebindkeypad
Interpret the numeric keypad keys so that they all work properly. You
@@ -120,7 +119,7 @@ For the 200 most recent files, log the last position of the cursor,
and place it at that position again upon reopening such a file.
(The old form of this option, \fB\-\-poslog\fR, is deprecated.)
.TP
.BR "\-Q ""\fIcharacters\fB""" ", " "\-\-quotestr=""" \fIcharacters\fR """
.BR "\-Q ""\fIcharacters\fB""" ", " "\-\-quotestr=""" \fIcharacters """
Set the quoting string for justifying. The default is
\fB"^([\ \\t]*[#:>\\|}])+"\fP if extended regular expression support is
available, or \fB">\ "\fP otherwise. Note that \fB\\t\fP stands for a
@@ -139,7 +138,7 @@ with any name beginning with 'r' (e.g. "rnano").
Use smooth scrolling: text will scroll line-by-line, instead of the
usual chunk-by-chunk behavior.
.TP
.BR \-T\ \fInumber\fR ", " \-\-tabsize= \fInumber
.BR \-T\ \fInumber ", " \-\-tabsize= \fInumber
Set the size (width) of a tab to \fInumber\fP columns. The value of
\fInumber\fP must be greater than 0. The default value is 8.
.TP
@@ -160,7 +159,7 @@ Specify which other characters (besides the normal alphanumeric ones)
should be considered as part of a word. This overrides option
\fB\-W\fR (\fB\-\-wordbounds\fR).
.TP
.BR \-Y\ \fIname\fR ", " \-\-syntax= \fIname
.BR \-Y\ \fIname ", " \-\-syntax= \fIname
Specify the name of the syntax highlighting to use from among the ones
defined in the \fInanorc\fP files.
.TP
@@ -209,7 +208,7 @@ and will write to the pipe when the user saves the "file". This way
\fBnano\fR can be used as an editor in combination with for instance
\fBgpg\fR without having to write sensitive data to disk first.
.TP
.BR \-o\ \fIdirectory\fR ", " \-\-operatingdir= \fIdirectory
.BR \-o\ \fIdirectory ", " \-\-operatingdir= \fIdirectory
Set the operating directory. This makes \fBnano\fP set up something
similar to a chroot.
.TP
@@ -218,17 +217,16 @@ Preserve the XON and XOFF sequences (^Q and ^S) so they will be caught
by the terminal.
.TP
.BR \-q ", " \-\-quiet
Do not report errors in the \fInanorc\fP files nor ask them to be
acknowledged by pressing Enter at startup.
Obsolete option. Recognized but ignored.
.TP
.BR \-r\ \fInumber\fR ", " \-\-fill= \fInumber
.BR \-r\ \fInumber ", " \-\-fill= \fInumber
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
\fB\-w\fR (\fB\-\-nowrap\fR) -- the last one given takes effect.
.TP
.BR \-s\ \fIprogram\fR ", " \-\-speller= \fIprogram
.BR \-s\ \fIprogram ", " \-\-speller= \fIprogram
Use this alternative spell checker command.
.TP
.BR \-t ", " \-\-tempfile
@@ -272,9 +270,10 @@ hard-wrapping of long lines, \fBM\-$\fR toggles soft-wrapping,
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
\fB~/.nanorc\fP (if it exists). Please see
\fBnano\fR will read two configuration files: first the system's
\fInanorc\fR (if it exists), and then the user's \fInanorc\fR (if it
exists), either \fB~/.nanorc\fR or \fI$XDG_CONFIG_HOME\fB/nano/nanorc\fR
or \fB~/.config/nano/nanorc\fR, whichever is encountered first. See
.BR nanorc (5)
for more information on the possible contents of those files.
@@ -294,12 +293,16 @@ 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)
are not yet covered by the general undo system. So after a justification
that is not immediately undone, or after any reindentation, earlier edits
that is not immediately undone, earlier edits
cannot be undone any more. The workaround is, of course, to exit without
saving.
.sp
The recording and playback of keyboard macros works correctly only on a
terminal emulator, not on a Linux console (VT), because the latter is a
deficient terminal. And it works only with recent versions of ncurses.
.sp
Please report any other bugs that you encounter via:
.br
\fIhttps://savannah.gnu.org/bugs/?group=nano\fR.

View File

@@ -8,8 +8,8 @@
@smallbook
@set EDITION 0.5
@set VERSION 2.8.6
@set UPDATED July 2017
@set VERSION 2.9.1
@set UPDATED November 2017
@dircategory Editors
@direntry
@@ -23,7 +23,7 @@
@titlepage
@title GNU @command{nano}
@subtitle a small and friendly text editor
@subtitle version 2.8.6
@subtitle version 2.9.1
@author Chris Allegretta
@page
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
@node Top
@top
This manual documents the GNU @command{nano} editor, version 2.8.6.
This manual documents the GNU @command{nano} editor, version 2.9.1.
@menu
* Introduction::
@@ -130,7 +130,7 @@ adding it with a comma. So a more complete command synopsis is:
@sp 1
@end iftex
Normally, however, you set your preferred options in a @file{.nanorc}
Normally, however, you set your preferred options in a @file{nanorc}
file (@pxref{Nanorc Files}). And when using @code{set positionlog}
(making @command{nano} remember the cursor position when you close a file),
you will rarely need to specify a line number.
@@ -183,12 +183,12 @@ Enable vim-style file locking when editing files.
@item -H
@itemx --historylog
Log search and replace strings to @file{~/.nano/search_history},
so they can be retrieved in later sessions.
Save the last hundred search strings and replacement strings and
executed commands, so they can be easily reused in later sessions.
@item -I
@itemx --ignorercfiles
Don't look at the system's nanorc file nor at the user's @file{~/.nanorc}.
Don't look at the system's nanorc file nor at the user's nanorc.
@item -K
@itemx --rebindkeypad
@@ -335,8 +335,7 @@ sent to the editor can be stopped and started.
@item -q
@itemx --quiet
Do not report errors in the nanorc file nor ask them to be acknowledged
by pressing @kbd{Enter} at startup.
Obsolete option. Recognized but ignored.
@item -r @var{number}
@itemx --fill=@var{number}
@@ -423,7 +422,7 @@ Ignored, for compatibility with Pico.
* Screen Layout::
* Search and Replace::
* Using the Mouse::
* Limitation::
* Limitations::
@end menu
@node Entering Text
@@ -553,15 +552,18 @@ Shift key during those actions.
The mouse will work in the X Window System, and on the console when gpm
is running.
@node Limitation
@section Limitation
@node Limitations
@section Limitations
Justifications (@kbd{^J}) and reindentations (@kbd{M-@{} and @kbd{M-@}})
Justifications (@kbd{^J})
are not yet covered by the general undo system. So after a justification
that is not immediately undone, or after any reindentation, earlier edits
that is not immediately undone, earlier edits
cannot be undone any more. The workaround is, of course, to exit without
saving.
The recording and playback of keyboard macros works correctly only on a
terminal emulator, not on a Linux console (VT), because the latter is a
deficient terminal. And it works only with recent versions of ncurses.
@node Built-in Help
@chapter Built-in Help
@@ -647,7 +649,8 @@ The nanorc files contain the default settings for @command{nano}. They
should be in Unix format, not in DOS or Mac format. During startup,
@command{nano} will first read the system-wide settings, from /etc/nanorc
(the exact path might be different), and then the user-specific settings,
from @file{~/.nanorc}.
either from @file{~/.nanorc} or from @file{$XDG_CONFIG_HOME/nano/nanorc}
or from @file{.config/nano/nanorc}, whichever exists first.
A nanorc file accepts a series of "set" and "unset" commands, which can
be used to configure @command{nano} on startup without using command-line
@@ -659,8 +662,7 @@ Options in nanorc files take precedence over @command{nano}'s defaults, and
command-line options override nanorc settings. Also, options that do not
take an argument are unset by default. So using the @code{unset} command
is only needed when wanting to override a setting of the system's nanorc
file in your own @file{~/.nanorc}. Options that take an argument cannot
be unset.
file in your own nanorc. Options that take an argument cannot be unset.
Quotes inside string parameters don't have to be escaped with
backslashes. The last double quote in the string will be treated as its
@@ -703,13 +705,14 @@ with @code{set backup} or @option{--backup} or @option{-B}.
The uniquely numbered files are stored in the specified directory.
@item set backwards
Do backwards searches by default.
Obsolete option. Recognized but ignored. @code{^Q} is available to
start a backward search.
@item set boldtext
Use bold instead of reverse video for the title bar, status bar, key combos,
function tags, line numbers, and selected text. This can be overridden for
the first five by setting the options @code{titlecolor}, @code{statuscolor},
@code{keycolor}, @code{functioncolor}, and @code{numbercolor}.
function tags, line numbers, and selected text. This can be overridden by
setting the options @code{titlecolor}, @code{statuscolor}, @code{keycolor},
@code{functioncolor}, @code{numbercolor}, and @code{selectedcolor}.
@item set brackets "@var{string}"
Set the characters treated as closing brackets when justifying
@@ -744,11 +747,11 @@ Valid names for foreground and background color are:
@code{white}, @code{black}, @code{blue}, @code{green},
@code{red}, @code{cyan}, @code{yellow}, and @code{magenta}.
The name of the foreground color may be prefixed with @code{bright}.
And either @var{fgcolor} or @var{,bgcolor} may be left out.
And either @var{fgcolor} or ,@var{bgcolor} may be left out.
@item set historylog
Enable the use of @file{~/.nano/search_history} for saving and reading
search/replace strings.
Save the last hundred search strings and replacement strings and
executed commands, so they can be easily reused in later sessions.
@item set justifytrim
When justifying text, trailing whitespace will automatically be removed.
@@ -827,9 +830,7 @@ Do quick status-bar blanking: status-bar messages will disappear after 1
keystroke instead of 25. Note that @option{constantshow} overrides this.
@item set quiet
When set, @command{nano} will not report errors in the nanorc file nor ask them
to be acknowledged by pressing @kbd{Enter} at startup. If this option is used, it
should be placed at the top of the file to be fully effective.
Obsolete option. Recognized but ignored.
@item set quotestr "@var{string}"
The email-quote string, used to justify email-quoted paragraphs. This
@@ -852,6 +853,10 @@ won't work properly with this option enabled.
@item set regexp
Do extended regular expression searches by default.
@item set selectedcolor @var{fgcolor},@var{bgcolor}
Use this color combination for selected text.
@xref{@code{set functioncolor}} for valid color names.
@item set showcursor
Put the cursor on the highlighted item in the file browser, to aid
braille users.
@@ -1076,15 +1081,18 @@ Exits from the program (or from the help viewer or the file browser).
Writes the current buffer to disk, asking for a name.
@item savefile
Writes the current file to disk without prompting or warning.
Writes the current file to disk without prompting.
@item insert
Inserts a file into the current buffer (at the current cursor position),
or into a new buffer when option @code{multibuffer} is set.
@item whereis
Searches for text in the current buffer --- or for filenames matching
a string in the current list in the file browser
Starts a forward search for text in the current buffer --- or for filenames
matching a string in the current list in the file browser.
@item wherewas
Starts a backward search for text in the current buffer.
@item searchagain
Repeats the last search command without prompting.
@@ -1195,10 +1203,10 @@ Moves the cursor to the beginning of the current or preceding block of text.
@item nextblock
Moves the cursor to the beginning of the next block of text.
@item prevpage
@item pageup
Goes up one screenful.
@item nextpage
@item pagedown
Goes down one screenful.
@item firstline
@@ -1239,6 +1247,13 @@ Deletes the character under the cursor.
@item backspace
Deletes the character before the cursor.
@item recordmacro
Starts the recording of keystrokes --- the keystrokes are stored
as a macro. When already recording, the recording is stopped.
@item runmacro
Replays the keystrokes of the last recorded macro.
@item undo
Undoes the last performed text action (add text, delete text, etc).
@@ -1300,7 +1315,7 @@ When about to write a file, discard the current buffer without saving.
(This function is bound by default only when option @option{--tempfile}
is in effect.)
@item tofiles
@item browser
Starts the file browser, allowing to select a file from a list.
@item gotodir
@@ -1459,14 +1474,14 @@ ask any more), or Cancel (stop with replacing).
@item Search and Replace History
When the option @option{-H} or @option{--historylog} is given (or set in
the .nanorc file), text entered as search or replace strings is stored.
the a nanorc file), text entered as search or replace strings is stored.
These strings can be accessed with the up/down arrow keys, or you can
type the first few characters and then use @kbd{Tab} to cycle through the
matching strings. A retrieved string can subsequently be edited.
@item Position History
When the option @option{-P} or @option{--positionlog} is given (or set in
the .nanorc file), @command{nano} will store the position of the cursor
a nanorc file), @command{nano} will store the position of the cursor
when you close a file, and will place the cursor in that position
again when you later reopen the file.
@@ -1587,9 +1602,8 @@ Disable support for reading the nanorc files at startup. With such
support, you can store custom settings in a system-wide and a per-user
nanorc file rather than having to pass command-line options to get
the desired behavior. @xref{Nanorc Files} for more info.
Disabling this also eliminates the @option{-I} and @option{-q} command-line
options; the first inhibits the reading of nanorcfiles, and the second
suppresses warnings about errors in those files.
Disabling this also eliminates the @option{-I} command-line option,
which inhibits the reading of nanorc files.
@item --disable-operatingdir
Disable setting the operating directory. This also eliminates the @option{-o}

View File

@@ -16,8 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH NANORC 5 "version 2.8.6" "July 2017"
.\" Please adjust this date whenever revising the manpage.
.TH NANORC 5 "version 2.9.1" "November 2017"
.SH NAME
nanorc \- GNU nano's configuration file
@@ -27,7 +26,9 @@ The \fInanorc\fP file contains the default settings for \fBnano\fP, a
small and friendly editor. The file should be in Unix format, not in
DOS or Mac format. During startup, \fBnano\fP will first read the
system-wide settings, from \fB/etc/nanorc\fP (the exact path might be
different), and then the user-specific settings, from \fB~/.nanorc\fP.
different on your system), and then the user-specific settings, either
from \fB~/.nanorc\fR or from \fI$XDG_CONFIG_HOME\fB/nano/nanorc\fR
or from \fB~/.config/nano/nanorc\fR, whichever is encountered first.
.SH OPTIONS
The configuration file accepts a series of \fBset\fP and \fBunset\fP
@@ -40,7 +41,7 @@ Options in \fInanorc\fP files take precedence over nano's defaults, and
command-line options override \fInanorc\fP settings. Also, options that
do not take an argument are unset by default. So using the \fBunset\fR
command is only needed when wanting to override a setting of the system's
\fInanorc\fR file in your own \fB~/.nanorc\fR. Options that take an
\fInanorc\fR file in your own \fInanorc\fR. Options that take an
argument cannot be unset.
.PP
Below, the \fIstring\fR parameters need to be enclosed in double quotes.
@@ -75,13 +76,14 @@ with \fBset backup\fR or \fB\-\-backup\fR or \fB\-B\fR.
The uniquely numbered files are stored in the specified \fIdirectory\fR.
.TP
.B set backwards
Do backwards searches by default.
Obsolete option. Recognized but ignored. \fB^Q\fR is available to
start a backward search.
.TP
.B set boldtext
Use bold instead of reverse video for the title bar, status bar, key combos,
function tags, line numbers, and selected text. This can be overridden for
the first five by setting the options \fBtitlecolor\fP, \fBstatuscolor\fP,
\fBkeycolor\fP, \fBfunctioncolor\fP, and \fBnumbercolor\fP.
function tags, line numbers, and selected text. This can be overridden by
setting the options \fBtitlecolor\fP, \fBstatuscolor\fP, \fBkeycolor\fP,
\fBfunctioncolor\fP, \fBnumbercolor\fP, and \fBselectedcolor\fP.
.TP
.B set brackets "\fIstring\fP"
Set the characters treated as closing brackets when justifying
@@ -113,8 +115,8 @@ in the two help lines at the bottom of the screen.
See \fBset titlecolor\fR for more details.
.TP
.B set historylog
Enable the use of \fB~/.nano/search_history\fP for saving and reading
search/replace strings.
Save the last hundred search strings and replacement strings and
executed commands, so they can be easily reused in later sessions.
.TP
.B set justifytrim
When justifying text, trailing whitespace will automatically be removed.
@@ -195,9 +197,7 @@ Do quick status-bar blanking: status-bar messages will disappear after 1
keystroke instead of 25. The option \fBconstantshow\fR overrides this.
.TP
.B set quiet
\fBnano\fP will not report errors in the \fInanorc\fP file nor ask them
to be acknowledged by pressing Enter at startup. If this is used, it
should be placed at the top of the file to be fully effective.
Obsolete option. Recognized but ignored.
.TP
.B set quotestr "\fIstring\fP"
The email-quote string, used to justify email-quoted paragraphs. This
@@ -220,6 +220,10 @@ won't work properly with this option enabled.
.B set regexp
Do extended regular expression searches by default.
.TP
.B set selectedcolor \fIfgcolor\fR,\fIbgcolor\fR
Specify the color combination to use for selected text.
See \fBset titlecolor\fR for more details.
.TP
.B set showcursor
Put the cursor on the highlighted item in the file browser, to aid
braille users.
@@ -433,15 +437,18 @@ Exits from the program (or from the help viewer or the file browser).
Writes the current buffer to disk, asking for a name.
.TP
.B savefile
Writes the current file to disk without prompting or warning.
Writes the current file to disk without prompting.
.TP
.B insert
Inserts a file into the current buffer (at the current cursor position),
or into a new buffer when option \fBmultibuffer\fR is set.
.TP
.B whereis
Searches for text in the current buffer -- or for filenames matching
a string in the current list in the file browser.
Starts a forward search for text in the current buffer -- or for filenames
matching a string in the current list in the file browser.
.TP
.B wherewas
Starts a backward search for text in the current buffer.
.TP
.B searchagain
Repeats the last search command without prompting.
@@ -555,10 +562,10 @@ Moves the cursor to the beginning of the current or preceding block of text.
.B nextblock
Moves the cursor to the beginning of the next block of text.
.TP
.B prevpage
.B pageup
Goes up one screenful.
.TP
.B nextpage
.B pagedown
Goes down one screenful.
.TP
.B firstline
@@ -599,6 +606,13 @@ Deletes the character under the cursor.
.B backspace
Deletes the character before the cursor.
.TP
.B recordmacro
Starts the recording of keystrokes -- the keystrokes are stored
as a macro. When already recording, the recording is stopped.
.TP
.B runmacro
Replays the keystrokes of the last recorded macro.
.TP
.B undo
Undoes the last performed text action (add text, delete text, etc).
.TP
@@ -660,7 +674,7 @@ When about to write a file, discard the current buffer without saving.
(This function is bound by default only when option \fB\-\-tempfile\fR
is in effect.)
.TP
.B tofiles
.B browser
Starts the file browser, allowing to select a file from a list.
.TP
.B gotodir
@@ -785,7 +799,7 @@ for \fBunbind\fR it means all menus where the specified \fIkey\fR exists.
.B /etc/nanorc
System-wide configuration file.
.TP
.B ~/.nanorc
.BR ~/.nanorc " or " \fI$XDG_CONFIG_HOME\fB/nano/nanorc " or " ~/.config/nano/nanorc
Per-user configuration file.
.SH SEE ALSO

View File

@@ -16,8 +16,7 @@
.\" Documentation License along with this program. If not, see
.\" <http://www.gnu.org/licenses/>.
.\"
.TH RNANO 1 "version 2.8.6" "July 2017"
.\" Please adjust this date whenever revising the manpage.
.TH RNANO 1 "version 2.9.1" "November 2017"
.SH NAME
rnano \- a restricted nano

View File

@@ -15,11 +15,6 @@
## its end. For example, for the "brackets" option, ""')>]}" will match
## ", ', ), >, ], and }.
## Silently ignore problems with unknown directives in the nanorc file.
## Useful when your nanorc file might be read on systems with multiple
## versions of nano installed (e.g. your home directory is on NFS).
# set quiet
## When soft line wrapping is enabled, make it wrap lines at blanks
## (tabs and spaces) instead of always at the edge of the screen.
# set atblanks
@@ -33,9 +28,6 @@
## The directory to put unique backup files in.
# set backupdir ""
## Do backwards searches by default.
# set backwards
## Use bold text instead of reverse video text.
# set boldtext
@@ -72,7 +64,7 @@
# 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
## 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.
# set locking
@@ -168,7 +160,7 @@
# set softwrap
## Use this spelling checker instead of the internal one. This option
## does not properly have a default value.
## does not have a default value.
# set speller "aspell -x -c"
## Allow nano to be suspended.
@@ -208,12 +200,14 @@
## These are examples; by default there are no colors.
# set titlecolor brightwhite,blue
# set statuscolor brightwhite,green
# set selectedcolor brightwhite,magenta
# set numbercolor cyan
# set keycolor cyan
# set functioncolor green
## In root's .nanorc you might want to use:
# set titlecolor brightwhite,red
# set statuscolor brightwhite,red
# set selectedcolor brightwhite,cyan
# set numbercolor magenta
# set keycolor brightmagenta
# set functioncolor magenta
@@ -267,11 +261,8 @@
## Key bindings.
## See nanorc(5) (section REBINDING KEYS) for more details on this.
##
## The following five functions are not bound to any key by default.
## You may wish to choose different keys than the ones suggested here.
# bind ^S savefile main
# bind M-Q findprevious main
# bind M-W findnext main
## The following two functions are not bound to any key by default.
## You may wish to choose other keys than the ones suggested here.
# bind M-B cutwordleft main
# bind M-N cutwordright main

View File

@@ -5,6 +5,7 @@ src/color.c
src/files.c
src/global.c
src/help.c
src/history.c
src/nano.c
src/prompt.c
src/rcfile.c

1268
po/bg.po

File diff suppressed because it is too large Load Diff

1346
po/ca.po

File diff suppressed because it is too large Load Diff

1329
po/cs.po

File diff suppressed because it is too large Load Diff

1336
po/da.po

File diff suppressed because it is too large Load Diff

1315
po/de.po

File diff suppressed because it is too large Load Diff

1343
po/eo.po

File diff suppressed because it is too large Load Diff

1336
po/es.po

File diff suppressed because it is too large Load Diff

1275
po/eu.po

File diff suppressed because it is too large Load Diff

1328
po/fi.po

File diff suppressed because it is too large Load Diff

1461
po/fr.po

File diff suppressed because it is too large Load Diff

1432
po/ga.po

File diff suppressed because it is too large Load Diff

1330
po/gl.po

File diff suppressed because it is too large Load Diff

1370
po/hr.po

File diff suppressed because it is too large Load Diff

1332
po/hu.po

File diff suppressed because it is too large Load Diff

1263
po/id.po

File diff suppressed because it is too large Load Diff

1308
po/it.po

File diff suppressed because it is too large Load Diff

1515
po/ja.po

File diff suppressed because it is too large Load Diff

1300
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1360
po/nb.po

File diff suppressed because it is too large Load Diff

1346
po/nl.po

File diff suppressed because it is too large Load Diff

1321
po/nn.po

File diff suppressed because it is too large Load Diff

1330
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1389
po/ro.po

File diff suppressed because it is too large Load Diff

1328
po/ru.po

File diff suppressed because it is too large Load Diff

1329
po/sl.po

File diff suppressed because it is too large Load Diff

1349
po/sr.po

File diff suppressed because it is too large Load Diff

1422
po/sv.po

File diff suppressed because it is too large Load Diff

1327
po/tr.po

File diff suppressed because it is too large Load Diff

1334
po/uk.po

File diff suppressed because it is too large Load Diff

1330
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

@@ -28,6 +28,7 @@ nano_SOURCES = browser.c \
files.c \
global.c \
help.c \
history.c \
move.c \
nano.c \
nano.h \

View File

@@ -2,7 +2,7 @@
* browser.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2015, 2016 Benno Schulenberg *
* Copyright (C) 2015-2016 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -21,11 +21,10 @@
#include "proto.h"
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#ifdef ENABLE_BROWSER
@@ -56,9 +55,6 @@ char *do_browser(char *path)
DIR *dir;
/* The directory whose contents we are showing. */
/* Don't show a cursor in the file list. */
curs_set(0);
read_directory_contents:
/* We come here when we refresh or select a new directory. */
@@ -107,20 +103,18 @@ char *do_browser(char *path)
titlebar(path);
while (TRUE) {
/* Make sure that the cursor is off. */
curs_set(0);
lastmessage = HUSH;
bottombars(MBROWSER);
/* Display (or redisplay) the file list if the list itself or
* the selected file has changed. */
if (old_selected != selected)
if (old_selected != selected || ISSET(SHOW_CURSOR))
browser_refresh();
old_selected = selected;
kbinput = get_kbinput(edit);
kbinput = get_kbinput(edit, ISSET(SHOW_CURSOR));
#ifdef ENABLE_MOUSE
if (kbinput == KEY_MOUSE) {
@@ -171,12 +165,16 @@ char *do_browser(char *path)
#else
say_there_is_no_help();
#endif
} else if (func == do_search) {
/* Search for a filename. */
} else if (func == do_search_forward) {
do_filesearch();
} else if (func == do_research) {
/* Search for another filename. */
do_fileresearch();
do_fileresearch(TRUE);
#ifndef NANO_TINY
} else if (func == do_findprevious) {
do_fileresearch(FALSE);
} else if (func == do_findnext) {
do_fileresearch(TRUE);
#endif
} else if (func == do_left) {
if (selected > 0)
selected--;
@@ -227,10 +225,7 @@ char *do_browser(char *path)
selected = filelist_len - 1;
} else if (func == goto_dir_void) {
/* Ask for the directory to go to. */
int i = do_prompt(TRUE, FALSE, MGOTODIR, NULL,
#ifndef DISABLE_HISTORIES
NULL,
#endif
int i = do_prompt(TRUE, FALSE, MGOTODIR, NULL, NULL,
/* TRANSLATORS: This is a prompt. */
browser_refresh, _("Go To Directory"));
@@ -248,12 +243,11 @@ char *do_browser(char *path)
sprintf(path, "%s%s", present_path, answer);
}
#ifndef DISABLE_OPERATINGDIR
if (check_operating_dir(path, FALSE)) {
#ifdef ENABLE_OPERATINGDIR
if (outside_of_confinement(path, FALSE)) {
/* TRANSLATORS: This refers to the confining effect of the
* option --operatingdir, not of --restricted. */
statusline(ALERT, _("Can't go outside of %s"),
full_operating_dir);
statusline(ALERT, _("Can't go outside of %s"), operating_dir);
path = mallocstrcpy(path, present_path);
continue;
}
@@ -279,13 +273,12 @@ char *do_browser(char *path)
continue;
}
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
/* Note: The selected file can be outside the operating
* directory if it's ".." or if it's a symlink to a
* directory outside the operating directory. */
if (check_operating_dir(filelist[selected], FALSE)) {
statusline(ALERT, _("Can't go outside of %s"),
full_operating_dir);
if (outside_of_confinement(filelist[selected], FALSE)) {
statusline(ALERT, _("Can't go outside of %s"), operating_dir);
continue;
}
#endif
@@ -379,10 +372,10 @@ char *do_browse_from(const char *inpath)
}
}
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
/* If the resulting path isn't in the operating directory, use
* the operating directory instead. */
if (check_operating_dir(path, FALSE))
if (outside_of_confinement(path, FALSE))
path = mallocstrcpy(path, operating_dir);
#endif
@@ -489,8 +482,11 @@ functionptrtype parse_browser_input(int *kbinput)
case 'W':
case 'w':
case '/':
return do_search;
return do_search_forward;
case 'N':
#ifndef NANO_TINY
return do_findprevious;
#endif
case 'n':
return do_research;
}
@@ -539,7 +535,7 @@ void browser_refresh(void)
/* 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);
wattron(edit, interface_color_pair[SELECTED_TEXT]);
the_row = row;
the_column = col;
}
@@ -611,7 +607,7 @@ void browser_refresh(void)
/* If this is the selected item, finish its highlighting. */
if (i == selected)
wattroff(edit, hilite_attribute);
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
free(info);
@@ -680,10 +676,7 @@ int filesearch_init(void)
buf = mallocstrcpy(NULL, "");
/* This is now one simple call. It just does a lot. */
input = do_prompt(FALSE, FALSE, MWHEREISFILE, NULL,
#ifndef DISABLE_HISTORIES
&search_history,
#endif
input = do_prompt(FALSE, FALSE, MWHEREISFILE, NULL, &search_history,
browser_refresh, "%s%s", _("Search"), buf);
/* Release buf now that we don't need it anymore. */
@@ -700,8 +693,9 @@ int filesearch_init(void)
return input;
}
/* Look for the given needle in the list of files. */
void findnextfile(const char *needle)
/* Look for the given needle in the list of files. If forwards is TRUE,
* search forward in the list; otherwise, search backward. */
void findfile(const char *needle, bool forwards)
{
size_t looking_at = selected;
/* The location in the file list of the filename we're looking at. */
@@ -721,12 +715,16 @@ void findnextfile(const char *needle)
/* Step through each filename in the list until a match is found or
* we've come back to the point where we started. */
while (TRUE) {
/* Move to the next filename in the list, or back to the first. */
if (looking_at < filelist_len - 1)
looking_at++;
else {
looking_at = 0;
statusbar(_("Search Wrapped"));
if (forwards) {
if (looking_at++ == filelist_len - 1) {
looking_at = 0;
statusbar(_("Search Wrapped"));
}
} else {
if (looking_at-- == 0) {
looking_at = filelist_len - 1;
statusbar(_("Search Wrapped"));
}
}
/* Get the bare filename, without the path. */
@@ -767,22 +765,23 @@ void do_filesearch(void)
else
last_search = mallocstrcpy(last_search, answer);
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
/* If answer is not empty, add the string to the search history list. */
if (*answer != '\0')
update_history(&search_history, answer);
#endif
findnextfile(answer);
findfile(answer, TRUE);
}
/* Search again for the last given filename, without prompting. */
void do_fileresearch(void)
/* Search again without prompting for the last given search string,
* either forwards or backwards. */
void do_fileresearch(bool forwards)
{
if (*last_search == '\0')
statusbar(_("No current search pattern"));
else
findnextfile(last_search);
findfile(last_search, forwards);
}
/* Select the first file in the list. */

View File

@@ -2,7 +2,7 @@
* chars.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2016 Benno Schulenberg *
* Copyright (C) 2016-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -21,8 +21,8 @@
#include "proto.h"
#include <string.h>
#include <ctype.h>
#include <string.h>
#ifdef ENABLE_UTF8
#include <wchar.h>
@@ -397,7 +397,7 @@ size_t move_mbleft(const char *buf, size_t pos)
}
/* Move forward again until we reach the original character,
* so we know the length of its preceding the character. */
* so we know the length of its preceding character. */
while (before < pos) {
char_len = parse_mbchar(buf + before, NULL, NULL);
before += char_len;
@@ -579,7 +579,7 @@ size_t mbstrnlen(const char *s, size_t maxlen)
return strnlen(s, maxlen);
}
#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
/* This function is equivalent to strchr() for multibyte strings. */
char *mbstrchr(const char *s, const char *c)
{
@@ -620,7 +620,7 @@ char *mbstrchr(const char *s, const char *c)
#endif
return (char *) strchr(s, *c);
}
#endif /* !NANO_TINY || !DISABLE_JUSTIFY */
#endif /* !NANO_TINY || ENABLE_JUSTIFY */
#ifndef NANO_TINY
/* This function is equivalent to strpbrk() for multibyte strings. */
@@ -686,7 +686,7 @@ char *mbrevstrpbrk(const char *head, const char *accept, const char *pointer)
}
#endif /* !NANO_TINY */
#if defined(ENABLE_NANORC) && (!defined(NANO_TINY) || !defined(DISABLE_JUSTIFY))
#if defined(ENABLE_NANORC) && (!defined(NANO_TINY) || defined(ENABLE_JUSTIFY))
/* Return TRUE if the string s contains one or more blank characters,
* and FALSE otherwise. */
bool has_blank_chars(const char *s)
@@ -719,7 +719,7 @@ bool has_blank_mbchars(const char *s)
#endif
return has_blank_chars(s);
}
#endif /* ENABLE_NANORC && (!NANO_TINY || !DISABLE_JUSTIFY) */
#endif /* ENABLE_NANORC && (!NANO_TINY || ENABLE_JUSTIFY) */
#ifdef ENABLE_UTF8
/* Return TRUE if wc is valid Unicode, and FALSE otherwise. */

View File

@@ -2,7 +2,7 @@
* color.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2014, 2015, 2016, 2017 Benno Schulenberg *
* Copyright (C) 2014-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -21,16 +21,23 @@
#include "proto.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#ifdef HAVE_MAGIC_H
#include <magic.h>
#endif
#include <string.h>
#include <unistd.h>
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
/* For early versions of ncurses-6.0, use an additional A_PROTECT attribute
* for all colors, in order to work around an ncurses miscoloring bug. */
#if defined(NCURSES_VERSION_MAJOR) && (NCURSES_VERSION_MAJOR == 6) && \
(NCURSES_VERSION_MINOR == 0) && (NCURSES_VERSION_PATCH < 20151017)
#define A_BANDAID A_PROTECT
#else
#define A_BANDAID A_NORMAL
#endif
/* Initialize the colors for nano's interface, and assign pair numbers
* for the colors in each syntax. */
@@ -61,8 +68,8 @@ void set_colorpairs(void)
if (background == -1 && !using_defaults)
background = COLOR_BLACK;
init_pair(i + 1, foreground, background);
interface_color_pair[i] =
COLOR_PAIR(i + 1) | (bright ? A_BOLD : A_NORMAL);
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BANDAID |
(bright ? A_BOLD : A_NORMAL);
} else {
if (i != FUNCTION_TAG)
interface_color_pair[i] = hilite_attribute;
@@ -93,7 +100,7 @@ void set_colorpairs(void)
else
ink->pairnum = new_number++;
ink->attributes = COLOR_PAIR(ink->pairnum) |
ink->attributes = COLOR_PAIR(ink->pairnum) | A_BANDAID |
(ink->bright ? A_BOLD : A_NORMAL);
}
}
@@ -127,9 +134,6 @@ void color_init(void)
background = COLOR_BLACK;
init_pair(ink->pairnum, foreground, background);
#ifdef DEBUG
fprintf(stderr, "init_pair(): fg = %hd, bg = %hd\n", foreground, background);
#endif
}
have_palette = TRUE;
@@ -177,13 +181,13 @@ void color_update(void)
break;
}
if (sint == NULL)
if (sint == NULL && !inhelp)
statusline(ALERT, _("Unknown syntax name: %s"), syntaxstr);
}
/* If no syntax-override string was specified, or it didn't match,
* try finding a syntax based on the filename (extension). */
if (sint == NULL) {
if (sint == NULL && !inhelp) {
char *reserved = charalloc(PATH_MAX + 1);
char *currentdir = getcwd(reserved, PATH_MAX + 1);
char *joinednames = charalloc(PATH_MAX + 1);
@@ -212,10 +216,7 @@ void color_update(void)
}
/* If the filename didn't match anything, try the first line. */
if (sint == NULL) {
#ifdef DEBUG
fprintf(stderr, "No result from file extension, trying headerline...\n");
#endif
if (sint == NULL && !inhelp) {
for (sint = syntaxes; sint != NULL; sint = sint->next) {
if (found_in_list(sint->headers, openfile->fileage->data))
break;
@@ -224,13 +225,11 @@ void color_update(void)
#ifdef HAVE_LIBMAGIC
/* If we still don't have an answer, try using magic. */
if (sint == NULL) {
if (sint == NULL && !inhelp) {
struct stat fileinfo;
magic_t cookie = NULL;
const char *magicstring = NULL;
#ifdef DEBUG
fprintf(stderr, "No result from headerline either, trying libmagic...\n");
#endif
if (stat(openfile->filename, &fileinfo) == 0) {
/* Open the magic database and get a diagnosis of the file. */
cookie = magic_open(MAGIC_SYMLINK |
@@ -245,9 +244,6 @@ void color_update(void)
if (magicstring == NULL)
statusline(ALERT, _("magic_file(%s) failed: %s"),
openfile->filename, magic_error(cookie));
#ifdef DEBUG
fprintf(stderr, "Returned magic string is: %s\n", magicstring);
#endif
}
}
@@ -265,7 +261,7 @@ void color_update(void)
#endif /* HAVE_LIBMAGIC */
/* If nothing at all matched, see if there is a default syntax. */
if (sint == NULL) {
if (sint == NULL && !inhelp) {
for (sint = syntaxes; sint != NULL; sint = sint->next) {
if (strcmp(sint->name, "default") == 0)
break;
@@ -437,4 +433,4 @@ void precalc_multicolorinfo(void)
}
}
#endif /* !DISABLE_COLOR */
#endif /* ENABLE_COLOR */

View File

@@ -23,7 +23,6 @@
#include "proto.h"
#include <string.h>
#include <stdio.h>
static bool keep_cutbuffer = FALSE;
/* Should we keep the contents of the cutbuffer? */
@@ -130,9 +129,6 @@ void do_cut_text(bool copy_text, bool cut_till_eof)
if (!keep_cutbuffer) {
free_filestruct(cutbuffer);
cutbuffer = NULL;
#ifdef DEBUG
fprintf(stderr, "Blew away cutbuffer =)\n");
#endif
/* Indicate that future cuts should add to the cutbuffer. */
keep_cutbuffer = TRUE;
}
@@ -151,10 +147,10 @@ void do_cut_text(bool copy_text, bool cut_till_eof)
if (cut_till_eof) {
/* Move all text up to the end of the file into the cutbuffer. */
cut_to_eof();
} else if (openfile->mark_set) {
} else if (openfile->mark) {
/* Move the marked text to the cutbuffer, and turn the mark off. */
cut_marked(&right_side_up);
openfile->mark_set = FALSE;
openfile->mark = NULL;
} else if (ISSET(CUT_FROM_CURSOR))
/* Move all text up to the end of the line into the cutbuffer. */
cut_to_eol();
@@ -192,7 +188,7 @@ void do_cut_text(bool copy_text, bool cut_till_eof)
refresh_needed = TRUE;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
check_the_multis(openfile->current);
#endif
@@ -220,7 +216,7 @@ void do_cut_text_void(void)
void do_copy_text(void)
{
static struct filestruct *next_contiguous_line = NULL;
bool mark_set = openfile->mark_set;
bool mark_is_set = (openfile->mark != NULL);
/* Remember the current viewport and cursor position. */
ssize_t is_edittop_lineno = openfile->edittop->lineno;
@@ -228,16 +224,16 @@ void do_copy_text(void)
ssize_t is_current_lineno = openfile->current->lineno;
size_t is_current_x = openfile->current_x;
if (mark_set || openfile->current != next_contiguous_line)
if (mark_is_set || openfile->current != next_contiguous_line)
cutbuffer_reset();
do_cut_text(TRUE, FALSE);
/* If the mark was set, blow away the cutbuffer on the next copy. */
next_contiguous_line = (mark_set ? NULL : openfile->current);
next_contiguous_line = (mark_is_set ? NULL : openfile->current);
if (mark_set) {
/* Restore the viewport and cursor position. */
/* If the mark was set, restore the viewport and cursor position. */
if (mark_is_set) {
openfile->edittop = fsfromline(is_edittop_lineno);
openfile->firstcolumn = is_firstcolumn;
openfile->current = fsfromline(is_current_lineno);
@@ -291,12 +287,9 @@ void do_uncut_text(void)
/* Mark the file as modified. */
set_modified();
/* Update current_y to account for the inserted lines. */
place_the_cursor(TRUE);
refresh_needed = TRUE;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
check_the_multis(openfile->current);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -22,10 +22,8 @@
#include "proto.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#ifdef ENABLE_HELP
@@ -105,7 +103,7 @@ void do_help(void)
int was_margin = margin;
#endif
ssize_t was_tabsize = tabsize;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
char *was_syntax = syntaxstr;
#endif
char *saved_answer = (answer != NULL) ? strdup(answer) : NULL;
@@ -151,7 +149,7 @@ void do_help(void)
margin = 0;
#endif
tabsize = 8;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
syntaxstr = "nanohelp";
#endif
curs_set(0);
@@ -160,6 +158,7 @@ void do_help(void)
help_init();
inhelp = TRUE;
location = 0;
didfind = 0;
bottombars(MHELP);
wnoutrefresh(bottomwin);
@@ -183,9 +182,10 @@ void do_help(void)
while (TRUE) {
lastmessage = HUSH;
focusing = TRUE;
didfind = 0;
kbinput = get_kbinput(edit);
/* Show the cursor when we searched and found something. */
kbinput = get_kbinput(edit, didfind == 1);
didfind = 0;
func = parse_help_input(&kbinput);
@@ -205,13 +205,16 @@ void do_help(void)
do_first_line();
} else if (func == do_last_line) {
do_last_line();
} else if (func == do_search) {
} else if (func == do_search_forward) {
do_search();
bottombars(MHELP);
} else if (func == do_research) {
do_research();
currmenu = MHELP;
#ifndef NANO_TINY
} else if (func == do_findprevious) {
do_findprevious();
} else if (func == do_findnext) {
do_findnext();
} else if (kbinput == KEY_WINCH) {
; /* Nothing to do. */
#endif
@@ -223,16 +226,12 @@ void do_help(void)
} else if (func == do_exit) {
/* Exit from the help viewer. */
close_buffer();
curs_set(0);
break;
} else
unbound_key(kbinput);
/* If we searched and found something, let the cursor show it. */
if (didfind == 1)
curs_set(1);
else
curs_set(0);
currmenu = MHELP;
edit_refresh();
location = 0;
@@ -252,16 +251,14 @@ void do_help(void)
margin = was_margin;
#endif
tabsize = was_tabsize;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
syntaxstr = was_syntax;
#endif
/* Switch back to the buffer we were invoked from. */
switch_to_prev_buffer_void();
switch_to_prev_buffer();
if (ISSET(NO_HELP)) {
blank_bottombars();
wnoutrefresh(bottomwin);
currmenu = oldmenu;
window_init();
} else
@@ -392,7 +389,7 @@ void help_init(void)
htx[2] = NULL;
}
#endif /* ENABLE_BROWSER */
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
else if (currmenu == MSPELL) {
htx[0] = N_("Spell Check Help Text\n\n "
"The spell checker checks the spelling of all text in "
@@ -406,7 +403,7 @@ void help_init(void)
htx[1] = NULL;
htx[2] = NULL;
}
#endif /* !DISABLE_SPELLER */
#endif /* ENABLE_SPELLER */
#ifndef NANO_TINY
else if (currmenu == MEXTCMD) {
htx[0] = N_("Execute Command Help Text\n\n "
@@ -514,7 +511,7 @@ void help_init(void)
if (scsfound == 1) {
sprintf(ptr, "%s ", s->keystr);
/* Unicode arrows take three bytes instead of one. */
if (s->keystr[0] == '\xE2' || s->keystr[1] == '\xE2')
if (strstr(s->keystr, "\xE2") != NULL)
ptr += 8;
else
ptr += 6;
@@ -578,8 +575,11 @@ functionptrtype parse_help_input(int *kbinput)
case 'W':
case 'w':
case '/':
return do_search;
return do_search_forward;
case 'N':
#ifndef NANO_TINY
return do_findprevious;
#endif
case 'n':
return do_research;
case 'E':

616
src/history.c Normal file
View File

@@ -0,0 +1,616 @@
/**************************************************************************
* history.c -- This file is part of GNU nano. *
* *
* Copyright (C) 2003-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2016-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation, either version 3 of the License, *
* or (at your option) any later version. *
* *
* GNU nano is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see http://www.gnu.org/licenses/. *
* *
**************************************************************************/
#include "proto.h"
#include <errno.h>
#include <string.h>
#ifdef ENABLE_HISTORIES
#ifndef SEARCH_HISTORY
#define SEARCH_HISTORY "search_history"
#endif
#ifndef POSITION_HISTORY
#define POSITION_HISTORY "filepos_history"
#endif
static bool history_changed = FALSE;
/* Whether any of the history lists has changed. */
static struct stat stat_of_positions_file;
/* The last-obtained stat information of the positions file. */
static char *poshistname = NULL;
/* The name of the positions-history file. */
/* Initialize the lists of historical search and replace strings
* and the list of historical executed commands. */
void history_init(void)
{
search_history = make_new_node(NULL);
search_history->data = mallocstrcpy(NULL, "");
searchtop = search_history;
searchbot = search_history;
replace_history = make_new_node(NULL);
replace_history->data = mallocstrcpy(NULL, "");
replacetop = replace_history;
replacebot = replace_history;
execute_history = make_new_node(NULL);
execute_history->data = mallocstrcpy(NULL, "");
executetop = execute_history;
executebot = execute_history;
}
/* Set the current position in the given history list to the bottom. */
void history_reset(const filestruct *list)
{
if (list == search_history)
search_history = searchbot;
else if (list == replace_history)
replace_history = replacebot;
else if (list == execute_history)
execute_history = executebot;
}
/* Return from the history list that starts at start and ends at end
* the first node that contains the first len characters of the given
* text, or NULL if there is no such node. */
filestruct *find_history(const filestruct *start, const filestruct *end,
const char *text, size_t len)
{
const filestruct *item;
for (item = start; item != end->prev && item != NULL; item = item->prev) {
if (strncmp(item->data, text, len) == 0)
return (filestruct *)item;
}
return NULL;
}
/* Update a history list (the one in which item is the current position)
* with a fresh string text. That is: add text, or move it to the end. */
void update_history(filestruct **item, const char *text)
{
filestruct **htop = NULL, **hbot = NULL, *thesame;
if (*item == search_history) {
htop = &searchtop;
hbot = &searchbot;
} else if (*item == replace_history) {
htop = &replacetop;
hbot = &replacebot;
} else if (*item == execute_history) {
htop = &executetop;
hbot = &executebot;
}
/* See if the string is already in the history. */
thesame = find_history(*hbot, *htop, text, HIGHEST_POSITIVE);
/* If an identical string was found, delete that item. */
if (thesame != NULL) {
filestruct *after = thesame->next;
/* If the string is at the head of the list, move the head. */
if (thesame == *htop)
*htop = after;
unlink_node(thesame);
renumber(after);
}
/* If the history is full, delete the oldest item (the one at the
* head of the list), to make room for a new item at the end. */
if ((*hbot)->lineno == MAX_SEARCH_HISTORY + 1) {
filestruct *oldest = *htop;
*htop = (*htop)->next;
unlink_node(oldest);
renumber(*htop);
}
/* Store the fresh string in the last item, then create a new item. */
(*hbot)->data = mallocstrcpy((*hbot)->data, text);
splice_node(*hbot, make_new_node(*hbot));
*hbot = (*hbot)->next;
(*hbot)->data = mallocstrcpy(NULL, "");
/* Indicate that the history needs to be saved on exit. */
history_changed = TRUE;
/* Set the current position in the list to the bottom. */
*item = *hbot;
}
/* Move h to the string in the history list just before it, and return
* that string. If there isn't one, don't move h and return NULL. */
char *get_history_older(filestruct **h)
{
if ((*h)->prev == NULL)
return NULL;
*h = (*h)->prev;
return (*h)->data;
}
/* Move h to the string in the history list just after it, and return
* that string. If there isn't one, don't move h and return NULL. */
char *get_history_newer(filestruct **h)
{
if ((*h)->next == NULL)
return NULL;
*h = (*h)->next;
return (*h)->data;
}
/* More placeholders. */
void get_history_newer_void(void)
{
;
}
void get_history_older_void(void)
{
;
}
#ifdef ENABLE_TABCOMP
/* Move h to the next string that's a tab completion of the string s,
* looking at only the first len characters of s, and return that
* string. If there isn't one, or if len is 0, don't move h and return
* s. */
char *get_history_completion(filestruct **h, char *s, size_t len)
{
if (len > 0) {
filestruct *htop = NULL, *hbot = NULL, *p;
if (*h == search_history) {
htop = searchtop;
hbot = searchbot;
} else if (*h == replace_history) {
htop = replacetop;
hbot = replacebot;
} else if (*h == execute_history) {
htop = executetop;
hbot = executebot;
}
/* Search the history list from the current position to the top
* for a match of len characters. Skip over an exact match. */
p = find_history((*h)->prev, htop, s, len);
while (p != NULL && strcmp(p->data, s) == 0)
p = find_history(p->prev, htop, s, len);
if (p != NULL) {
*h = p;
return mallocstrcpy(s, (*h)->data);
}
/* Search the history list from the bottom to the current position
* for a match of len characters. Skip over an exact match. */
p = find_history(hbot, *h, s, len);
while (p != NULL && strcmp(p->data, s) == 0)
p = find_history(p->prev, *h, s, len);
if (p != NULL) {
*h = p;
return mallocstrcpy(s, (*h)->data);
}
}
/* If we're here, we didn't find a match, we didn't find an inexact
* match, or len is 0. Return s. */
return (char *)s;
}
#endif /* ENSABLE_TABCOMP */
void history_error(const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
vfprintf(stderr, _(msg), ap);
va_end(ap);
fprintf(stderr, _("\nPress Enter to continue\n"));
while (getchar() != '\n')
;
}
/* Check whether we have or could make a directory for history files. */
bool have_statedir(void)
{
struct stat dirstat;
const char *xdgdatadir;
get_homedir();
if (homedir != NULL) {
statedir = concatenate(homedir, "/.nano/");
if (stat(statedir, &dirstat) == 0 && S_ISDIR(dirstat.st_mode)) {
poshistname = concatenate(statedir, POSITION_HISTORY);
return TRUE;
}
}
free(statedir);
xdgdatadir = getenv("XDG_DATA_HOME");
if (homedir == NULL && xdgdatadir == NULL)
return FALSE;
if (xdgdatadir != NULL)
statedir = concatenate(xdgdatadir, "/nano/");
else
statedir = concatenate(homedir, "/.local/share/nano/");
if (stat(statedir, &dirstat) == -1) {
if (xdgdatadir == NULL) {
char *statepath = concatenate(homedir, "/.local");
mkdir(statepath, S_IRWXU | S_IRWXG | S_IRWXO);
free(statepath);
statepath = concatenate(homedir, "/.local/share");
mkdir(statepath, S_IRWXU);
free(statepath);
}
if (mkdir(statedir, S_IRWXU) == -1) {
history_error(N_("Unable to create directory %s: %s\n"
"It is required for saving/loading "
"search history or cursor positions.\n"),
statedir, strerror(errno));
return FALSE;
}
} else if (!S_ISDIR(dirstat.st_mode)) {
history_error(N_("Path %s is not a directory and needs to be.\n"
"Nano will be unable to load or save "
"search history or cursor positions.\n"),
statedir);
return FALSE;
}
poshistname = concatenate(statedir, POSITION_HISTORY);
return TRUE;
}
/* Load the histories for Search and Replace and Execute Command. */
void load_history(void)
{
char *histname = concatenate(statedir, SEARCH_HISTORY);
FILE *hisfile = fopen(histname, "rb");
if (hisfile == NULL) {
if (errno != ENOENT) {
/* When reading failed, don't save history when we quit. */
UNSET(HISTORYLOG);
history_error(N_("Error reading %s: %s"), histname,
strerror(errno));
}
} else {
/* Load the three history lists -- first search, then replace,
* then execute -- from oldest entry to newest. Between two
* lists there is an empty line. */
filestruct **history = &search_history;
char *line = NULL;
size_t buf_len = 0;
ssize_t read;
while ((read = getline(&line, &buf_len, hisfile)) > 0) {
line[--read] = '\0';
if (read > 0) {
/* Encode any embedded NUL as 0x0A. */
unsunder(line, read);
update_history(history, line);
} else if (history == &search_history)
history = &replace_history;
else
history = &execute_history;
}
fclose(hisfile);
free(line);
}
/* After reading them in, set the status of the lists to "unchanged". */
history_changed = FALSE;
free(histname);
}
/* Write the lines of a history list, starting at head, from oldest to newest,
* to the given file. Return TRUE if writing succeeded, and FALSE otherwise. */
bool write_list(const filestruct *head, FILE *hisfile)
{
const filestruct *item;
for (item = head; item != NULL; item = item->next) {
size_t length = strlen(item->data);
/* Decode 0x0A bytes as embedded NULs. */
sunder(item->data);
if (fwrite(item->data, sizeof(char), length, hisfile) < length)
return FALSE;
if (putc('\n', hisfile) == EOF)
return FALSE;
}
return TRUE;
}
/* Save the histories for Search and Replace and Execute Command. */
void save_history(void)
{
char *histname;
FILE *hisfile;
/* If the histories are unchanged, don't bother saving them. */
if (!history_changed)
return;
histname = concatenate(statedir, SEARCH_HISTORY);
hisfile = fopen(histname, "wb");
if (hisfile == NULL)
fprintf(stderr, _("Error writing %s: %s\n"), histname,
strerror(errno));
else {
/* Don't allow others to read or write the history file. */
chmod(histname, S_IRUSR | S_IWUSR);
if (!write_list(searchtop, hisfile) ||
!write_list(replacetop, hisfile) ||
!write_list(executetop, hisfile))
fprintf(stderr, _("Error writing %s: %s\n"), histname,
strerror(errno));
fclose(hisfile);
}
free(histname);
}
/* Load the recorded cursor positions for files that were edited. */
void load_poshistory(void)
{
FILE *hisfile = fopen(poshistname, "rb");
if (hisfile == NULL) {
if (errno != ENOENT) {
/* When reading failed, don't save history when we quit. */
UNSET(POS_HISTORY);
history_error(N_("Error reading %s: %s"), poshistname, strerror(errno));
}
} else {
char *line = NULL, *lineptr, *xptr;
size_t buf_len = 0;
ssize_t read, count = 0;
poshiststruct *record_ptr = NULL, *newrecord;
/* Read and parse each line, and store the extracted data. */
while ((read = getline(&line, &buf_len, hisfile)) > 5) {
/* Decode nulls as embedded newlines. */
unsunder(line, read);
/* Find where the x index and line number are in the line. */
xptr = revstrstr(line, " ", line + read - 3);
if (xptr == NULL)
continue;
lineptr = revstrstr(line, " ", xptr - 2);
if (lineptr == NULL)
continue;
/* Now separate the three elements of the line. */
*(xptr++) = '\0';
*(lineptr++) = '\0';
/* Create a new position record. */
newrecord = (poshiststruct *)nmalloc(sizeof(poshiststruct));
newrecord->filename = mallocstrcpy(NULL, line);
newrecord->lineno = atoi(lineptr);
newrecord->xno = atoi(xptr);
newrecord->next = NULL;
/* Add the record to the list. */
if (position_history == NULL)
position_history = newrecord;
else
record_ptr->next = newrecord;
record_ptr = newrecord;
/* Impose a limit, so the file will not grow indefinitely. */
if (++count > 200) {
poshiststruct *drop_record = position_history;
position_history = position_history->next;
free(drop_record->filename);
free(drop_record);
}
}
fclose(hisfile);
free(line);
stat(poshistname, &stat_of_positions_file);
}
}
/* Save the recorded cursor positions for files that were edited. */
void save_poshistory(void)
{
poshiststruct *posptr;
FILE *hisfile = fopen(poshistname, "wb");
if (hisfile == NULL)
fprintf(stderr, _("Error writing %s: %s\n"), poshistname, strerror(errno));
else {
/* Don't allow others to read or write the history file. */
chmod(poshistname, S_IRUSR | S_IWUSR);
for (posptr = position_history; posptr != NULL; posptr = posptr->next) {
char *path_and_place;
size_t length;
/* Assume 20 decimal positions each for line and column number,
* plus two spaces, plus the line feed, plus the null byte. */
path_and_place = charalloc(strlen(posptr->filename) + 44);
sprintf(path_and_place, "%s %zd %zd\n",
posptr->filename, posptr->lineno, posptr->xno);
length = strlen(path_and_place);
/* Encode newlines in filenames as nulls. */
sunder(path_and_place);
/* Restore the terminating newline. */
path_and_place[length - 1] = '\n';
if (fwrite(path_and_place, sizeof(char), length, hisfile) < length)
fprintf(stderr, _("Error writing %s: %s\n"),
poshistname, strerror(errno));
free(path_and_place);
}
fclose(hisfile);
stat(poshistname, &stat_of_positions_file);
}
}
/* Reload the position history file if it has been modified since last load. */
void reload_positions_if_needed(void)
{
struct stat newstat;
stat(poshistname, &newstat);
if (newstat.st_mtime != stat_of_positions_file.st_mtime) {
poshiststruct *ptr, *nextone;
for (ptr = position_history; ptr != NULL; ptr = nextone) {
nextone = ptr->next;
free(ptr->filename);
free(ptr);
}
position_history = NULL;
load_poshistory();
}
}
/* Update the recorded last file positions, given a filename, a line
* and a column. If no entry is found, add a new one at the end. */
void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
{
poshiststruct *posptr, *theone, *posprev = NULL;
char *fullpath = get_full_path(filename);
if (fullpath == NULL || fullpath[strlen(fullpath) - 1] == '/' || inhelp) {
free(fullpath);
return;
}
reload_positions_if_needed();
/* Look for a matching filename in the list. */
for (posptr = position_history; posptr != NULL; posptr = posptr->next) {
if (!strcmp(posptr->filename, fullpath))
break;
posprev = posptr;
}
/* Don't record files that have the default cursor position. */
if (lineno == 1 && xpos == 1) {
if (posptr != NULL) {
if (posprev == NULL)
position_history = posptr->next;
else
posprev->next = posptr->next;
free(posptr->filename);
free(posptr);
save_poshistory();
}
free(fullpath);
return;
}
theone = posptr;
/* If we didn't find it, make a new node; otherwise, if we're
* not at the end, move the matching one to the end. */
if (theone == NULL) {
theone = (poshiststruct *)nmalloc(sizeof(poshiststruct));
theone->filename = mallocstrcpy(NULL, fullpath);
if (position_history == NULL)
position_history = theone;
else
posprev->next = theone;
} else if (posptr->next != NULL) {
if (posprev == NULL)
position_history = posptr->next;
else
posprev->next = posptr->next;
while (posptr->next != NULL)
posptr = posptr->next;
posptr->next = theone;
}
/* Store the last cursor position. */
theone->lineno = lineno;
theone->xno = xpos;
theone->next = NULL;
free(fullpath);
save_poshistory();
}
/* Check whether the given file matches an existing entry in the recorded
* last file positions. If not, return FALSE. If yes, return TRUE and
* set line and column to the retrieved values. */
bool has_old_position(const char *file, ssize_t *line, ssize_t *column)
{
poshiststruct *posptr = position_history;
char *fullpath = get_full_path(file);
if (fullpath == NULL)
return FALSE;
reload_positions_if_needed();
while (posptr != NULL && strcmp(posptr->filename, fullpath) != 0)
posptr = posptr->next;
free(fullpath);
if (posptr == NULL)
return FALSE;
*line = posptr->lineno;
*column = posptr->xno;
return TRUE;
}
#endif /* ENABLE_HISTORIES */

View File

@@ -2,7 +2,7 @@
* move.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* Copyright (C) 2014-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -22,7 +22,6 @@
#include "proto.h"
#include <string.h>
#include <ctype.h>
/* Move to the first line of the file. */
void do_first_line(void)
@@ -53,8 +52,10 @@ void get_edge_and_target(size_t *leftedge, size_t *target_column)
{
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
size_t shim = editwincols * (1 + (tabsize / editwincols));
*leftedge = leftedge_for(xplustabs(), openfile->current);
*target_column = openfile->placewewant - *leftedge;
*target_column = (openfile->placewewant + shim - *leftedge) % editwincols;
} else
#endif
{
@@ -63,6 +64,51 @@ void get_edge_and_target(size_t *leftedge, size_t *target_column)
}
}
/* Return the index in line->data that corresponds to the given column on the
* chunk that starts at the given leftedge. If the target column has landed
* on a tab, prevent the cursor from falling back a row when moving forward,
* or from skipping a row when moving backward, by incrementing the index. */
size_t proper_x(filestruct *line, size_t *leftedge, bool forward,
size_t column, bool *shifted)
{
size_t index = actual_x(line->data, column);
#ifndef NANO_TINY
if (ISSET(SOFTWRAP) && line->data[index] == '\t' &&
((forward && strnlenpt(line->data, index) < *leftedge) ||
(!forward && column / tabsize == (*leftedge - 1) / tabsize &&
column / tabsize < (*leftedge + editwincols - 1) / tabsize))) {
index++;
if (shifted != NULL)
*shifted = TRUE;
}
if (ISSET(SOFTWRAP))
*leftedge = leftedge_for(strnlenpt(line->data, index), line);
#endif
return index;
}
/* Adjust the values for current_x and placewewant in case we have landed in
* the middle of a tab that crosses a row boundary. */
void set_proper_index_and_pww(size_t *leftedge, size_t target, bool forward)
{
bool shifted = FALSE;
size_t was_edge = *leftedge;
openfile->current_x = proper_x(openfile->current, leftedge, forward,
actual_last_column(*leftedge, target), &shifted);
/* If the index was incremented, try going to the target column. */
if (shifted || *leftedge < was_edge)
openfile->current_x = proper_x(openfile->current, leftedge, forward,
actual_last_column(*leftedge, target), &shifted);
openfile->placewewant = *leftedge + target;
}
/* Move up nearly one screenful. */
void do_page_up(void)
{
@@ -73,13 +119,11 @@ void do_page_up(void)
* beginning of the top line of the edit window, as Pico does. */
if (!ISSET(SMOOTH_SCROLL)) {
openfile->current = openfile->edittop;
openfile->placewewant = openfile->firstcolumn;
openfile->current_x = actual_x(openfile->current->data,
openfile->firstcolumn);
leftedge = openfile->firstcolumn;
openfile->current_y = 0;
}
get_edge_and_target(&leftedge, &target_column);
target_column = 0;
} else
get_edge_and_target(&leftedge, &target_column);
/* Move up the required number of lines or chunks. If we can't, we're
* at the top of the file, so put the cursor there and get out. */
@@ -88,9 +132,7 @@ void do_page_up(void)
return;
}
openfile->placewewant = leftedge + target_column;
openfile->current_x = actual_x(openfile->current->data,
actual_last_column(leftedge, target_column));
set_proper_index_and_pww(&leftedge, target_column, FALSE);
/* Move the viewport so that the cursor stays immobile, if possible. */
adjust_viewport(STATIONARY);
@@ -107,13 +149,11 @@ void do_page_down(void)
* beginning of the top line of the edit window, as Pico does. */
if (!ISSET(SMOOTH_SCROLL)) {
openfile->current = openfile->edittop;
openfile->placewewant = openfile->firstcolumn;
openfile->current_x = actual_x(openfile->current->data,
openfile->firstcolumn);
leftedge = openfile->firstcolumn;
openfile->current_y = 0;
}
get_edge_and_target(&leftedge, &target_column);
target_column = 0;
} else
get_edge_and_target(&leftedge, &target_column);
/* Move down the required number of lines or chunks. If we can't, we're
* at the bottom of the file, so put the cursor there and get out. */
@@ -122,38 +162,30 @@ void do_page_down(void)
return;
}
openfile->placewewant = leftedge + target_column;
openfile->current_x = actual_x(openfile->current->data,
actual_last_column(leftedge, target_column));
set_proper_index_and_pww(&leftedge, target_column, TRUE);
/* Move the viewport so that the cursor stays immobile, if possible. */
adjust_viewport(STATIONARY);
refresh_needed = TRUE;
}
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
/* Move to the beginning of the last beginning-of-paragraph line before the
* current line. If update_screen is TRUE, update the screen afterwards. */
void do_para_begin(bool update_screen)
{
filestruct *was_current = openfile->current;
if (openfile->current != openfile->fileage) {
do
openfile->current = openfile->current->prev;
while (!begpar(openfile->current));
}
if (openfile->current != openfile->fileage)
openfile->current = openfile->current->prev;
while (!begpar(openfile->current))
openfile->current = openfile->current->prev;
openfile->current_x = 0;
if (update_screen)
edit_redraw(was_current);
}
/* Move up to first start of a paragraph before the current line. */
void do_para_begin_void(void)
{
do_para_begin(TRUE);
edit_redraw(was_current, CENTERING);
}
/* Move down to the beginning of the last line of the current paragraph.
@@ -183,7 +215,13 @@ void do_para_end(bool update_screen)
openfile->current_x = strlen(openfile->current->data);
if (update_screen)
edit_redraw(was_current);
edit_redraw(was_current, CENTERING);
}
/* Move up to first start of a paragraph before the current line. */
void do_para_begin_void(void)
{
do_para_begin(TRUE);
}
/* Move down to just after the first end of a paragraph. */
@@ -191,9 +229,9 @@ void do_para_end_void(void)
{
do_para_end(TRUE);
}
#endif /* !DISABLE_JUSTIFY */
#endif /* ENABLE_JUSTIFY */
/* Move to the preceding block of text in the file. */
/* Move to the preceding block of text. */
void do_prev_block(void)
{
filestruct *was_current = openfile->current;
@@ -212,10 +250,10 @@ void do_prev_block(void)
openfile->current = openfile->current->next;
openfile->current_x = 0;
edit_redraw(was_current);
edit_redraw(was_current, CENTERING);
}
/* Move to the next block of text in the file. */
/* Move to the next block of text. */
void do_next_block(void)
{
filestruct *was_current = openfile->current;
@@ -230,12 +268,11 @@ void do_next_block(void)
}
openfile->current_x = 0;
edit_redraw(was_current);
edit_redraw(was_current, CENTERING);
}
/* Move to the previous word in the file. If allow_punct is TRUE, treat
* punctuation as part of a word. If update_screen is TRUE, update the
* screen afterwards. */
/* Move to the previous word. If allow_punct is TRUE, treat punctuation
* as part of a word. When requested, update the screen afterwards. */
void do_prev_word(bool allow_punct, bool update_screen)
{
filestruct *was_current = openfile->current;
@@ -273,23 +310,13 @@ void do_prev_word(bool allow_punct, bool update_screen)
openfile->current_x = move_mbright(openfile->current->data,
openfile->current_x);
if (update_screen) {
focusing = FALSE;
edit_redraw(was_current);
}
if (update_screen)
edit_redraw(was_current, FLOWING);
}
/* Move to the previous word in the file, treating punctuation as part of a
* word if the WORD_BOUNDS flag is set, and update the screen afterwards. */
void do_prev_word_void(void)
{
do_prev_word(ISSET(WORD_BOUNDS), TRUE);
}
/* Move to the next word in the file. If allow_punct is TRUE, treat
* punctuation as part of a word. If update_screen is TRUE, update the
* screen afterwards. Return TRUE if we started on a word, and FALSE
* otherwise. */
/* Move to the next word. If allow_punct is TRUE, treat punctuation
* as part of a word. When requested, update the screen afterwards.
* Return TRUE if we started on a word, and FALSE otherwise. */
bool do_next_word(bool allow_punct, bool update_screen)
{
filestruct *was_current = openfile->current;
@@ -301,7 +328,7 @@ bool do_next_word(bool allow_punct, bool update_screen)
while (TRUE) {
/* If at the end of a line, move to the beginning of the next one. */
if (openfile->current->data[openfile->current_x] == '\0') {
/* If at the end of the file, stop. */
/* When at end of file, stop. */
if (openfile->current->next == NULL)
break;
openfile->current = openfile->current->next;
@@ -322,15 +349,20 @@ bool do_next_word(bool allow_punct, bool update_screen)
break;
}
if (update_screen) {
focusing = FALSE;
edit_redraw(was_current);
}
if (update_screen)
edit_redraw(was_current, FLOWING);
/* Return whether we started on a word. */
return started_on_word;
}
/* Move to the previous word in the file, treating punctuation as part of a
* word if the WORD_BOUNDS flag is set, and update the screen afterwards. */
void do_prev_word_void(void)
{
do_prev_word(ISSET(WORD_BOUNDS), TRUE);
}
/* Move to the next word in the file, treating punctuation as part of a word
* if the WORD_BOUNDS flag is set, and update the screen afterwards. */
void do_next_word_void(void)
@@ -339,10 +371,9 @@ void do_next_word_void(void)
}
/* Move to the beginning of the current line (or softwrapped chunk).
* If be_clever is TRUE, do a smart home when wanted and possible,
* and do a dynamic home when in softwrap mode and it's possible.
* If be_clever is FALSE, just do a simple home. */
void do_home(bool be_clever)
* When enabled, do a smart home. When softwrapping, go the beginning
* of the full line when already at the start of a chunk. */
void do_home(void)
{
filestruct *was_current = openfile->current;
size_t was_column = xplustabs();
@@ -353,10 +384,11 @@ void do_home(bool be_clever)
if (ISSET(SOFTWRAP)) {
leftedge = leftedge_for(was_column, openfile->current);
leftedge_x = actual_x(openfile->current->data, leftedge);
leftedge_x = proper_x(openfile->current, &leftedge, FALSE, leftedge,
NULL);
}
if (ISSET(SMART_HOME) && be_clever) {
if (ISSET(SMART_HOME)) {
size_t indent_x = indent_length(openfile->current->data);
if (openfile->current->data[indent_x] != '\0') {
@@ -376,7 +408,7 @@ void do_home(bool be_clever)
if (!moved && ISSET(SOFTWRAP)) {
/* If already at the left edge of the screen, move fully home.
* Otherwise, move to the left edge. */
if (openfile->current_x == leftedge_x && be_clever)
if (openfile->current_x == leftedge_x)
openfile->current_x = 0;
else {
openfile->current_x = leftedge_x;
@@ -388,27 +420,20 @@ void do_home(bool be_clever)
openfile->current_x = 0;
if (moved_off_chunk)
openfile->placewewant = 0;
openfile->placewewant = xplustabs();
/* If we changed chunk, we might be offscreen. Otherwise,
* update current if the mark is on or we changed "page". */
if (ISSET(SOFTWRAP) && moved_off_chunk) {
focusing = FALSE;
edit_redraw(was_current);
} else if (line_needs_update(was_column, openfile->placewewant))
if (ISSET(SOFTWRAP) && moved_off_chunk)
edit_redraw(was_current, FLOWING);
else if (line_needs_update(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
}
/* Do a (smart or dynamic) home. */
void do_home_void(void)
{
do_home(TRUE);
}
/* Move to the end of the current line (or softwrapped chunk).
* If be_clever is TRUE, do a dynamic end when in softwrap mode and
* it's possible. If be_clever is FALSE, just do a simple end. */
void do_end(bool be_clever)
* When softwrapping and alredy at the end of a chunk, go to the
* end of the full line. */
void do_end(void)
{
filestruct *was_current = openfile->current;
size_t was_column = xplustabs();
@@ -434,7 +459,7 @@ void do_end(bool be_clever)
/* If already at the right edge of the screen, move fully to
* the end of the line. Otherwise, move to the right edge. */
if (openfile->current_x == rightedge_x && be_clever)
if (openfile->current_x == rightedge_x)
openfile->current_x = line_len;
else {
openfile->current_x = rightedge_x;
@@ -450,25 +475,17 @@ void do_end(bool be_clever)
/* If we changed chunk, we might be offscreen. Otherwise,
* update current if the mark is on or we changed "page". */
if (ISSET(SOFTWRAP) && moved_off_chunk) {
focusing = FALSE;
edit_redraw(was_current);
} else if (line_needs_update(was_column, openfile->placewewant))
if (ISSET(SOFTWRAP) && moved_off_chunk)
edit_redraw(was_current, FLOWING);
else if (line_needs_update(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
}
/* Do a (dynamic) end. */
void do_end_void(void)
{
do_end(TRUE);
}
/* Move the cursor to the preceding line or chunk. If scroll_only is TRUE,
* also scroll the screen one row, so the cursor stays in the same spot. */
void do_up(bool scroll_only)
{
filestruct *was_current = openfile->current;
size_t was_column = xplustabs();
size_t leftedge, target_column;
/* When just scrolling and the top of the file is onscreen, get out. */
@@ -482,34 +499,15 @@ void do_up(bool scroll_only)
if (go_back_chunks(1, &openfile->current, &leftedge) > 0)
return;
set_proper_index_and_pww(&leftedge, target_column, FALSE);
if (scroll_only)
edit_scroll(BACKWARD, 1);
edit_redraw(was_current, FLOWING);
/* <Up> should not change placewewant, so restore it. */
openfile->placewewant = leftedge + target_column;
openfile->current_x = actual_x(openfile->current->data,
actual_last_column(leftedge, target_column));
/* 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_y == 0 || scroll_only)
edit_scroll(UPWARD, (ISSET(SMOOTH_SCROLL) || scroll_only) ?
1 : editwinrows / 2 + 1);
if (openfile->current_y > 0) {
/* Redraw the prior line if it's not offscreen, and it's not the same
* line as the current one, and the line was horizontally scrolled. */
if ((!scroll_only || openfile->current_y < editwinrows - 1) &&
openfile->current != was_current &&
line_needs_update(was_column, 0))
update_line(openfile->current->next, 0);
/* Redraw the current line if it needs to be horizontally scrolled. */
if (line_needs_update(0, xplustabs()))
update_line(openfile->current, openfile->current_x);
}
}
/* Move up one line or chunk. */
void do_up_void(void)
{
do_up(FALSE);
}
/* Move the cursor to next line or chunk. If scroll_only is TRUE, also
@@ -517,7 +515,6 @@ void do_up_void(void)
void do_down(bool scroll_only)
{
filestruct *was_current = openfile->current;
size_t was_column = xplustabs();
size_t leftedge, target_column;
get_edge_and_target(&leftedge, &target_column);
@@ -526,28 +523,21 @@ void do_down(bool scroll_only)
if (go_forward_chunks(1, &openfile->current, &leftedge) > 0)
return;
set_proper_index_and_pww(&leftedge, target_column, TRUE);
if (scroll_only)
edit_scroll(FORWARD, 1);
edit_redraw(was_current, FLOWING);
/* <Down> should not change placewewant, so restore it. */
openfile->placewewant = leftedge + target_column;
openfile->current_x = actual_x(openfile->current->data,
actual_last_column(leftedge, target_column));
}
/* When the cursor was on the last line of the edit window (or when just
* scrolling without moving the cursor), scroll the edit window down -- one
* line if we're in smooth scrolling mode, and half a page otherwise. */
if (openfile->current_y == editwinrows - 1 || scroll_only)
edit_scroll(DOWNWARD, (ISSET(SMOOTH_SCROLL) || scroll_only) ?
1 : editwinrows / 2 + 1);
if (openfile->current_y < editwinrows - 1) {
/* Redraw the prior line if it's not offscreen, and it's not the same
* line as the current one, and the line was horizontally scrolled. */
if ((!scroll_only || openfile->current_y > 0) &&
openfile->current != was_current &&
line_needs_update(was_column, 0))
update_line(openfile->current->prev, 0);
/* Redraw the current line if it needs to be horizontally scrolled. */
if (line_needs_update(0, xplustabs()))
update_line(openfile->current, openfile->current_x);
}
/* Move up one line or chunk. */
void do_up_void(void)
{
do_up(FALSE);
}
/* Move down one line or chunk. */
@@ -573,73 +563,31 @@ void do_scroll_down(void)
/* Move left one character. */
void do_left(void)
{
size_t was_column = xplustabs();
#ifndef NANO_TINY
filestruct *was_current = openfile->current;
size_t was_chunk = chunk_for(was_column, was_current);
#endif
if (openfile->current_x > 0)
openfile->current_x = move_mbleft(openfile->current->data,
openfile->current_x);
else if (openfile->current != openfile->fileage) {
do_up_void();
do_end(FALSE);
return;
openfile->current = openfile->current->prev;
openfile->current_x = strlen(openfile->current->data);
}
openfile->placewewant = xplustabs();
#ifndef NANO_TINY
/* If we were on the first line of the edit window, and we changed chunk,
* we're now above the first line of the edit window, so scroll up. */
if (ISSET(SOFTWRAP) && openfile->current_y == 0 &&
openfile->current == was_current &&
chunk_for(openfile->placewewant,
openfile->current) != was_chunk) {
edit_scroll(UPWARD, ISSET(SMOOTH_SCROLL) ? 1 : editwinrows / 2 + 1);
return;
}
#endif
/* Update current if the mark is on or it has changed "page". */
if (line_needs_update(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
edit_redraw(was_current, FLOWING);
}
/* Move right one character. */
void do_right(void)
{
size_t was_column = xplustabs();
#ifndef NANO_TINY
filestruct *was_current = openfile->current;
size_t was_chunk = chunk_for(was_column, was_current);
#endif
if (openfile->current->data[openfile->current_x] != '\0')
openfile->current_x = move_mbright(openfile->current->data,
openfile->current_x);
else if (openfile->current != openfile->filebot) {
do_home(FALSE);
do_down_void();
return;
openfile->current = openfile->current->next;
openfile->current_x = 0;
}
openfile->placewewant = xplustabs();
#ifndef NANO_TINY
/* If we were on the last line of the edit window, and we changed chunk,
* we're now below the first line of the edit window, so scroll down. */
if (ISSET(SOFTWRAP) && openfile->current_y == editwinrows - 1 &&
openfile->current == was_current &&
chunk_for(openfile->placewewant,
openfile->current) != was_chunk) {
edit_scroll(DOWNWARD, ISSET(SMOOTH_SCROLL) ? 1 : editwinrows / 2 + 1);
return;
}
#endif
/* Update current if the mark is on or it has changed "page". */
if (line_needs_update(was_column, openfile->placewewant))
update_line(openfile->current, openfile->current_x);
edit_redraw(was_current, FLOWING);
}

View File

@@ -2,7 +2,7 @@
* nano.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* Copyright (C) 2014-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -22,24 +22,22 @@
#include "proto.h"
#include "revision.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <locale.h>
#ifdef ENABLE_UTF8
#include <langinfo.h>
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#ifndef NANO_TINY
#include <sys/ioctl.h>
#endif
#ifdef ENABLE_UTF8
#include <langinfo.h>
#endif
#include <locale.h>
#include <string.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#include <unistd.h>
#ifdef ENABLE_MOUSE
static int oldinterval = -1;
@@ -73,7 +71,7 @@ filestruct *make_new_node(filestruct *prevnode)
newnode->next = NULL;
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
newnode->multidata = NULL;
#endif
@@ -90,7 +88,7 @@ filestruct *copy_node(const filestruct *src)
dst->prev = src->prev;
dst->lineno = src->lineno;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
dst->multidata = NULL;
#endif
@@ -130,7 +128,7 @@ void unlink_node(filestruct *fileptr)
void delete_node(filestruct *fileptr)
{
free(fileptr->data);
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
free(fileptr->multidata);
#endif
free(fileptr);
@@ -308,16 +306,14 @@ void extract_buffer(filestruct **file_top, filestruct **file_bot,
edittop_inside = (openfile->edittop->lineno >= openfile->fileage->lineno &&
openfile->edittop->lineno <= openfile->filebot->lineno);
#ifndef NANO_TINY
if (openfile->mark_set) {
mark_inside = (openfile->mark_begin->lineno >=
openfile->fileage->lineno &&
openfile->mark_begin->lineno <=
openfile->filebot->lineno &&
(openfile->mark_begin != openfile->fileage ||
openfile->mark_begin_x >= top_x) &&
(openfile->mark_begin != openfile->filebot ||
openfile->mark_begin_x <= bot_x));
same_line = (openfile->mark_begin == openfile->fileage);
if (openfile->mark) {
mark_inside = (openfile->mark->lineno >= openfile->fileage->lineno &&
openfile->mark->lineno <= openfile->filebot->lineno &&
(openfile->mark != openfile->fileage ||
openfile->mark_x >= top_x) &&
(openfile->mark != openfile->filebot ||
openfile->mark_x <= bot_x));
same_line = (openfile->mark == openfile->fileage);
}
#endif
@@ -370,11 +366,11 @@ void extract_buffer(filestruct **file_top, filestruct **file_bot,
openfile->current_x = top_x;
#ifndef NANO_TINY
if (mark_inside) {
openfile->mark_begin = openfile->current;
openfile->mark_begin_x = openfile->current_x;
openfile->mark = openfile->current;
openfile->mark_x = openfile->current_x;
} else if (same_line)
/* Update the pointer to this partially cut line. */
openfile->mark_begin = openfile->current;
openfile->mark = openfile->current;
#endif
top_save = openfile->fileage;
@@ -414,7 +410,7 @@ void ingraft_buffer(filestruct *somebuffer)
#ifndef NANO_TINY
/* Keep track of whether the mark begins inside the partition and
* will need adjustment. */
if (openfile->mark_set) {
if (openfile->mark) {
filestruct *top, *bot;
size_t top_x, bot_x;
@@ -447,10 +443,10 @@ void ingraft_buffer(filestruct *somebuffer)
* x coordinate for the change in the current line. */
if (openfile->fileage == openfile->filebot) {
#ifndef NANO_TINY
if (openfile->mark_set && single_line) {
openfile->mark_begin = openfile->current;
if (openfile->mark && single_line) {
openfile->mark = openfile->current;
if (!right_side_up)
openfile->mark_begin_x += openfile->current_x;
openfile->mark_x += openfile->current_x;
}
#endif
/* When the pasted stuff contains no newline, adjust the cursor's
@@ -458,12 +454,12 @@ void ingraft_buffer(filestruct *somebuffer)
openfile->current_x += current_x_save;
}
#ifndef NANO_TINY
else if (openfile->mark_set && single_line) {
else if (openfile->mark && single_line) {
if (right_side_up)
openfile->mark_begin = openfile->fileage;
openfile->mark = openfile->fileage;
else {
openfile->mark_begin = openfile->current;
openfile->mark_begin_x += openfile->current_x - current_x_save;
openfile->mark = openfile->current;
openfile->mark_x += openfile->current_x - current_x_save;
}
}
#endif
@@ -509,6 +505,9 @@ void unlink_opennode(openfilestruct *fileptr)
{
assert(fileptr != fileptr->prev && fileptr != fileptr->next);
if (fileptr == firstfile)
firstfile = firstfile->next;
fileptr->prev->next = fileptr->next;
fileptr->next->prev = fileptr->prev;
@@ -524,7 +523,7 @@ void delete_opennode(openfilestruct *fileptr)
free(fileptr->current_stat);
free(fileptr->lock_filename);
/* Free the undo stack. */
discard_until(NULL, fileptr);
discard_until(NULL, fileptr, TRUE);
#endif
free(fileptr);
}
@@ -563,12 +562,12 @@ void finish(void)
/* Restore the old terminal settings. */
tcsetattr(0, TCSANOW, &oldterm);
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
/* If the user wants history persistence, write the relevant files. */
if (ISSET(HISTORYLOG))
save_history();
if (ISSET(POS_HISTORY)) {
update_poshistory(openfile->filename, openfile->current->lineno, xplustabs() + 1);
save_poshistory();
}
#endif
@@ -719,7 +718,7 @@ void window_init(void)
keypad(bottomwin, TRUE);
}
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
/* Set up the wrapping point, accounting for screen width when negative. */
fill = wrap_at;
if (fill <= 0)
@@ -805,7 +804,7 @@ void usage(void)
#ifndef NANO_TINY
print_opt("-G", "--locking", N_("Use (vim-style) lock files"));
#endif
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
if (!ISSET(RESTRICTED))
print_opt("-H", "--historylog",
N_("Log & read search/replace string history"));
@@ -823,12 +822,12 @@ void usage(void)
N_("Don't convert files from DOS/Mac format"));
#endif
print_opt("-O", "--morespace", N_("Use one more line for editing"));
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
if (!ISSET(RESTRICTED))
print_opt("-P", "--positionlog",
N_("Log & read location of cursor position"));
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
print_opt(_("-Q <str>"), _("--quotestr=<str>"), N_("Quoting string"));
#endif
if (!ISSET(RESTRICTED))
@@ -846,7 +845,7 @@ void usage(void)
print_opt(_("-X <str>"), _("--wordchars=<str>"),
N_("Which other characters are word parts"));
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
if (!ISSET(RESTRICTED))
print_opt(_("-Y <name>"), _("--syntax=<name>"),
N_("Syntax definition to use for coloring"));
@@ -873,21 +872,16 @@ void usage(void)
print_opt("-m", "--mouse", N_("Enable the use of the mouse"));
#endif
print_opt("-n", "--noread", N_("Do not read the file (only write it)"));
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
print_opt(_("-o <dir>"), _("--operatingdir=<dir>"),
N_("Set operating directory"));
#endif
print_opt("-p", "--preserve", N_("Preserve XON (^Q) and XOFF (^S) keys"));
#ifdef ENABLE_NANORC
if (!ISSET(RESTRICTED))
print_opt("-q", "--quiet",
N_("Silently ignore startup issues like rc file errors"));
#endif
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
print_opt(_("-r <#cols>"), _("--fill=<#cols>"),
N_("Set hard-wrapping point at column #cols"));
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
if (!ISSET(RESTRICTED))
print_opt(_("-s <prog>"), _("--speller=<prog>"),
N_("Enable alternate speller"));
@@ -897,7 +891,7 @@ void usage(void)
print_opt("-u", "--unix", N_("Save a file by default in Unix format"));
#endif
print_opt("-v", "--view", N_("View mode (read-only)"));
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
print_opt("-w", "--nowrap", N_("Don't hard-wrap long lines"));
#endif
print_opt("-x", "--nohelp", N_("Don't show the two help lines"));
@@ -928,19 +922,19 @@ void version(void)
#ifdef ENABLE_BROWSER
printf(" --enable-browser");
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
printf(" --enable-color");
#endif
#ifndef DISABLE_EXTRA
#ifdef ENABLE_EXTRA
printf(" --enable-extra");
#endif
#ifdef ENABLE_HELP
printf(" --enable-help");
#endif
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
printf(" --enable-histories");
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
printf(" --enable-justify");
#endif
#ifdef HAVE_LIBMAGIC
@@ -958,38 +952,38 @@ void version(void)
#ifdef ENABLE_MULTIBUFFER
printf(" --enable-multibuffer");
#endif
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
printf(" --enable-operatingdir");
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
printf(" --enable-speller");
#endif
#ifdef ENABLE_TABCOMP
printf(" --enable-tabcomp");
#endif
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
printf(" --enable-wrapping");
#endif
#else /* !NANO_TINY */
#ifndef ENABLE_BROWSER
printf(" --disable-browser");
#endif
#ifdef DISABLE_COLOR
#ifndef ENABLE_COLOR
printf(" --disable-color");
#endif
#ifndef ENABLE_COMMENT
printf(" --disable-comment");
#endif
#ifdef DISABLE_EXTRA
#ifndef ENABLE_EXTRA
printf(" --disable-extra");
#endif
#ifndef ENABLE_HELP
printf(" --disable-help");
#endif
#ifdef DISABLE_HISTORIES
#ifndef ENABLE_HISTORIES
printf(" --disable-histories");
#endif
#ifdef DISABLE_JUSTIFY
#ifndef ENABLE_JUSTIFY
printf(" --disable-justify");
#endif
#ifndef HAVE_LIBMAGIC
@@ -1007,10 +1001,10 @@ void version(void)
#ifndef ENABLE_NANORC
printf(" --disable-nanorc");
#endif
#ifdef DISABLE_OPERATINGDIR
#ifndef ENABLE_OPERATINGDIR
printf(" --disable-operatingdir");
#endif
#ifdef DISABLE_SPELLER
#ifndef ENABLE_SPELLER
printf(" --disable-speller");
#endif
#ifndef ENABLE_TABCOMP
@@ -1019,7 +1013,7 @@ void version(void)
#ifndef ENABLE_WORDCOMPLETION
printf(" --disable-wordcomp");
#endif
#ifdef DISABLE_WRAPPING
#ifndef ENABLE_WRAPPING
printf(" --disable-wrapping");
#endif
#endif /* !NANO_TINY */
@@ -1079,7 +1073,7 @@ void do_exit(void)
/* If the user chose not to save, or if the user chose to save and
* the save succeeded, we're ready to exit. */
if (i == 0 || (i == 1 && do_writeout(TRUE)))
if (i == 0 || (i == 1 && do_writeout(TRUE, TRUE) > 0))
close_and_go();
else if (i != 1)
statusbar(_("Cancelled"));
@@ -1399,7 +1393,7 @@ void do_toggle(int flag)
break;
case WHITESPACE_DISPLAY:
titlebar(NULL); /* Fall through. */
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
case NO_COLOR_SYNTAX:
#endif
refresh_needed = TRUE;
@@ -1572,13 +1566,13 @@ int do_input(bool allow_funcs)
/* The input buffer for actual characters. */
static size_t depth = 0;
/* The length of the input buffer. */
bool preserve = FALSE;
/* Whether to preserve the contents of the cutbuffer. */
bool retain_cuts = FALSE;
/* Whether to conserve the current contents of the cutbuffer. */
const sc *s;
bool have_shortcut;
/* Read in a keystroke. */
input = get_kbinput(edit);
/* Read in a keystroke, and show the cursor while waiting. */
input = get_kbinput(edit, VISIBLE);
#ifndef NANO_TINY
if (input == KEY_WINCH)
@@ -1591,7 +1585,7 @@ int do_input(bool allow_funcs)
if (do_mouse() == 1)
/* The click was on a shortcut -- read in the character
* that it was converted into. */
input = get_kbinput(edit);
input = get_kbinput(edit, BLIND);
else
/* The click was invalid or has been handled -- get out. */
return ERR;
@@ -1629,8 +1623,8 @@ int do_input(bool allow_funcs)
puddle[depth++] = (char)input;
}
#ifndef NANO_TINY
if (openfile->mark_set && openfile->kind_of_mark == SOFTMARK) {
openfile->mark_set = FALSE;
if (openfile->mark && openfile->kind_of_mark == SOFTMARK) {
openfile->mark = NULL;
refresh_needed = TRUE;
}
#endif
@@ -1641,7 +1635,7 @@ int do_input(bool allow_funcs)
* 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
#ifdef ENABLE_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)
@@ -1678,7 +1672,7 @@ int do_input(bool allow_funcs)
|| s->scfunc == do_copy_text || s->scfunc == do_cut_till_eof
#endif
)
preserve = TRUE;
retain_cuts = TRUE;
#ifdef ENABLE_WORDCOMPLETION
if (s->scfunc != complete_a_word)
@@ -1688,16 +1682,18 @@ int do_input(bool allow_funcs)
if (s->scfunc == do_toggle_void) {
do_toggle(s->toggle);
if (s->toggle != CUT_FROM_CURSOR)
preserve = TRUE;
retain_cuts = TRUE;
} else
#endif
{
#ifndef NANO_TINY
filestruct *was_current = openfile->current;
size_t was_x = openfile->current_x;
/* 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;
if (shift_held && !openfile->mark) {
openfile->mark = openfile->current;
openfile->mark_x = openfile->current_x;
openfile->kind_of_mark = SOFTMARK;
}
#endif
@@ -1705,14 +1701,15 @@ int do_input(bool allow_funcs)
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;
if (!shift_held && openfile->mark &&
openfile->kind_of_mark == SOFTMARK &&
(openfile->current_x != was_x ||
openfile->current != was_current)) {
openfile->mark = NULL;
refresh_needed = TRUE;
}
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
if (f && !f->viewok)
check_the_multis(openfile->current);
#endif
@@ -1723,23 +1720,12 @@ int do_input(bool allow_funcs)
/* If we aren't cutting or copying text, and the key wasn't a toggle,
* blow away the text in the cutbuffer upon the next cutting action. */
if (!preserve)
if (!retain_cuts)
cutbuffer_reset();
return input;
}
void xon_complaint(void)
{
statusbar(_("XON ignored, mumble mumble"));
}
void xoff_complaint(void)
{
statusbar(_("XOFF ignored, mumble mumble"));
}
#ifdef ENABLE_MOUSE
/* Handle a mouse click on the edit window or the shortcut list. */
int do_mouse(void)
@@ -1767,10 +1753,6 @@ int do_mouse(void)
#endif
leftedge = get_page_start(xplustabs());
#ifdef DEBUG
fprintf(stderr, "mouse_row = %d, current_y = %ld\n", mouse_row, (long)openfile->current_y);
#endif
/* Move current up or down to the row corresponding to mouse_row. */
if (row_count < 0)
go_back_chunks(-row_count, &openfile->current, &leftedge);
@@ -1790,7 +1772,7 @@ int do_mouse(void)
/* The cursor moved; clean the cutbuffer on the next cut. */
cutbuffer_reset();
edit_redraw(current_save);
edit_redraw(current_save, CENTERING);
}
/* No more handling is needed. */
@@ -1854,9 +1836,18 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
add_undo(ADD);
/* Note that current_x has not yet been incremented. */
if (openfile->mark_set && openfile->current == openfile->mark_begin &&
openfile->current_x < openfile->mark_begin_x)
openfile->mark_begin_x += char_len;
if (openfile->current == openfile->mark &&
openfile->current_x < openfile->mark_x)
openfile->mark_x += char_len;
/* When the cursor is on the top row and not on the first chunk
* of a line, adding text there might change the preceding chunk
* and thus require an adjustment of firstcolumn. */
if (openfile->current == openfile->edittop &&
openfile->firstcolumn > 0) {
ensure_firstcolumn_is_aligned();
refresh_needed = TRUE;
}
#endif
openfile->current_x += char_len;
@@ -1865,7 +1856,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
update_undo(ADD);
#endif
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
/* If text gets wrapped, the edit window needs a refresh. */
if (!ISSET(NO_WRAP) && do_wrap(openfile->current))
refresh_needed = TRUE;
@@ -1886,7 +1877,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
openfile->placewewant = xplustabs();
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
check_the_multis(openfile->current);
#endif
@@ -1896,15 +1887,15 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
int main(int argc, char **argv)
{
int optchr;
#ifndef DISABLE_WRAPJUSTIFY
int stdin_flags, optchr;
#if defined(ENABLED_WRAPORJUSTIFY) && defined(ENABLE_NANORC)
bool fill_used = FALSE;
/* Was the fill option used on the command line? */
#ifndef DISABLE_WRAPPING
#endif
#ifdef ENABLE_WRAPPING
bool forced_wrapping = FALSE;
/* Should long lines be automatically hard wrapped? */
#endif
#endif
#ifdef ENABLE_MULTIBUFFER
bool is_multibuffer;
/* The actual value of the multibuffer option, restored after
@@ -1921,14 +1912,14 @@ int main(int argc, char **argv)
{"rebindkeypad", 0, NULL, 'K'},
{"nonewlines", 0, NULL, 'L'},
{"morespace", 0, NULL, 'O'},
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
{"quotestr", 1, NULL, 'Q'},
#endif
{"restricted", 0, NULL, 'R'},
{"tabsize", 1, NULL, 'T'},
{"quickblank", 0, NULL, 'U'},
{"version", 0, NULL, 'V'},
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
{"syntax", 1, NULL, 'Y'},
#endif
{"constantshow", 0, NULL, 'c'},
@@ -1944,20 +1935,20 @@ int main(int argc, char **argv)
{"mouse", 0, NULL, 'm'},
#endif
{"noread", 0, NULL, 'n'},
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
{"operatingdir", 1, NULL, 'o'},
#endif
{"preserve", 0, NULL, 'p'},
{"quiet", 0, NULL, 'q'},
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
{"fill", 1, NULL, 'r'},
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
{"speller", 1, NULL, 's'},
#endif
{"tempfile", 0, NULL, 't'},
{"view", 0, NULL, 'v'},
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
{"nowrap", 0, NULL, 'w'},
#endif
{"nohelp", 0, NULL, 'x'},
@@ -1987,6 +1978,11 @@ int main(int argc, char **argv)
/* Back up the terminal settings so that they can be restored. */
tcgetattr(0, &oldterm);
/* Get the state of standard input and ensure it uses blocking mode. */
stdin_flags = fcntl(0, F_GETFL, 0);
if (stdin_flags != -1)
fcntl(0, F_SETFL, stdin_flags & ~O_NONBLOCK);
#ifdef ENABLE_UTF8
/* If setting the locale is successful and it uses UTF-8, we need
* to use the multibyte functions for text processing. */
@@ -2063,7 +2059,7 @@ int main(int argc, char **argv)
SET(LOCKING);
break;
#endif
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
case 'H':
SET(HISTORYLOG);
break;
@@ -2087,12 +2083,12 @@ int main(int argc, char **argv)
case 'O':
SET(MORE_SPACE);
break;
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
case 'P':
SET(POS_HISTORY);
break;
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
case 'Q':
quotestr = mallocstrcpy(quotestr, optarg);
break;
@@ -2126,7 +2122,7 @@ int main(int argc, char **argv)
word_chars = mallocstrcpy(word_chars, optarg);
break;
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
case 'Y':
syntaxstr = mallocstrcpy(syntaxstr, optarg);
break;
@@ -2161,7 +2157,7 @@ int main(int argc, char **argv)
case 'n':
SET(NOREAD_MODE);
break;
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
case 'o':
operating_dir = mallocstrcpy(operating_dir, optarg);
break;
@@ -2170,24 +2166,25 @@ int main(int argc, char **argv)
SET(PRESERVE);
break;
#ifdef ENABLE_NANORC
case 'q':
SET(QUIET);
case 'q': /* obsolete, ignored */
break;
#endif
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
case 'r':
if (!parse_num(optarg, &wrap_at)) {
fprintf(stderr, _("Requested fill size \"%s\" is invalid"), optarg);
fprintf(stderr, "\n");
exit(1);
}
#ifdef ENABLE_NANORC
fill_used = TRUE;
#ifndef DISABLE_WRAPPING
#endif
#ifdef ENABLE_WRAPPING
forced_wrapping = TRUE;
#endif
break;
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
case 's':
alt_speller = mallocstrcpy(alt_speller, optarg);
break;
@@ -2203,7 +2200,7 @@ int main(int argc, char **argv)
case 'v':
SET(VIEW_MODE);
break;
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
case 'w':
SET(NO_WRAP);
/* If both --fill and --nowrap are given on the
@@ -2256,20 +2253,20 @@ int main(int argc, char **argv)
#ifdef ENABLE_NANORC
if (!no_rcfiles) {
/* Back up the command-line options, then read the rcfile(s). */
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
char *operating_dir_cpy = operating_dir;
#endif
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
ssize_t wrap_at_cpy = wrap_at;
#endif
#ifndef NANO_TINY
char *backup_dir_cpy = backup_dir;
char *word_chars_cpy = word_chars;
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
char *quotestr_cpy = quotestr;
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
char *alt_speller_cpy = alt_speller;
#endif
ssize_t tabsize_cpy = tabsize;
@@ -2278,17 +2275,17 @@ int main(int argc, char **argv)
memcpy(flags_cpy, flags, sizeof(flags_cpy));
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
operating_dir = NULL;
#endif
#ifndef NANO_TINY
backup_dir = NULL;
word_chars = NULL;
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
quotestr = NULL;
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
alt_speller = NULL;
#endif
@@ -2300,13 +2297,13 @@ int main(int argc, char **argv)
#endif
/* If the backed-up command-line options have a value, restore them. */
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
if (operating_dir_cpy != NULL) {
free(operating_dir);
operating_dir = operating_dir_cpy;
}
#endif
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
if (fill_used)
wrap_at = wrap_at_cpy;
#endif
@@ -2320,13 +2317,13 @@ int main(int argc, char **argv)
word_chars = word_chars_cpy;
}
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
if (quotestr_cpy != NULL) {
free(quotestr);
quotestr = quotestr_cpy;
}
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
if (alt_speller_cpy != NULL) {
free(alt_speller);
alt_speller = alt_speller_cpy;
@@ -2347,52 +2344,51 @@ int main(int argc, char **argv)
#endif
#endif /* ENABLE_NANORC */
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
/* Override a "set nowrap" in an rcfile (or a --disable-wrapping-as-root)
* if --fill was given on the command line and not undone by --nowrap. */
if (forced_wrapping)
UNSET(NO_WRAP);
#endif
/* If we're using bold text instead of reverse video text, set it up
* now. */
/* If the user wants bold instead of reverse video for hilited text... */
if (ISSET(BOLD_TEXT))
hilite_attribute = A_BOLD;
#ifndef DISABLE_HISTORIES
/* Set up the search/replace history. */
#ifdef ENABLE_HISTORIES
/* Initialize the pointers for the Search/Replace/Execute histories. */
history_init();
/* Verify that the home directory and ~/.nano subdir exist. */
if (ISSET(HISTORYLOG) || ISSET(POS_HISTORY)) {
get_homedir();
if (homedir == NULL || check_dotnano() == 0) {
UNSET(HISTORYLOG);
UNSET(POS_HISTORY);
}
/* If we need history files, verify that we have a directory for them,
* and when not, cancel the options. */
if ((ISSET(HISTORYLOG) || ISSET(POS_HISTORY)) && !have_statedir()) {
UNSET(HISTORYLOG);
UNSET(POS_HISTORY);
}
/* If the user wants history persistence, read the relevant files. */
if (ISSET(HISTORYLOG))
load_history();
if (ISSET(POS_HISTORY))
load_poshistory();
#endif /* !DISABLE_HISTORIES */
#endif /* ENABLE_HISTORIES */
#ifndef NANO_TINY
/* Set up the backup directory (unless we're using restricted mode,
* in which case backups are disabled, since they would allow
* reading from or writing to files not specified on the command
* line). This entails making sure it exists and is a directory, so
* that backup files will be saved there. */
if (!ISSET(RESTRICTED))
/* If backups are enabled and a backup directory was specified and
* we're not in restricted mode, make sure the path exists and is
* a directory, so that backup files can be saved there. */
if (ISSET(BACKUP_FILE) && backup_dir != NULL && !ISSET(RESTRICTED))
init_backup_dir();
#endif
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
/* Set up the operating directory. This entails chdir()ing there,
* so that file reads and writes will be based there. */
init_operating_dir();
if (operating_dir != NULL)
init_operating_dir();
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
/* If punct wasn't specified, set its default value. */
if (punct == NULL)
punct = mallocstrcpy(NULL, "!.?");
@@ -2416,16 +2412,16 @@ int main(int argc, char **argv)
quoteerr = charalloc(size);
regerror(quoterc, &quotereg, quoteerr, size);
}
#endif /* !DISABLE_JUSTIFY */
#endif /* ENABLE_JUSTIFY */
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
/* If we don't have an alternative spell checker after reading the
* command line and/or rcfile(s), check $SPELL for one, as Pico
* does (unless we're using restricted mode, in which case spell
* checking is disabled, since it would allow reading from or
* writing to files not specified on the command line). */
if (!ISSET(RESTRICTED) && alt_speller == NULL) {
char *spellenv = getenv("SPELL");
const char *spellenv = getenv("SPELL");
if (spellenv != NULL)
alt_speller = mallocstrcpy(NULL, spellenv);
}
@@ -2457,6 +2453,7 @@ int main(int argc, char **argv)
/* Initialize the search string. */
last_search = mallocstrcpy(NULL, "");
UNSET(BACKWARDS_SEARCH);
/* If tabsize wasn't specified, set its default value. */
if (tabsize == -1)
@@ -2480,6 +2477,7 @@ int main(int argc, char **argv)
/* Create the three subwindows, based on the current screen dimensions. */
window_init();
curs_set(0);
editwincols = COLS;
@@ -2491,11 +2489,12 @@ int main(int argc, char **argv)
mouse_init();
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
set_colorpairs();
#else
interface_color_pair[TITLE_BAR] = hilite_attribute;
interface_color_pair[LINE_NUMBER] = hilite_attribute;
interface_color_pair[SELECTED_TEXT] = hilite_attribute;
interface_color_pair[STATUS_BAR] = hilite_attribute;
interface_color_pair[KEY_COMBO] = hilite_attribute;
interface_color_pair[FUNCTION_TAG] = A_NORMAL;
@@ -2518,6 +2517,11 @@ int main(int argc, char **argv)
/* Ask for the codes for Shift+Control+Home/End. */
shiftcontrolhome = get_keycode("kHOM6", SHIFT_CONTROL_HOME);
shiftcontrolend = get_keycode("kEND6", SHIFT_CONTROL_END);
/* Ask for the codes for Alt+Left/Right/Up/Down. */
altleft = get_keycode("kLFT3", ALT_LEFT);
altright = get_keycode("kRIT3", ALT_RIGHT);
altup = get_keycode("kUP3", ALT_UP);
altdown = get_keycode("kDN3", ALT_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);
@@ -2561,7 +2565,7 @@ int main(int argc, char **argv)
/* If a position was given on the command line, go there. */
if (givenline != 0 || givencol != 0)
do_gotolinecolumn(givenline, givencol, FALSE, FALSE);
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
else if (ISSET(POS_HISTORY) && openfile->filename[0] != '\0') {
ssize_t savedline, savedcol;
/* If edited before, restore the last cursor position. */
@@ -2592,6 +2596,9 @@ int main(int argc, char **argv)
prepare_for_display();
if (rcfile_with_errors != NULL)
statusline(ALERT, _("Mistakes in '%s'"), rcfile_with_errors);
while (TRUE) {
#ifdef ENABLE_LINENUMBERS
int needed_margin = digits(openfile->filebot->lineno) + 1;
@@ -2626,14 +2633,11 @@ int main(int argc, char **argv)
/* Refresh just the cursor position or the entire edit window. */
if (!refresh_needed) {
place_the_cursor(TRUE);
place_the_cursor();
wnoutrefresh(edit);
} else
edit_refresh();
/* Make sure the cursor is visible. */
curs_set(1);
focusing = TRUE;
/* Forget any earlier statusbar x position. */

View File

@@ -2,7 +2,7 @@
* nano.h -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* Copyright (C) 2014-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -128,10 +128,20 @@
#undef ENABLE_MOUSE
#endif
#if defined(DISABLE_WRAPPING) && defined(DISABLE_JUSTIFY)
#define DISABLE_WRAPJUSTIFY 1
#if defined(ENABLE_WRAPPING) || defined(ENABLE_JUSTIFY)
#define ENABLED_WRAPORJUSTIFY 1
#endif
#define BACKWARD FALSE
#define FORWARD TRUE
#define BLIND FALSE
#define VISIBLE TRUE
#define JUSTFIND 0
#define REPLACING 1
#define INREGION 2
/* Enumeration types. */
typedef enum {
NIX_FILE, DOS_FILE, MAC_FILE
@@ -149,19 +159,16 @@ typedef enum {
SOFTMARK, HARDMARK
} mark_type;
typedef enum {
UPWARD, DOWNWARD
} scroll_dir;
typedef enum {
CENTERING, FLOWING, STATIONARY
} update_type;
typedef enum {
ADD, DEL, BACK, CUT, CUT_TO_EOF, REPLACE,
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
SPLIT_BEGIN, SPLIT_END,
#endif
INDENT, UNINDENT,
#ifdef ENABLE_COMMENT
COMMENT, UNCOMMENT, PREFLIGHT,
#endif
@@ -169,7 +176,7 @@ typedef enum {
} undo_type;
/* Structure types. */
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
typedef struct colortype {
short fg;
/* This syntax's foreground color. */
@@ -258,7 +265,7 @@ typedef struct lintstruct {
/* Regex starts and ends within this line. */
#define CWOULDBE (1<<6)
/* An unpaired start match on or before this line. */
#endif /* !DISABLE_COLOR */
#endif /* ENABLE_COLOR */
/* More structure types. */
typedef struct filestruct {
@@ -270,7 +277,7 @@ typedef struct filestruct {
/* Next node. */
struct filestruct *prev;
/* Previous node. */
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
short *multidata;
/* Array of which multi-line regexes apply to this line. */
#endif
@@ -300,6 +307,8 @@ typedef struct undo_group {
/* First line of group. */
ssize_t bottom_line;
/* Last line of group. */
char **indentations;
/* String data used to restore the affected lines; one per line. */
struct undo_group *next;
} undo_group;
@@ -334,7 +343,7 @@ typedef struct undo {
} undo;
#endif /* !NANO_TINY */
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
typedef struct poshiststruct {
char *filename;
/* The file. */
@@ -373,26 +382,27 @@ typedef struct openfilestruct {
struct stat *current_stat;
/* The file's current stat information. */
#ifndef NANO_TINY
bool mark_set;
/* Whether the mark is on in this file. */
filestruct *mark_begin;
/* 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. */
filestruct *mark;
/* The line in the file where the mark is set; NULL if not set. */
size_t mark_x;
/* The mark's x position in the above line. */
mark_type kind_of_mark;
/* Whether this is a soft or a hard mark. */
/* Whether it is a soft (with Shift) or a hard mark. */
file_format fmt;
/* The file's format. */
/* The file's format -- Unix or DOS or Mac or mixed. */
undo *undotop;
/* The top of the undo list. */
undo *current_undo;
/* The current (i.e. next) level of undo. */
undo_type last_action;
/* The type of the last action the user performed. */
bool pristine;
/* Whether the undo stack still contains the first edit -- it won't
* when a justification or spell check discarded the undo stack. */
char *lock_filename;
/* The path of the lockfile, if we created one. */
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
syntaxtype *syntax;
/* The syntax struct for this file, if any. */
colortype *colorstrings;
@@ -469,6 +479,7 @@ enum
{
TITLE_BAR = 0,
LINE_NUMBER,
SELECTED_TEXT,
STATUS_BAR,
KEY_COMBO,
FUNCTION_TAG,
@@ -559,22 +570,26 @@ enum
#define CONTROL_RIGHT 0x402
#define CONTROL_UP 0x403
#define CONTROL_DOWN 0x404
#define CONTROL_HOME 0x411
#define CONTROL_END 0x412
#define SHIFT_CONTROL_LEFT 0x405
#define SHIFT_CONTROL_RIGHT 0x406
#define SHIFT_CONTROL_UP 0x407
#define SHIFT_CONTROL_DOWN 0x408
#define SHIFT_CONTROL_HOME 0x413
#define SHIFT_CONTROL_END 0x414
#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
#define CONTROL_HOME 0x405
#define CONTROL_END 0x406
#define SHIFT_CONTROL_LEFT 0x411
#define SHIFT_CONTROL_RIGHT 0x412
#define SHIFT_CONTROL_UP 0x413
#define SHIFT_CONTROL_DOWN 0x414
#define SHIFT_CONTROL_HOME 0x415
#define SHIFT_CONTROL_END 0x416
#define ALT_LEFT 0x421
#define ALT_RIGHT 0x422
#define ALT_UP 0x423
#define ALT_DOWN 0x424
#define SHIFT_ALT_LEFT 0x431
#define SHIFT_ALT_RIGHT 0x432
#define SHIFT_ALT_UP 0x433
#define SHIFT_ALT_DOWN 0x434
#define SHIFT_HOME 0x455
#define SHIFT_END 0x456
#define SHIFT_PAGEUP 0x457
#define SHIFT_PAGEDOWN 0x458
#ifdef USE_SLANG
#ifdef ENABLE_UTF8

View File

@@ -21,8 +21,6 @@
#include "proto.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
static char *prompt = NULL;
@@ -50,7 +48,7 @@ int do_statusbar_input(bool *ran_func, bool *finished)
*finished = FALSE;
/* Read in a character. */
input = get_kbinput(bottomwin);
input = get_kbinput(bottomwin, VISIBLE);
#ifndef NANO_TINY
if (input == KEY_WINCH)
@@ -62,7 +60,7 @@ int do_statusbar_input(bool *ran_func, bool *finished)
* shortcut character. */
if (input == KEY_MOUSE) {
if (do_statusbar_mouse() == 1)
input = get_kbinput(bottomwin);
input = get_kbinput(bottomwin, BLIND);
else
return ERR;
}
@@ -124,9 +122,9 @@ int do_statusbar_input(bool *ran_func, bool *finished)
else if (s->scfunc == do_next_word_void)
do_statusbar_next_word();
#endif
else if (s->scfunc == do_home_void)
else if (s->scfunc == do_home)
do_statusbar_home();
else if (s->scfunc == do_end_void)
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. */
@@ -145,7 +143,10 @@ int do_statusbar_input(bool *ran_func, bool *finished)
do_statusbar_delete();
else if (s->scfunc == do_backspace)
do_statusbar_backspace();
else {
else if (s->scfunc == do_uncut_text) {
if (cutbuffer != NULL)
do_statusbar_uncut_text();
} 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
@@ -363,6 +364,23 @@ size_t statusbar_xplustabs(void)
return strnlenpt(answer, statusbar_x);
}
/* Paste the first line of the cutbuffer into the current answer. */
void do_statusbar_uncut_text(void)
{
size_t pastelen = strlen(cutbuffer->data);
char *fusion = charalloc(strlen(answer) + pastelen + 1);
/* Concatenate: the current answer before the cursor, the first line
* of the cutbuffer, plus the rest of the current answer. */
strncpy(fusion, answer, statusbar_x);
strncpy(fusion + statusbar_x, cutbuffer->data, pastelen);
strcpy(fusion + statusbar_x + pastelen, answer + statusbar_x);
free(answer);
answer = fusion;
statusbar_x += pastelen;
}
/* 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
@@ -421,10 +439,7 @@ void update_the_statusbar(void)
/* Get a string of input at the statusbar prompt. */
functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
bool allow_files, bool *listed,
#ifndef DISABLE_HISTORIES
filestruct **history_list,
#endif
bool allow_files, bool *listed, filestruct **history_list,
void (*refresh_func)(void))
{
int kbinput = ERR;
@@ -434,7 +449,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
bool tabbed = FALSE;
/* Whether we've pressed Tab. */
#endif
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
char *history = NULL;
/* The current history string. */
char *magichistory = NULL;
@@ -447,21 +462,14 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
/* The length of the original string that we're trying to
* tab complete, if any. */
#endif
#endif /* !DISABLE_HISTORIES */
#endif /* ENABLE_HISTORIES */
if (statusbar_x > strlen(answer))
statusbar_x = strlen(answer);
#ifdef DEBUG
fprintf(stderr, "acquiring: answer = \"%s\", statusbar_x = %lu\n", answer, (unsigned long) statusbar_x);
#endif
update_the_statusbar();
while (TRUE) {
/* Ensure the cursor is shown when waiting for input. */
curs_set(1);
kbinput = do_statusbar_input(&ran_func, &finished);
#ifndef NANO_TINY
@@ -469,7 +477,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
if (kbinput == KEY_WINCH) {
refresh_func();
*actual = KEY_WINCH;
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
free(magichistory);
#endif
return NULL;
@@ -486,7 +494,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
tabbed = FALSE;
if (func == do_tab) {
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
if (history_list != NULL) {
if (last_kbinput != the_code_for(do_tab, TAB_CODE))
complete_len = strlen(answer);
@@ -503,7 +511,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
&tabbed, refresh_func, listed);
} else
#endif /* ENABLE_TABCOMP */
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
if (func == get_history_older_void) {
if (history_list != NULL) {
/* If we're scrolling up at the bottom of the history list
@@ -549,7 +557,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
finished = FALSE;
}
} else
#endif /* !DISABLE_HISTORIES */
#endif /* ENABLE_HISTORIES */
if (func == do_help_void) {
/* This key has a shortcut-list entry when it's used to go to
* the help browser or display a message indicating that help
@@ -566,12 +574,12 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
update_the_statusbar();
#if !defined(DISABLE_HISTORIES) && defined(ENABLE_TABCOMP)
#if defined(ENABLE_HISTORIES) && defined(ENABLE_TABCOMP)
last_kbinput = kbinput;
#endif
}
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
/* Set the current position in the history list to the bottom. */
if (history_list != NULL) {
history_reset(*history_list);
@@ -596,10 +604,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
* interpreted. The allow_files parameter indicates whether we should
* allow all files (as opposed to just directories) to be tab completed. */
int do_prompt(bool allow_tabs, bool allow_files,
int menu, const char *curranswer,
#ifndef DISABLE_HISTORIES
filestruct **history_list,
#endif
int menu, const char *curranswer, filestruct **history_list,
void (*refresh_func)(void), const char *msg, ...)
{
va_list ap;
@@ -625,11 +630,7 @@ int do_prompt(bool allow_tabs, bool allow_files,
prompt[actual_x(prompt, (COLS < 5) ? 0 : COLS - 5)] = '\0';
func = acquire_an_answer(&retval, allow_tabs, allow_files, &listed,
#ifndef DISABLE_HISTORIES
history_list,
#endif
refresh_func);
history_list, refresh_func);
free(prompt);
prompt = saved_prompt;
@@ -653,10 +654,6 @@ int do_prompt(bool allow_tabs, bool allow_files,
blank_statusbar();
wnoutrefresh(bottomwin);
#ifdef DEBUG
fprintf(stderr, "answer = \"%s\"\n", answer);
#endif
#ifdef ENABLE_TABCOMP
/* If we've done tab completion, there might still be a list of
* filename matches on the edit window. Clear them off. */
@@ -676,7 +673,7 @@ int do_yesno_prompt(bool all, const char *msg)
char *message = display_string(msg, 0, COLS, FALSE);
/* TRANSLATORS: For the next three strings, if possible, specify
* the single-byte shortcuts for both your language and English.
* the single-byte letters for both your language and English.
* For example, in French: "OoYy", for both "Oui" and "Yes". */
const char *yesstr = _("Yy");
const char *nostr = _("Nn");
@@ -688,10 +685,9 @@ int do_yesno_prompt(bool all, const char *msg)
while (response == -2) {
int kbinput;
functionptrtype func;
if (!ISSET(NO_HELP)) {
char shortstr[3];
char shortstr[MAXCHARLEN + 2];
/* Temporary string for (translated) " Y", " N" and " A". */
if (COLS < 32)
@@ -703,20 +699,20 @@ int do_yesno_prompt(bool all, const char *msg)
/* Now show the ones for "Yes", "No", "Cancel" and maybe "All". */
sprintf(shortstr, " %c", yesstr[0]);
wmove(bottomwin, 1, 0);
onekey(shortstr, _("Yes"), width);
post_one_key(shortstr, _("Yes"), width);
if (all) {
shortstr[1] = allstr[0];
wmove(bottomwin, 1, width);
onekey(shortstr, _("All"), width);
post_one_key(shortstr, _("All"), width);
}
shortstr[1] = nostr[0];
wmove(bottomwin, 2, 0);
onekey(shortstr, _("No"), width);
post_one_key(shortstr, _("No"), width);
wmove(bottomwin, 2, width);
onekey("^C", _("Cancel"), width);
post_one_key("^C", _("Cancel"), width);
}
/* Color the statusbar over its full width and display the question. */
@@ -726,17 +722,19 @@ int do_yesno_prompt(bool all, const char *msg)
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
wnoutrefresh(bottomwin);
/* When not replacing, show the cursor. */
if (!all)
curs_set(1);
currmenu = MYESNO;
kbinput = get_kbinput(bottomwin);
func = func_from_key(&kbinput);
/* When not replacing, show the cursor while waiting for a key. */
kbinput = get_kbinput(bottomwin, !all);
if (func == do_cancel)
/* See if the pressed key is in the Yes, No, or All strings. */
if (strchr(yesstr, kbinput) != NULL)
response = 1;
else if (strchr(nostr, kbinput) != NULL)
response = 0;
else if (all && strchr(allstr, kbinput) != NULL)
response = 2;
else if (func_from_key(&kbinput) == do_cancel)
response = -1;
#ifdef ENABLE_MOUSE
else if (kbinput == KEY_MOUSE) {
@@ -746,14 +744,9 @@ int do_yesno_prompt(bool all, const char *msg)
wmouse_trafo(bottomwin, &mouse_y, &mouse_x, FALSE) &&
mouse_x < (width * 2) && mouse_y > 0) {
int x = mouse_x / width;
/* The x-coordinate among the Yes/No/All shortcuts. */
int y = mouse_y - 1;
/* The y-coordinate among the Yes/No/All shortcuts. */
assert(0 <= x && x <= 1 && 0 <= y && y <= 1);
/* x == 0 means they clicked Yes or No.
* y == 0 means Yes or All. */
/* x == 0 means Yes or No, y == 0 means Yes or All. */
response = -2 * x * y + x - y + 1;
if (response == 2 && !all)
@@ -761,15 +754,6 @@ int do_yesno_prompt(bool all, const char *msg)
}
}
#endif /* ENABLE_MOUSE */
else {
/* Look for the kbinput in the Yes, No (and All) strings. */
if (strchr(yesstr, kbinput) != NULL)
response = 1;
else if (strchr(nostr, kbinput) != NULL)
response = 0;
else if (all && strchr(allstr, kbinput) != NULL)
response = 2;
}
}
free(message);

View File

@@ -43,10 +43,6 @@ extern bool as_an_at;
extern int margin;
extern int editwincols;
#ifndef DISABLE_COLOR
extern bool have_palette;
#endif
extern bool suppress_cursorpos;
extern message_type lastmessage;
@@ -56,6 +52,8 @@ extern filestruct *pletion_line;
extern bool inhelp;
extern char *title;
extern bool more_than_one;
extern int didfind;
extern int controlleft;
@@ -71,13 +69,17 @@ extern int shiftcontrolup;
extern int shiftcontroldown;
extern int shiftcontrolhome;
extern int shiftcontrolend;
extern int altleft;
extern int altright;
extern int altup;
extern int altdown;
extern int shiftaltleft;
extern int shiftaltright;
extern int shiftaltup;
extern int shiftaltdown;
#endif
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
extern ssize_t fill;
extern ssize_t wrap_at;
#endif
@@ -96,12 +98,10 @@ extern filestruct *cutbuffer;
extern filestruct *cutbottom;
extern partition *filepart;
extern openfilestruct *openfile;
extern openfilestruct *firstfile;
#ifndef NANO_TINY
extern char *matchbrackets;
#endif
#ifndef NANO_TINY
extern char *whitespace;
extern int whitespace_len[2];
#endif
@@ -109,7 +109,7 @@ extern int whitespace_len[2];
extern const char *exit_tag;
extern const char *close_tag;
extern const char *uncut_tag;
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
extern const char *unjust_tag;
extern char *punct;
extern char *brackets;
@@ -117,7 +117,7 @@ extern char *quotestr;
extern regex_t quotereg;
extern int quoterc;
extern char *quoteerr;
#endif /* !DISABLE_JUSTIFY */
#endif
extern char *word_chars;
@@ -130,18 +130,18 @@ extern char *backup_dir;
extern const char *locking_prefix;
extern const char *locking_suffix;
#endif
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
extern char *operating_dir;
extern char *full_operating_dir;
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
extern char *alt_speller;
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
extern syntaxtype *syntaxes;
extern char *syntaxstr;
extern bool have_palette;
#endif
extern bool refresh_needed;
@@ -152,13 +152,16 @@ extern subnfunc *allfuncs;
extern subnfunc *exitfunc;
extern subnfunc *uncutfunc;
#ifndef DISABLE_HISTORIES
extern filestruct *search_history;
extern filestruct *searchage;
extern filestruct *searchbot;
extern filestruct *replace_history;
extern filestruct *replaceage;
extern filestruct *execute_history;
#ifdef ENABLE_HISTORIES
extern filestruct *searchtop;
extern filestruct *searchbot;
extern filestruct *replacetop;
extern filestruct *replacebot;
extern filestruct *executetop;
extern filestruct *executebot;
extern poshiststruct *position_history;
#endif
@@ -166,12 +169,14 @@ extern regex_t search_regexp;
extern regmatch_t regmatches[10];
extern int hilite_attribute;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
extern char* specified_color_combo[NUMBER_OF_ELEMENTS];
#endif
extern int interface_color_pair[NUMBER_OF_ELEMENTS];
extern char *homedir;
extern char *statedir;
extern char *rcfile_with_errors;
typedef void (*functionptrtype)(void);
@@ -183,7 +188,7 @@ functionptrtype parse_browser_input(int *kbinput);
void browser_refresh(void);
void browser_select_dirname(const char *needle);
void do_filesearch(void);
void do_fileresearch(void);
void do_fileresearch(bool forwards);
void do_first_file(void);
void do_last_file(void);
char *strip_last_component(const char *path);
@@ -217,7 +222,7 @@ char *mbrevstrcasestr(const char *haystack, const char *needle,
const char *index);
size_t mbstrlen(const char *s);
size_t mbstrnlen(const char *s, size_t maxlen);
#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
char *mbstrchr(const char *s, const char *c);
#endif
#ifndef NANO_TINY
@@ -225,7 +230,7 @@ char *mbstrpbrk(const char *s, const char *accept);
char *revstrpbrk(const char *head, const char *accept, const char *index);
char *mbrevstrpbrk(const char *head, const char *accept, const char *index);
#endif
#if defined(ENABLE_NANORC) && (!defined(NANO_TINY) || !defined(DISABLE_JUSTIFY))
#if defined(ENABLE_NANORC) && (!defined(NANO_TINY) || defined(ENABLE_JUSTIFY))
bool has_blank_mbchars(const char *s);
#endif
#ifdef ENABLE_UTF8
@@ -236,7 +241,7 @@ bool is_valid_mbstring(const char *s);
#endif
/* Most functions in color.c. */
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
void set_colorpairs(void);
void color_init(void);
void color_update(void);
@@ -262,7 +267,7 @@ void do_uncut_text(void);
/* Most functions in files.c. */
void initialize_buffer_text(void);
bool open_buffer(const char *filename, bool undoable);
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
void replace_buffer(const char *filename);
#ifndef NANO_TINY
void replace_marked_buffer(const char *filename, filestruct *top, size_t top_x,
@@ -271,8 +276,8 @@ void replace_marked_buffer(const char *filename, filestruct *top, size_t top_x,
#endif
void prepare_for_display(void);
#ifdef ENABLE_MULTIBUFFER
void switch_to_prev_buffer_void(void);
void switch_to_next_buffer_void(void);
void switch_to_prev_buffer(void);
void switch_to_next_buffer(void);
bool close_buffer(void);
#endif
void read_file(FILE *f, int fd, const char *filename, bool undoable,
@@ -282,9 +287,9 @@ char *get_next_filename(const char *name, const char *suffix);
void do_insertfile_void(void);
char *get_full_path(const char *origpath);
char *safe_tempfile(FILE **f);
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
void init_operating_dir(void);
bool check_operating_dir(const char *currpath, bool allow_tabcomp);
bool outside_of_confinement(const char *currpath, bool allow_tabcomp);
#endif
#ifndef NANO_TINY
void init_backup_dir(void);
@@ -298,40 +303,28 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
bool write_marked_file(const char *name, FILE *f_open, bool tmp,
kind_of_writing_type method);
#endif
int do_writeout(bool exiting);
int do_writeout(bool exiting, bool withprompt);
void do_writeout_void(void);
#ifndef NANO_TINY
void do_savefile(void);
#endif
char *real_dir_from_tilde(const char *buf);
#if defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
int diralphasort(const void *va, const void *vb);
void free_chararray(char **array, size_t len);
#endif
#ifdef ENABLE_TABCOMP
char *input_tab(char *buf, bool allow_files, size_t *place,
bool *lastwastab, void (*refresh_func)(void), bool *listed);
#endif
const char *tail(const char *path);
#ifndef DISABLE_HISTORIES
void load_history(void);
void save_history(void);
int check_dotnano(void);
void load_poshistory(void);
void save_poshistory(void);
void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos);
bool has_old_position(const char *file, ssize_t *line, ssize_t *column);
#endif
/* Some functions in global.c. */
size_t length_of_list(int menu);
const sc *first_sc_for(int menu, void (*func)(void));
int the_code_for(void (*func)(void), int defaultval);
functionptrtype func_from_key(int *kbinput);
int keycode_from_string(const char *keystring);
void assign_keyinfo(sc *s, const char *keystring, const int keycode);
void print_sclist(void);
void shortcut_init(void);
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
void set_lint_or_format_shortcuts(void);
void set_spell_shortcuts(void);
#endif
@@ -353,30 +346,48 @@ size_t help_line_len(const char *ptr);
#endif
void do_help_void(void);
/* All functions in move.c. */
/* Most functions in history.c. */
#ifdef ENABLE_HISTORIES
void history_init(void);
void history_reset(const filestruct *h);
void update_history(filestruct **h, const char *s);
char *get_history_older(filestruct **h);
char *get_history_newer(filestruct **h);
void get_history_older_void(void);
void get_history_newer_void(void);
#ifdef ENABLE_TABCOMP
char *get_history_completion(filestruct **h, char *s, size_t len);
#endif
bool have_statedir(void);
void load_history(void);
void save_history(void);
void load_poshistory(void);
void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos);
bool has_old_position(const char *file, ssize_t *line, ssize_t *column);
#endif
/* Most functions in move.c. */
void do_first_line(void);
void do_last_line(void);
void do_page_up(void);
void do_page_down(void);
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
void do_para_begin(bool update_screen);
void do_para_begin_void(void);
void do_para_end(bool update_screen);
void do_para_begin_void(void);
void do_para_end_void(void);
#endif
void do_prev_block(void);
void do_next_block(void);
void do_prev_word(bool allow_punct, bool update_screen);
void do_prev_word_void(void);
bool do_next_word(bool allow_punct, bool update_screen);
void do_prev_word_void(void);
void do_next_word_void(void);
void do_home(bool be_clever);
void do_home_void(void);
void do_end(bool be_clever);
void do_end_void(void);
void do_home(void);
void do_end(void);
void do_up(bool scroll_only);
void do_up_void(void);
void do_down(bool scroll_only);
void do_up_void(void);
void do_down_void(void);
#ifndef NANO_TINY
void do_scroll_up(void);
@@ -448,6 +459,7 @@ void do_statusbar_right(void);
void do_statusbar_backspace(void);
void do_statusbar_delete(void);
void do_statusbar_cut_text(void);
void do_statusbar_uncut_text(void);
#ifndef NANO_TINY
void do_statusbar_prev_word(void);
void do_statusbar_next_word(void);
@@ -458,16 +470,13 @@ size_t get_statusbar_page_start(size_t start_col, size_t column);
void reinit_statusbar_x(void);
void update_the_statusbar(void);
int do_prompt(bool allow_tabs, bool allow_files,
int menu, const char *curranswer,
#ifndef DISABLE_HISTORIES
filestruct **history_list,
#endif
int menu, const char *curranswer, filestruct **history_list,
void (*refresh_func)(void), const char *msg, ...);
int do_yesno_prompt(bool all, const char *msg);
/* Most functions in rcfile.c. */
#ifdef ENABLE_NANORC
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright);
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage);
#endif
@@ -478,9 +487,11 @@ void do_rcfiles(void);
/* Most functions in search.c. */
void not_found_msg(const char *str);
void search_replace_abort(void);
int findnextstr(const char *needle, bool whole_word_only, bool have_region,
int findnextstr(const char *needle, bool whole_word_only, int modus,
size_t *match_len, bool skipone, const filestruct *begin, size_t begin_x);
void do_search(void);
void do_search_forward(void);
void do_search_backward(void);
#ifndef NANO_TINY
void do_findprevious(void);
void do_findnext(void);
@@ -496,19 +507,6 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
void do_gotolinecolumn_void(void);
#ifndef NANO_TINY
void do_find_bracket(void);
#ifdef ENABLE_TABCOMP
char *get_history_completion(filestruct **h, char *s, size_t len);
#endif
#endif
#ifndef DISABLE_HISTORIES
bool history_has_changed(void);
void history_init(void);
void history_reset(const filestruct *h);
void update_history(filestruct **h, const char *s);
char *get_history_older(filestruct **h);
char *get_history_newer(filestruct **h);
void get_history_older_void(void);
void get_history_newer_void(void);
#endif
/* Most functions in text.c. */
@@ -537,24 +535,22 @@ void do_enter(void);
#ifndef NANO_TINY
RETSIGTYPE cancel_command(int signal);
bool execute_command(const char *command);
void discard_until(const undo *thisitem, openfilestruct *thefile);
void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep);
void add_undo(undo_type action);
#ifdef ENABLE_COMMENT
void update_comment_undo(ssize_t lineno);
#endif
void update_multiline_undo(ssize_t lineno, char *indentation);
void update_undo(undo_type action);
#endif /* !NANO_TINY */
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
void wrap_reset(void);
bool do_wrap(filestruct *line);
#endif
#if defined(ENABLE_HELP) || !defined(DISABLE_WRAPJUSTIFY)
#if defined(ENABLE_HELP) || defined(ENABLED_WRAPORJUSTIFY)
ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl);
#endif
#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
size_t indent_length(const char *line);
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
void justify_format(filestruct *paragraph, size_t skip);
bool begpar(const filestruct *const foo);
bool inpar(const filestruct *const foo);
@@ -562,10 +558,10 @@ void do_justify(bool full_justify);
void do_justify_void(void);
void do_full_justify(void);
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
void do_spell(void);
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
void do_linter(void);
void do_formatter(void);
#endif
@@ -577,6 +573,8 @@ void complete_a_word(void);
/* All functions in utils.c. */
void get_homedir(void);
const char *tail(const char *path);
char *concatenate(const char *path, const char *name);
#ifdef ENABLE_LINENUMBERS
int digits(ssize_t n);
#endif
@@ -586,8 +584,11 @@ void snuggly_fit(char **str);
void null_at(char **data, size_t index);
void unsunder(char *str, size_t true_len);
void sunder(char *str);
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
void free_chararray(char **array, size_t len);
#endif
const char *fixbounds(const char *r);
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
bool is_separate_word(size_t position, size_t length, const char *buf);
#endif
const char *strstrwrapper(const char *haystack, const char *needle,
@@ -600,9 +601,9 @@ char *mallocstrcpy(char *dest, const char *src);
char *free_and_assign(char *dest, char *src);
size_t get_page_start(size_t column);
size_t xplustabs(void);
size_t actual_x(const char *s, size_t column);
size_t strnlenpt(const char *s, size_t maxlen);
size_t strlenpt(const char *s);
size_t actual_x(const char *text, size_t column);
size_t strnlenpt(const char *text, size_t maxlen);
size_t strlenpt(const char *text);
void new_magicline(void);
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
void remove_magicline(void);
@@ -621,10 +622,12 @@ void dump_filestruct_reverse(void);
#endif
/* Most functions in winio.c. */
void record_macro(void);
void run_macro(void);
void get_key_buffer(WINDOW *win);
size_t get_key_buffer_len(void);
void unget_kbinput(int kbinput, bool metakey);
int get_kbinput(WINDOW *win);
int get_kbinput(WINDOW *win, bool showcursor);
int parse_kbinput(WINDOW *win);
int arrow_from_abcd(int kbinput);
int parse_escape_sequence(WINDOW *win, int kbinput);
@@ -648,8 +651,8 @@ void statusbar(const char *msg);
void warn_and_shortly_pause(const char *msg);
void statusline(message_type importance, const char *msg, ...);
void bottombars(int menu);
void onekey(const char *keystroke, const char *desc, int length);
void place_the_cursor(bool forreal);
void post_one_key(const char *keystroke, const char *tag, int width);
void place_the_cursor(void);
void edit_draw(filestruct *fileptr, const char *converted,
int line, size_t from_col);
int update_line(filestruct *fileptr, size_t index);
@@ -660,7 +663,7 @@ bool line_needs_update(const size_t old_column, const size_t new_column);
int go_back_chunks(int nrows, filestruct **line, size_t *leftedge);
int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge);
bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge);
void edit_scroll(scroll_dir direction, int nrows);
void edit_scroll(bool direction, int nrows);
#ifndef NANO_TINY
size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
bool *end_of_line);
@@ -671,7 +674,7 @@ size_t number_of_chunks_in(filestruct *line);
void ensure_firstcolumn_is_aligned(void);
#endif
size_t actual_last_column(size_t leftedge, size_t column);
void edit_redraw(filestruct *old_current);
void edit_redraw(filestruct *old_current, update_type manner);
void edit_refresh(void);
void adjust_viewport(update_type location);
void total_redraw(void);
@@ -683,12 +686,10 @@ void spotlight(bool active, size_t from_col, size_t to_col);
#ifndef NANO_TINY
void spotlight_softwrapped(bool active, size_t from_col, size_t to_col);
#endif
void xon_complaint(void);
void xoff_complaint(void);
void do_suspend_void(void);
void disable_waiting(void);
void enable_waiting(void);
#ifndef DISABLE_EXTRA
#ifdef ENABLE_EXTRA
void do_credits(void);
#endif

View File

@@ -3,7 +3,7 @@
* *
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2014 Mike Frysinger *
* Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
* Copyright (C) 2014-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -22,18 +22,16 @@
#include "proto.h"
#include <glob.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <glob.h>
#include <string.h>
#include <unistd.h>
#ifdef ENABLE_NANORC
#ifndef RCFILE_NAME
#define RCFILE_NAME ".nanorc"
#define RCFILE_NAME "nanorc"
#endif
static const rcoption rcopts[] = {
@@ -41,15 +39,15 @@ static const rcoption rcopts[] = {
#ifdef ENABLE_LINENUMBERS
{"linenumbers", LINE_NUMBERS},
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
{"brackets", 0},
#endif
{"const", CONSTANT_SHOW}, /* deprecated form, remove in 2018 */
{"constantshow", CONSTANT_SHOW},
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
{"fill", 0},
#endif
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
{"historylog", HISTORYLOG},
#endif
{"morespace", MORE_SPACE},
@@ -62,18 +60,18 @@ static const rcoption rcopts[] = {
{"nohelp", NO_HELP},
{"nonewlines", NO_NEWLINES},
{"nopauses", NO_PAUSES},
#ifndef DISABLE_WRAPPING
#ifdef ENABLE_WRAPPING
{"nowrap", NO_WRAP},
#endif
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
{"operatingdir", 0},
#endif
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
{"poslog", POS_HISTORY}, /* deprecated form, remove in 2018 */
{"positionlog", POS_HISTORY},
#endif
{"preserve", PRESERVE},
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
{"punct", 0},
{"quotestr", 0},
#endif
@@ -81,7 +79,7 @@ static const rcoption rcopts[] = {
{"rebinddelete", REBIND_DELETE},
{"rebindkeypad", REBIND_KEYPAD},
{"regexp", USE_REGEXP},
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
{"speller", 0},
#endif
{"suspend", SUSPEND},
@@ -113,9 +111,10 @@ static const rcoption rcopts[] = {
{"wordbounds", WORD_BOUNDS},
{"wordchars", 0},
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
{"titlecolor", 0},
{"numbercolor", 0},
{"selectedcolor", 0},
{"statuscolor", 0},
{"keycolor", 0},
{"functioncolor", 0},
@@ -123,13 +122,11 @@ static const rcoption rcopts[] = {
{NULL, 0}
};
static bool errors = FALSE;
/* Whether we got any errors while parsing an rcfile. */
static size_t lineno = 0;
/* If we did, the line number where the last error occurred. */
/* The line number of the last encountered error. */
static char *nanorc = NULL;
/* The path to the rcfile we're parsing. */
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
static bool opensyntax = FALSE;
/* Whether we're allowed to add to the last syntax. When a file ends,
* or when a new syntax command is seen, this bool becomes FALSE. */
@@ -139,21 +136,16 @@ static colortype *lastcolor = NULL;
/* The end of the color list for the current syntax. */
#endif
/* We have an error in some part of the rcfile. Print the error message
* on stderr, and then make the user hit Enter to continue starting
* nano. */
/* Report an error in an rcfile, printing it to stderr. */
void rcfile_error(const char *msg, ...)
{
va_list ap;
if (ISSET(QUIET))
return;
if (rcfile_with_errors == NULL)
rcfile_with_errors = strdup(nanorc);
fprintf(stderr, "\n");
if (lineno > 0) {
errors = TRUE;
if (lineno > 0)
fprintf(stderr, _("Error in %s on line %lu: "), nanorc, (unsigned long)lineno);
}
va_start(ap, msg);
vfprintf(stderr, _(msg), ap);
@@ -163,7 +155,7 @@ void rcfile_error(const char *msg, ...)
}
#endif /* ENABLE_NANORC */
#if defined(ENABLE_NANORC) || !defined(DISABLE_HISTORIES)
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
/* Parse the next word from the string, null-terminate it, and return
* a pointer to the first character after the null terminator. The
* returned pointer will point to '\0' if we hit the end of the line. */
@@ -183,7 +175,7 @@ char *parse_next_word(char *ptr)
return ptr;
}
#endif /* ENABLE_NANORC || !DISABLE_HISTORIES */
#endif /* ENABLE_NANORC || ENABLE_HISTORIES */
#ifdef ENABLE_NANORC
/* Parse an argument, with optional quotes, after a keyword that takes
@@ -222,7 +214,7 @@ char *parse_argument(char *ptr)
return ptr;
}
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
/* Pass over the current regex string in the line starting at ptr,
* null-terminate it, and return a pointer to the /next/ word. */
char *parse_next_regex(char *ptr)
@@ -345,7 +337,7 @@ void parse_syntax(char *ptr)
if (*ptr != '\0')
grab_and_store("extension", ptr, &live_syntax->extensions);
}
#endif /* !DISABLE_COLOR */
#endif /* ENABLE_COLOR */
/* Check whether the given executable function is "universal" (meaning
* any horizontal movement or deletion) and thus is present in almost
@@ -353,13 +345,13 @@ void parse_syntax(char *ptr)
bool is_universal(void (*func)(void))
{
if (func == do_left || func == do_right ||
func == do_home_void || func == do_end_void ||
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)
func == do_cut_text_void || func == do_uncut_text ||
func == do_tab || func == do_enter || func == do_verbatim_input)
return TRUE;
else
return FALSE;
@@ -389,7 +381,7 @@ void parse_binding(char *ptr, bool dobind)
if (strlen(keycopy) < 2) {
rcfile_error(N_("Key name is too short"));
goto free_copy;
goto free_things;
}
/* Uppercase only the first two or three characters of the key name. */
@@ -400,7 +392,7 @@ void parse_binding(char *ptr, bool dobind)
keycopy[2] = toupper((unsigned char)keycopy[2]);
else {
rcfile_error(N_("Key name is too short"));
goto free_copy;
goto free_things;
}
}
@@ -410,15 +402,10 @@ void parse_binding(char *ptr, bool dobind)
keycopy[1] = tolower((unsigned char)keycopy[1]);
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] == '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)) {
goto free_things;
} else if (keycode_from_string(keycopy) < 0) {
rcfile_error(N_("Key name %s is invalid"), keycopy);
goto free_copy;
goto free_things;
}
if (dobind) {
@@ -427,7 +414,7 @@ void parse_binding(char *ptr, bool dobind)
if (funcptr[0] == '\0') {
rcfile_error(N_("Must specify a function to bind the key to"));
goto free_copy;
goto free_things;
}
}
@@ -437,31 +424,23 @@ void parse_binding(char *ptr, bool dobind)
if (menuptr[0] == '\0') {
/* TRANSLATORS: Do not translate the word "all". */
rcfile_error(N_("Must specify a menu (or \"all\") in which to bind/unbind the key"));
goto free_copy;
goto free_things;
}
if (dobind) {
newsc = strtosc(funcptr);
if (newsc == NULL) {
rcfile_error(N_("Cannot map name \"%s\" to a function"), funcptr);
goto free_copy;
goto free_things;
}
}
menu = strtomenu(menuptr);
if (menu < 1) {
rcfile_error(N_("Cannot map name \"%s\" to a menu"), menuptr);
goto free_copy;
goto free_things;
}
#ifdef DEBUG
if (dobind)
fprintf(stderr, "newsc address is now %ld, assigned func = %ld, menu = %x\n",
(long)&newsc, (long)newsc->scfunc, menu);
else
fprintf(stderr, "unbinding \"%s\" from menu %x\n", keycopy, menu);
#endif
if (dobind) {
subnfunc *f;
int mask = 0;
@@ -485,8 +464,7 @@ void parse_binding(char *ptr, bool dobind)
if (!menu) {
rcfile_error(N_("Function '%s' does not exist in menu '%s'"), funcptr, menuptr);
free(newsc);
goto free_copy;
goto free_things;
}
newsc->menus = menu;
@@ -495,23 +473,14 @@ void parse_binding(char *ptr, bool dobind)
/* 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;
goto free_things;
}
#ifdef DEBUG
fprintf(stderr, "s->keystr = \"%s\"\n", newsc->keystr);
fprintf(stderr, "s->keycode = \"%d\"\n", newsc->keycode);
#endif
}
/* Now find and delete any existing same shortcut in the menu(s). */
for (s = sclist; s != NULL; s = s->next) {
if ((s->menus & menu) && !strcmp(s->keystr, keycopy)) {
#ifdef DEBUG
fprintf(stderr, "deleting entry from among menus %x\n", s->menus);
#endif
if ((s->menus & menu) && !strcmp(s->keystr, keycopy))
s->menus &= ~menu;
}
}
if (dobind) {
@@ -530,15 +499,20 @@ void parse_binding(char *ptr, bool dobind)
return;
}
free_copy:
free_things:
free(newsc);
free(keycopy);
}
/* Verify that the given file is not a folder nor a device. */
/* Verify that the given file exists, is not a folder nor a device. */
bool is_good_file(char *file)
{
struct stat rcinfo;
/* First check that the file exists and is readable. */
if (access(file, R_OK) != 0)
return FALSE;
/* If the thing exists, it may not be a directory nor a device. */
if (stat(file, &rcinfo) != -1 && (S_ISDIR(rcinfo.st_mode) ||
S_ISCHR(rcinfo.st_mode) || S_ISBLK(rcinfo.st_mode))) {
@@ -549,7 +523,7 @@ bool is_good_file(char *file)
return TRUE;
}
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
/* Read and parse one included syntax file. */
static void parse_one_include(char *file)
{
@@ -895,9 +869,8 @@ void pick_up_name(const char *kind, char *ptr, char **storage)
}
*storage = mallocstrcpy(*storage, ptr);
}
#endif /* !DISABLE_COLOR */
#endif /* ENABLE_COLOR */
/* Verify that the user has not unmapped every shortcut for a
* function that we consider 'vital' (such as "Exit"). */
@@ -958,7 +931,7 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
keyword = ptr;
ptr = parse_next_word(ptr);
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
/* Handle extending first... */
if (strcasecmp(keyword, "extendsyntax") == 0) {
syntaxtype *sint;
@@ -1018,7 +991,7 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
else if (strcasecmp(keyword, "linter") == 0)
pick_up_name("linter", ptr, &live_syntax->linter);
else if (strcasecmp(keyword, "formatter") == 0)
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
pick_up_name("formatter", ptr, &live_syntax->formatter);
#else
;
@@ -1029,7 +1002,7 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
else if (strcasecmp(keyword, "include") == 0)
parse_includes(ptr);
else
#endif /* !DISABLE_COLOR */
#endif /* ENABLE_COLOR */
if (strcasecmp(keyword, "set") == 0)
set = 1;
else if (strcasecmp(keyword, "unset") == 0)
@@ -1041,7 +1014,7 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
else
rcfile_error(N_("Command \"%s\" not understood"), keyword);
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
/* If a syntax was extended, it stops at the end of the command. */
if (live_syntax != syntaxes)
opensyntax = FALSE;
@@ -1110,11 +1083,13 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
continue;
}
#ifndef DISABLE_COLOR
#ifdef ENABLE_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, "selectedcolor") == 0)
specified_color_combo[SELECTED_TEXT] = option;
else if (strcasecmp(rcopts[i].name, "statuscolor") == 0)
specified_color_combo[STATUS_BAR] = option;
else if (strcasecmp(rcopts[i].name, "keycolor") == 0)
@@ -1123,12 +1098,12 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
specified_color_combo[FUNCTION_TAG] = option;
else
#endif
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
if (strcasecmp(rcopts[i].name, "operatingdir") == 0)
operating_dir = option;
else
#endif
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
if (strcasecmp(rcopts[i].name, "fill") == 0) {
if (!parse_num(option, &wrap_at)) {
rcfile_error(N_("Requested fill size \"%s\" is invalid"),
@@ -1160,7 +1135,7 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
}
} else
#endif
#ifndef DISABLE_JUSTIFY
#ifdef ENABLE_JUSTIFY
if (strcasecmp(rcopts[i].name, "punct") == 0) {
punct = option;
if (has_blank_mbchars(punct)) {
@@ -1187,7 +1162,7 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
word_chars = option;
else
#endif
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
if (strcasecmp(rcopts[i].name, "speller") == 0)
alt_speller = option;
else
@@ -1203,7 +1178,7 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
assert(FALSE);
}
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
if (opensyntax && lastcolor == NULL)
rcfile_error(N_("Syntax \"%s\" has no color commands"),
live_syntax->name);
@@ -1230,7 +1205,6 @@ void parse_one_nanorc(void)
#ifdef DEBUG
fprintf(stderr, "Going to parse file \"%s\"\n", nanorc);
#endif
rcstream = fopen(nanorc, "rb");
/* If opening the file succeeded, parse it. Otherwise, only
@@ -1241,9 +1215,22 @@ void parse_one_nanorc(void)
rcfile_error(N_("Error reading %s: %s"), nanorc, strerror(errno));
}
bool have_nanorc(const char *path, char *name)
{
if (path == NULL)
return FALSE;
free(nanorc);
nanorc = concatenate(path, name);
return is_good_file(nanorc);
}
/* First read the system-wide rcfile, then the user's rcfile. */
void do_rcfiles(void)
{
const char *xdgconfdir;
nanorc = mallocstrcpy(nanorc, SYSCONFDIR "/nanorc");
/* Process the system-wide nanorc. */
@@ -1257,27 +1244,22 @@ void do_rcfiles(void)
#endif
get_homedir();
xdgconfdir = getenv("XDG_CONFIG_HOME");
if (homedir == NULL)
rcfile_error(N_("I can't find my home directory! Wah!"));
else {
nanorc = charealloc(nanorc, strlen(homedir) + strlen(RCFILE_NAME) + 2);
sprintf(nanorc, "%s/%s", homedir, RCFILE_NAME);
/* Process the current user's nanorc. */
/* Now try the to find a nanorc file in the user's home directory
* or in the XDG configuration directories. */
if (have_nanorc(homedir, "/." RCFILE_NAME))
parse_one_nanorc();
}
else if (have_nanorc(xdgconfdir, "/nano/" RCFILE_NAME))
parse_one_nanorc();
else if (have_nanorc(homedir, "/.config/nano/" RCFILE_NAME))
parse_one_nanorc();
else if (homedir == NULL && xdgconfdir == NULL)
rcfile_error(N_("I can't find my home directory! Wah!"));
check_vitals_mapped();
free(nanorc);
if (errors && !ISSET(QUIET) && !ISSET(NO_PAUSES)) {
errors = FALSE;
fprintf(stderr, _("\nPress Enter to continue starting nano.\n"));
while (getchar() != '\n')
;
}
}
#endif /* ENABLE_NANORC */

View File

@@ -2,7 +2,7 @@
* search.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2015, 2016, 2017 Benno Schulenberg *
* Copyright (C) 2015-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -22,18 +22,12 @@
#include "proto.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#ifdef DEBUG
#include <time.h>
#endif
static bool came_full_circle = FALSE;
/* Have we reached the starting line again while searching? */
#ifndef DISABLE_HISTORIES
static bool history_changed = FALSE;
/* Have any of the history lists changed? */
#endif
static bool regexp_compiled = FALSE;
/* Have we compiled any regular expressions? */
@@ -71,21 +65,14 @@ void regexp_cleanup(void)
}
}
/* Indicate on the statusbar that the string at str was not found by the
* last search. */
/* Report on the status bar that the given string was not found. */
void not_found_msg(const char *str)
{
char *disp;
int numchars;
assert(str != NULL);
disp = display_string(str, 0, (COLS / 2) + 1, FALSE);
numchars = actual_x(disp, mbstrnlen(disp, COLS / 2));
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE);
size_t numchars = actual_x(disp, strnlenpt(disp, COLS / 2));
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
(disp[numchars] == '\0') ? "" : "...");
free(disp);
}
@@ -96,7 +83,7 @@ void not_found_msg(const char *str)
void search_replace_abort(void)
{
#ifndef NANO_TINY
if (openfile->mark_set)
if (openfile->mark)
refresh_needed = TRUE;
#endif
regexp_cleanup();
@@ -144,10 +131,7 @@ int search_init(bool replacing, bool use_answer)
/* This is now one simple call. It just does a lot. */
i = do_prompt(FALSE, FALSE,
inhelp ? MFINDINHELP : (replacing ? MREPLACE : MWHEREIS),
backupstring,
#ifndef DISABLE_HISTORIES
&search_history,
#endif
backupstring, &search_history,
/* TRANSLATORS: This is the main search prompt. */
edit_refresh, "%s%s%s%s%s%s", _("Search"),
/* TRANSLATORS: The next three modify the search prompt. */
@@ -156,7 +140,7 @@ int search_init(bool replacing, bool use_answer)
ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") : "", replacing ?
#ifndef NANO_TINY
/* TRANSLATORS: The next two modify the search prompt. */
openfile->mark_set ? _(" (to replace) in selection") :
openfile->mark ? _(" (to replace) in selection") :
#endif
_(" (to replace)") : "", buf);
@@ -178,7 +162,7 @@ int search_init(bool replacing, bool use_answer)
/* If an answer was given, remember it. */
if (*answer != '\0') {
last_search = mallocstrcpy(last_search, answer);
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
update_history(&search_history, answer);
#endif
}
@@ -218,7 +202,7 @@ 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(const char *needle, bool whole_word_only, bool have_region,
int findnextstr(const char *needle, bool whole_word_only, int modus,
size_t *match_len, bool skipone, const filestruct *begin, size_t begin_x)
{
size_t found_len = strlen(needle);
@@ -289,7 +273,7 @@ int findnextstr(const char *needle, bool whole_word_only, bool have_region,
/* When doing a regex search, compute the length of the match. */
if (ISSET(USE_REGEXP))
found_len = regmatches[0].rm_eo - regmatches[0].rm_so;
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
/* When we're spell checking, a match should be a separate word;
* if it's not, continue looking in the rest of the line. */
if (whole_word_only && !is_separate_word(found - line->data,
@@ -304,7 +288,6 @@ int findnextstr(const char *needle, bool whole_word_only, bool have_region,
/* If we're back at the beginning, then there is no needle. */
if (came_full_circle) {
not_found_msg(needle);
enable_waiting();
return 0;
}
@@ -318,7 +301,7 @@ int findnextstr(const char *needle, bool whole_word_only, bool have_region,
/* If we've reached the start or end of the buffer, wrap around;
* but stop when spell-checking or replacing in a region. */
if (line == NULL) {
if (whole_word_only || have_region) {
if (whole_word_only || modus == INREGION) {
enable_waiting();
return 0;
}
@@ -328,9 +311,11 @@ int findnextstr(const char *needle, bool whole_word_only, bool have_region,
else
line = openfile->fileage;
statusbar(_("Search Wrapped"));
/* Delay the "Searching..." message for at least two seconds. */
feedback = -2;
if (modus == JUSTFIND) {
statusbar(_("Search Wrapped"));
/* Delay the "Searching..." message for at least two seconds. */
feedback = -2;
}
}
/* If we've reached the original starting line, take note. */
@@ -349,10 +334,8 @@ int findnextstr(const char *needle, bool whole_word_only, bool have_region,
/* Ensure that the found occurrence is not beyond the starting x. */
if (came_full_circle && ((!ISSET(BACKWARDS_SEARCH) && found_x > begin_x) ||
(ISSET(BACKWARDS_SEARCH) && found_x < begin_x))) {
not_found_msg(needle);
(ISSET(BACKWARDS_SEARCH) && found_x < begin_x)))
return 0;
}
/* Set the current position to point at what we found. */
openfile->current = line;
@@ -365,6 +348,7 @@ int findnextstr(const char *needle, bool whole_word_only, bool have_region,
/* Wipe the "Searching..." message and unset the suppression flag. */
if (feedback > 0) {
blank_statusbar();
wrefresh(bottomwin);
suppress_cursorpos = FALSE;
}
@@ -387,35 +371,40 @@ void do_search(void)
go_looking();
}
/* Search forward for a string. */
void do_search_forward(void)
{
UNSET(BACKWARDS_SEARCH);
do_search();
}
/* Search backwards for a string. */
void do_search_backward(void)
{
SET(BACKWARDS_SEARCH);
do_search();
}
#ifndef NANO_TINY
/* Search in the backward direction for the next occurrence. */
void do_findprevious(void)
{
if ISSET(BACKWARDS_SEARCH)
do_research();
else {
SET(BACKWARDS_SEARCH);
do_research();
UNSET(BACKWARDS_SEARCH);
}
SET(BACKWARDS_SEARCH);
do_research();
}
/* Search in the forward direction for the next occurrence. */
void do_findnext(void)
{
if ISSET(BACKWARDS_SEARCH) {
UNSET(BACKWARDS_SEARCH);
do_research();
SET(BACKWARDS_SEARCH);
} else
do_research();
UNSET(BACKWARDS_SEARCH);
do_research();
}
#endif /* !NANO_TINY */
/* Search for the last string without prompting. */
void do_research(void)
{
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
/* If nothing was searched for yet during this run of nano, but
* there is a search history, take the most recent item. */
if (*last_search == '\0' && searchbot->prev != NULL)
@@ -448,7 +437,7 @@ void go_looking(void)
came_full_circle = FALSE;
didfind = findnextstr(last_search, FALSE, FALSE, NULL, FALSE,
didfind = findnextstr(last_search, FALSE, JUSTFIND, NULL, FALSE,
openfile->current, openfile->current_x);
/* If we found something, and we're back at the exact same spot
@@ -456,12 +445,14 @@ void go_looking(void)
if (didfind == 1 && openfile->current == was_current &&
openfile->current_x == was_current_x)
statusbar(_("This is the only occurrence"));
else if (didfind == 0)
not_found_msg(last_search);
#ifdef DEBUG
statusline(HUSH, "Took: %.2f", (double)(clock() - start) / CLOCKS_PER_SEC);
#endif
edit_redraw(was_current);
edit_redraw(was_current, CENTERING);
search_replace_abort();
}
@@ -557,21 +548,21 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
size_t match_len;
bool replaceall = FALSE;
bool skipone = FALSE;
bool mark_was_set = FALSE;
int modus = REPLACING;
#ifndef NANO_TINY
filestruct *was_mark = openfile->mark;
filestruct *top, *bot;
size_t top_x, bot_x;
bool right_side_up = FALSE;
/* TRUE if (mark_begin, mark_begin_x) is the top of the mark,
* FALSE if (current, current_x) is. */
mark_was_set = openfile->mark_set;
/* If the mark is on, frame the region, and turn the mark off. */
if (mark_was_set) {
if (openfile->mark) {
mark_order((const filestruct **)&top, &top_x,
(const filestruct **)&bot, &bot_x, &right_side_up);
openfile->mark_set = FALSE;
openfile->mark = NULL;
modus = INREGION;
/* Start either at the top or the bottom of the marked region. */
if (!ISSET(BACKWARDS_SEARCH)) {
@@ -588,7 +579,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
while (TRUE) {
int i = 0;
int result = findnextstr(needle, whole_word_only, mark_was_set,
int result = findnextstr(needle, whole_word_only, modus,
&match_len, skipone, real_current, *real_current_x);
/* If nothing more was found, or the user aborted, stop looping. */
@@ -600,7 +591,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
#ifndef NANO_TINY
/* An occurrence outside of the marked region means we're done. */
if (mark_was_set && (openfile->current->lineno > bot->lineno ||
if (was_mark && (openfile->current->lineno > bot->lineno ||
openfile->current->lineno < top->lineno ||
(openfile->current == bot &&
openfile->current_x + match_len > bot_x) ||
@@ -621,9 +612,6 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
/* Refresh the edit window, scrolling it if necessary. */
edit_refresh();
/* Don't show cursor, to not distract from highlighted match. */
curs_set(0);
spotlight(TRUE, from_col, to_col);
/* TRANSLATORS: This is a prompt. */
@@ -655,20 +643,20 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
#ifndef NANO_TINY
/* If the mark was on and it was located after the cursor,
* then adjust its x position for any text length changes. */
if (mark_was_set && !right_side_up) {
if (openfile->current == openfile->mark_begin &&
openfile->mark_begin_x > openfile->current_x) {
if (openfile->mark_begin_x < openfile->current_x + match_len)
openfile->mark_begin_x = openfile->current_x;
if (was_mark && !right_side_up) {
if (openfile->current == was_mark &&
openfile->mark_x > openfile->current_x) {
if (openfile->mark_x < openfile->current_x + match_len)
openfile->mark_x = openfile->current_x;
else
openfile->mark_begin_x += length_change;
bot_x = openfile->mark_begin_x;
openfile->mark_x += length_change;
bot_x = openfile->mark_x;
}
}
/* If the mark was not on or it was before the cursor, then
* adjust the cursor's x position for any text length changes. */
if (!mark_was_set || right_side_up) {
if (!was_mark || right_side_up) {
#endif
if (openfile->current == real_current &&
openfile->current_x < *real_current_x) {
@@ -696,7 +684,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
openfile->current->data = copy;
if (!replaceall) {
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
/* When doing syntax coloring, the replacement might require
* a change of colors, so refresh the whole edit window. */
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX))
@@ -714,17 +702,15 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
if (numreplaced == -1)
not_found_msg(needle);
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
else if (numreplaced > 0)
refresh_needed = TRUE;
#endif
#ifndef NANO_TINY
if (mark_was_set)
openfile->mark_set = TRUE;
openfile->mark = was_mark;
#endif
/* If the NO_NEWLINES flag isn't set, and text has been added to the
/* If "automatic newline" is enabled, and text has been added to the
* magicline, make a new magicline. */
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
new_magicline();
@@ -757,14 +743,11 @@ void do_replace(void)
if (i != 0)
return;
i = do_prompt(FALSE, FALSE, MREPLACEWITH, NULL,
#ifndef DISABLE_HISTORIES
&replace_history,
#endif
i = do_prompt(FALSE, FALSE, MREPLACEWITH, NULL, &replace_history,
/* TRANSLATORS: This is a prompt. */
edit_refresh, _("Replace with"));
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
/* If the replace string is not "", add it to the replace history list. */
if (i == 0)
update_history(&replace_history, answer);
@@ -794,9 +777,8 @@ void do_replace(void)
refresh_needed = TRUE;
if (numreplaced >= 0)
statusline(HUSH, P_("Replaced %lu occurrence",
"Replaced %lu occurrences", (unsigned long)numreplaced),
(unsigned long)numreplaced);
statusline(HUSH, P_("Replaced %zd occurrence",
"Replaced %zd occurrences", numreplaced), numreplaced);
search_replace_abort();
}
@@ -825,10 +807,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
/* Ask for the line and column. */
int i = do_prompt(FALSE, FALSE, MGOTOLINE,
use_answer ? answer : NULL,
#ifndef DISABLE_HISTORIES
NULL,
#endif
use_answer ? answer : NULL, NULL,
/* TRANSLATORS: This is a prompt. */
edit_refresh, _("Enter line number, column number"));
@@ -1075,8 +1054,7 @@ void do_find_bracket(void)
/* If count is zero, we've found a matching bracket. Update
* the screen and get out. */
if (count == 0) {
focusing = FALSE;
edit_redraw(current_save);
edit_redraw(current_save, FLOWING);
break;
}
} else {
@@ -1090,199 +1068,3 @@ void do_find_bracket(void)
}
}
#endif /* !NANO_TINY */
#ifndef DISABLE_HISTORIES
/* Indicate whether any of the history lists have changed. */
bool history_has_changed(void)
{
return history_changed;
}
/* Initialize the search and replace history lists. */
void history_init(void)
{
search_history = make_new_node(NULL);
search_history->data = mallocstrcpy(NULL, "");
searchage = search_history;
searchbot = search_history;
replace_history = make_new_node(NULL);
replace_history->data = mallocstrcpy(NULL, "");
replaceage = replace_history;
replacebot = replace_history;
}
/* Set the current position in the history list h to the bottom. */
void history_reset(const filestruct *h)
{
if (h == search_history)
search_history = searchbot;
else if (h == replace_history)
replace_history = replacebot;
}
/* Return the first node containing the first len characters of the
* string s in the history list, starting at h_start and ending at
* h_end, or NULL if there isn't one. */
filestruct *find_history(const filestruct *h_start, const filestruct
*h_end, const char *s, size_t len)
{
const filestruct *p;
for (p = h_start; p != h_end->prev && p != NULL; p = p->prev) {
if (strncmp(s, p->data, len) == 0)
return (filestruct *)p;
}
return NULL;
}
/* Update a history list (the one in which h is the current position)
* with a fresh string s. That is: add s, or move it to the end. */
void update_history(filestruct **h, const char *s)
{
filestruct **hage = NULL, **hbot = NULL, *thesame;
assert(h != NULL && s != NULL);
if (*h == search_history) {
hage = &searchage;
hbot = &searchbot;
} else if (*h == replace_history) {
hage = &replaceage;
hbot = &replacebot;
}
assert(hage != NULL && hbot != NULL);
/* See if the string is already in the history. */
thesame = find_history(*hbot, *hage, s, HIGHEST_POSITIVE);
/* If an identical string was found, delete that item. */
if (thesame != NULL) {
filestruct *after = thesame->next;
/* If the string is at the head of the list, move the head. */
if (thesame == *hage)
*hage = after;
unlink_node(thesame);
renumber(after);
}
/* If the history is full, delete the oldest item (the one at the
* head of the list), to make room for a new item at the end. */
if ((*hbot)->lineno == MAX_SEARCH_HISTORY + 1) {
filestruct *oldest = *hage;
*hage = (*hage)->next;
unlink_node(oldest);
renumber(*hage);
}
/* Store the fresh string in the last item, then create a new item. */
(*hbot)->data = mallocstrcpy((*hbot)->data, s);
splice_node(*hbot, make_new_node(*hbot));
*hbot = (*hbot)->next;
(*hbot)->data = mallocstrcpy(NULL, "");
/* Indicate that the history needs to be saved on exit. */
history_changed = TRUE;
/* Set the current position in the list to the bottom. */
*h = *hbot;
}
/* Move h to the string in the history list just before it, and return
* that string. If there isn't one, don't move h and return NULL. */
char *get_history_older(filestruct **h)
{
assert(h != NULL);
if ((*h)->prev == NULL)
return NULL;
*h = (*h)->prev;
return (*h)->data;
}
/* Move h to the string in the history list just after it, and return
* that string. If there isn't one, don't move h and return NULL. */
char *get_history_newer(filestruct **h)
{
assert(h != NULL);
if ((*h)->next == NULL)
return NULL;
*h = (*h)->next;
return (*h)->data;
}
/* More placeholders. */
void get_history_newer_void(void)
{
;
}
void get_history_older_void(void)
{
;
}
#ifdef ENABLE_TABCOMP
/* Move h to the next string that's a tab completion of the string s,
* looking at only the first len characters of s, and return that
* string. If there isn't one, or if len is 0, don't move h and return
* s. */
char *get_history_completion(filestruct **h, char *s, size_t len)
{
assert(s != NULL);
if (len > 0) {
filestruct *hage = NULL, *hbot = NULL, *p;
assert(h != NULL);
if (*h == search_history) {
hage = searchage;
hbot = searchbot;
} else if (*h == replace_history) {
hage = replaceage;
hbot = replacebot;
}
assert(hage != NULL && hbot != NULL);
/* Search the history list from the current position to the top
* for a match of len characters. Skip over an exact match. */
p = find_history((*h)->prev, hage, s, len);
while (p != NULL && strcmp(p->data, s) == 0)
p = find_history(p->prev, hage, s, len);
if (p != NULL) {
*h = p;
return mallocstrcpy(s, (*h)->data);
}
/* Search the history list from the bottom to the current position
* for a match of len characters. Skip over an exact match. */
p = find_history(hbot, *h, s, len);
while (p != NULL && strcmp(p->data, s) == 0)
p = find_history(p->prev, *h, s, len);
if (p != NULL) {
*h = p;
return mallocstrcpy(s, (*h)->data);
}
}
/* If we're here, we didn't find a match, we didn't find an inexact
* match, or len is 0. Return s. */
return (char *)s;
}
#endif /* ENSABLE_TABCOMP */
#endif /* !DISABLE_HISTORIES */

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
* utils.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2016 Benno Schulenberg *
* Copyright (C) 2016-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -21,14 +21,12 @@
#include "proto.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
/* Return the user's home directory. We use $HOME, and if that fails,
* we fall back on the home directory of the effective user ID. */
@@ -55,6 +53,29 @@ void get_homedir(void)
}
}
/* Return the filename part of the given path. */
const char *tail(const char *path)
{
const char *slash = strrchr(path, '/');
if (slash == NULL)
return path;
else
return ++slash;
}
/* Return a copy of the two given strings, welded together. */
char *concatenate(const char *path, const char *name)
{
size_t pathlen = strlen(path);
char *joined = charalloc(pathlen + strlen(name) + 1);
strcpy(joined, path);
strcpy(joined + pathlen, name);
return joined;
}
#ifdef ENABLE_LINENUMBERS
/* Return the number of digits that the given integer n takes up. */
int digits(ssize_t n)
@@ -172,6 +193,20 @@ void sunder(char *str)
}
}
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
/* Free the memory of the given array, which should contain len elements. */
void free_chararray(char **array, size_t len)
{
if (array == NULL)
return;
while (len > 0)
free(array[--len]);
free(array);
}
#endif
/* Fix the regex if we're on platforms which require an adjustment
* from GNU-style to BSD-style word boundaries. */
const char *fixbounds(const char *r)
@@ -181,10 +216,6 @@ const char *fixbounds(const char *r)
char *r2 = charalloc(strlen(r) * 5);
char *r3;
#ifdef DEBUG
fprintf(stderr, "fixbounds(): Start string = \"%s\"\n", r);
#endif
for (i = 0; i < strlen(r); i++) {
if (r[i] != '\0' && r[i] == '\\' && (r[i + 1] == '>' || r[i + 1] == '<')) {
strcpy(&r2[j], "[[:");
@@ -196,19 +227,18 @@ const char *fixbounds(const char *r)
r2[j] = r[i];
j++;
}
r2[j] = '\0';
r3 = mallocstrcpy(NULL, r2);
free(r2);
#ifdef DEBUG
fprintf(stderr, "fixbounds(): Ending string = \"%s\"\n", r3);
#endif
return (const char *) r3;
#endif /* !GNU_WORDBOUNDS */
return r;
}
#ifndef DISABLE_SPELLER
#ifdef ENABLE_SPELLER
/* Is the word starting at the given position in buf and of the given length
* a separate word? That is: is it not part of a longer word?*/
bool is_separate_word(size_t position, size_t length, const char *buf)
@@ -226,7 +256,7 @@ bool is_separate_word(size_t position, size_t length, const char *buf)
return ((position == 0 || !is_alpha_mbchar(before)) &&
(buf[word_end] == '\0' || !is_alpha_mbchar(after)));
}
#endif /* !DISABLE_SPELLER */
#endif /* ENABLE_SPELLER */
/* Return the position of the needle in the haystack, or NULL if not found.
* When searching backwards, we will find the last match that starts no later
@@ -483,18 +513,18 @@ void remove_magicline(void)
void mark_order(const filestruct **top, size_t *top_x, const filestruct
**bot, size_t *bot_x, bool *right_side_up)
{
if ((openfile->current->lineno == openfile->mark_begin->lineno &&
openfile->current_x > openfile->mark_begin_x) ||
openfile->current->lineno > openfile->mark_begin->lineno) {
*top = openfile->mark_begin;
*top_x = openfile->mark_begin_x;
if ((openfile->current->lineno == openfile->mark->lineno &&
openfile->current_x > openfile->mark_x) ||
openfile->current->lineno > openfile->mark->lineno) {
*top = openfile->mark;
*top_x = openfile->mark_x;
*bot = openfile->current;
*bot_x = openfile->current_x;
if (right_side_up != NULL)
*right_side_up = TRUE;
} else {
*bot = openfile->mark_begin;
*bot_x = openfile->mark_begin_x;
*bot = openfile->mark;
*bot_x = openfile->mark_x;
*top = openfile->current;
*top_x = openfile->current_x;
if (right_side_up != NULL)
@@ -515,8 +545,7 @@ filestruct *fsfromline(ssize_t lineno)
f = f->next;
if (f->lineno != lineno) {
statusline(ALERT, _("Internal error: can't match line %ld. "
"Please save your work."), (long)lineno);
statusline(ALERT, "Gone undo line -- please report a bug");
return NULL;
}
@@ -554,7 +583,7 @@ void dump_filestruct(const filestruct *inptr)
fprintf(stderr, "Dumping a buffer to stderr...\n");
while (inptr != NULL) {
fprintf(stderr, "(%ld) %s\n", (long)inptr->lineno, inptr->data);
fprintf(stderr, "(%zd) %s\n", inptr->lineno, inptr->data);
inptr = inptr->next;
}
}
@@ -565,8 +594,7 @@ void dump_filestruct_reverse(void)
const filestruct *fileptr = openfile->filebot;
while (fileptr != NULL) {
fprintf(stderr, "(%ld) %s\n", (long)fileptr->lineno,
fileptr->data);
fprintf(stderr, "(%zd) %s\n", fileptr->lineno, fileptr->data);
fileptr = fileptr->prev;
}
}

View File

@@ -2,7 +2,7 @@
* winio.c -- This file is part of GNU nano. *
* *
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
* Copyright (C) 2014, 2015, 2016, 2017 Benno Schulenberg *
* Copyright (C) 2014-2017 Benno Schulenberg *
* *
* GNU nano is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
@@ -22,15 +22,11 @@
#include "proto.h"
#include "revision.h"
#include <ctype.h>
#ifdef __linux__
#include <sys/ioctl.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#ifdef REVISION
#define BRANDING REVISION
@@ -53,6 +49,71 @@ static int statusblank = 0;
static bool seen_wide = FALSE;
/* Whether we've seen a multicolumn character in the current line. */
#endif
static bool reveal_cursor = FALSE;
/* Whether the cursor should be shown when waiting for input. */
#ifndef NANO_TINY
static bool recording = FALSE;
/* Whether we are in the process of recording a macro. */
static int *macro_buffer = NULL;
/* A buffer where the recorded key codes are stored. */
static size_t macro_length = 0;
/* The current length of the macro. */
/* Add the given code to the macro buffer. */
void add_to_macrobuffer(int code)
{
macro_length++;
macro_buffer = (int*)nrealloc(macro_buffer, macro_length * sizeof(int));
macro_buffer[macro_length - 1] = code;
}
/* Remove the last key code plus any trailing Esc codes from macro buffer. */
void snip_last_keystroke(void)
{
macro_length--;
while (macro_length > 0 && macro_buffer[macro_length - 1] == '\x1b')
macro_length--;
}
/* Start or stop the recording of keystrokes. */
void record_macro(void)
{
recording = !recording;
if (recording) {
macro_length = 0;
statusbar(_("Recording a macro..."));
} else {
snip_last_keystroke();
statusbar(_("Stopped recording"));
}
}
/* Copy the stored sequence of codes into the regular key buffer,
* so they will be "executed" again. */
void run_macro(void)
{
size_t i;
if (recording) {
statusline(HUSH, _("Cannot run macro while recording"));
snip_last_keystroke();
return;
}
if (macro_length == 0) {
statusline(HUSH, _("Macro is empty"));
return;
}
free(key_buffer);
key_buffer = (int *)nmalloc(macro_length * sizeof(int));
key_buffer_len = macro_length;
for (i = 0; i < macro_length; i++)
key_buffer[i] = macro_buffer[i];
}
#endif /* !NANO_TINY */
/* Control character compatibility:
*
@@ -113,7 +174,7 @@ static bool seen_wide = FALSE;
* buffer is empty. */
void get_key_buffer(WINDOW *win)
{
int input;
int input = ERR;
size_t errcount = 0;
/* If the keystroke buffer isn't empty, get out. */
@@ -124,38 +185,34 @@ void get_key_buffer(WINDOW *win)
* screen updates. */
doupdate();
/* Read in the first character using whatever mode we're in. */
input = wgetch(win);
#ifndef NANO_TINY
if (the_window_resized) {
ungetch(input);
regenerate_screen();
input = KEY_WINCH;
}
#endif
if (input == ERR && !waiting_mode)
return;
if (reveal_cursor)
curs_set(1);
/* Read in the first keystroke using whatever mode we're in. */
while (input == ERR) {
/* If we've failed to get a character MAX_BUF_SIZE times in a row,
* assume our input source is gone and die gracefully. We could
* check if errno is set to EIO ("Input/output error") and die in
* that case, but it's not always set properly. Argh. */
if (++errcount == MAX_BUF_SIZE)
die(_("Too many errors from stdin"));
input = wgetch(win);
#ifndef NANO_TINY
if (the_window_resized) {
regenerate_screen();
input = KEY_WINCH;
break;
}
#endif
input = wgetch(win);
if (input == ERR && !waiting_mode) {
curs_set(0);
return;
}
/* If we've failed to get a character MAX_BUF_SIZE times in a row,
* assume our input source is gone and die gracefully. We could
* check if errno is set to EIO ("Input/output error") and die in
* that case, but it's not always set properly. Argh. */
if (input == ERR && ++errcount == MAX_BUF_SIZE)
die(_("Too many errors from stdin"));
}
curs_set(0);
/* Increment the length of the keystroke buffer, and save the value
* of the keystroke at the end of it. */
key_buffer_len++;
@@ -173,6 +230,10 @@ void get_key_buffer(WINDOW *win)
nodelay(win, TRUE);
while (TRUE) {
#ifndef NANO_TINY
if (recording)
add_to_macrobuffer(input);
#endif
input = wgetch(win);
/* If there aren't any more characters, stop reading. */
@@ -289,10 +350,12 @@ int *get_input(WINDOW *win, size_t input_len)
}
/* Read in a single keystroke, ignoring any that are invalid. */
int get_kbinput(WINDOW *win)
int get_kbinput(WINDOW *win, bool showcursor)
{
int kbinput = ERR;
reveal_cursor = showcursor;
/* Extract one keystroke from the input stream. */
while (kbinput == ERR)
kbinput = parse_kbinput(win);
@@ -527,7 +590,15 @@ int parse_kbinput(WINDOW *win)
} else if (retval == shiftcontrolend) {
shift_held = TRUE;
return CONTROL_END;
} else if (retval == shiftaltleft) {
} else if (retval == altleft)
return ALT_LEFT;
else if (retval == altright)
return ALT_RIGHT;
else if (retval == altup)
return ALT_UP;
else if (retval == altdown)
return ALT_DOWN;
else if (retval == shiftaltleft) {
shift_held = TRUE;
return KEY_HOME;
} else if (retval == shiftaltright) {
@@ -958,6 +1029,19 @@ int convert_sequence(const int *seq, size_t seq_len)
}
break;
#ifndef NANO_TINY
case '9': /* To accomodate iTerm2 in "xterm mode". */
case '3':
switch (seq[4]) {
case 'A': /* Esc [ 1 ; 3 A == Alt-Up on xterm. */
return ALT_UP;
case 'B': /* Esc [ 1 ; 3 B == Alt-Down on xterm. */
return ALT_DOWN;
case 'C': /* Esc [ 1 ; 3 C == Alt-Right on xterm. */
return ALT_RIGHT;
case 'D': /* Esc [ 1 ; 3 D == Alt-Left on xterm. */
return ALT_LEFT;
}
break;
case '4':
/* When the arrow keys are held together with Shift+Meta,
* act as if they are Home/End/PgUp/PgDown with Shift. */
@@ -1252,7 +1336,7 @@ int parse_escape_sequence(WINDOW *win, int kbinput)
suppress_cursorpos = FALSE;
lastmessage = HUSH;
if (currmenu == MMAIN) {
place_the_cursor(TRUE);
place_the_cursor();
curs_set(1);
}
}
@@ -1415,11 +1499,6 @@ long get_unicode_kbinput(WINDOW *win, int kbinput)
statusline(HUSH, _("Unicode Input: %s"), partial);
}
#ifdef DEBUG
fprintf(stderr, "get_unicode_kbinput(): kbinput = %d, uni_digits = %d, uni = %ld, retval = %ld\n",
kbinput, uni_digits, uni, retval);
#endif
/* If we have an end result, reset the Unicode digit counter. */
if (retval != ERR)
uni_digits = 0;
@@ -1508,6 +1587,8 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count)
{
int *kbinput;
reveal_cursor = TRUE;
/* Read in the first code. */
while ((kbinput = get_input(win, 1)) == NULL)
;
@@ -1537,6 +1618,8 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count)
char *multibyte;
int onebyte, i;
reveal_cursor = FALSE;
while (unicode == ERR) {
free(kbinput);
while ((kbinput = get_input(win, 1)) == NULL)
@@ -1655,9 +1738,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
/* Adjust the index if we hit the last two wider ones. */
if ((j > number) && (*mouse_x % i < COLS % i))
j -= 2;
#ifdef DEBUG
fprintf(stderr, "Calculated %i as index in shortcut list, currmenu = %x.\n", j, currmenu);
#endif
/* Ignore releases/clicks of the first mouse button beyond
* the last shortcut. */
if (j > number)
@@ -1675,9 +1756,6 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
if (j == 0)
break;
}
#ifdef DEBUG
fprintf(stderr, "Stopped on func %ld present in menus %x\n", (long)f->scfunc, f->menus);
#endif
/* And put the corresponding key into the keyboard buffer. */
if (f != NULL) {
@@ -1705,12 +1783,10 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
if (in_edit || (in_bottomwin && *mouse_y == 0)) {
int i;
/* One upward roll of the mouse wheel is equivalent to
* moving up three lines, and one downward roll of the mouse
* wheel is equivalent to moving down three lines. */
/* One roll of the mouse wheel should move three lines. */
for (i = 0; i < 3; i++)
unget_kbinput((mevent.bstate & BUTTON4_PRESSED) ?
KEY_PPAGE : KEY_NPAGE, FALSE);
KEY_UP : KEY_DOWN, FALSE);
return 1;
} else
@@ -1875,7 +1951,7 @@ char *display_string(const char *buf, size_t column, size_t span, bool isdata)
#endif
}
while (*buf != '\0' && column < beyond) {
while (*buf != '\0' && (column < beyond || mbwidth(buf) == 0)) {
int charlength, charwidth = 1;
if (*buf == ' ') {
@@ -1895,7 +1971,9 @@ char *display_string(const char *buf, size_t column, size_t span, bool isdata)
} else if (*buf == '\t') {
/* Show a tab as a visible character, or as as a space. */
#ifndef NANO_TINY
if (ISSET(WHITESPACE_DISPLAY)) {
if (ISSET(WHITESPACE_DISPLAY) && (index > 0 || !isdata ||
!ISSET(SOFTWRAP) || column % tabsize == 0 ||
column == start_col)) {
int i = 0;
while (i < whitespace_len[0])
@@ -1966,6 +2044,19 @@ char *display_string(const char *buf, size_t column, size_t span, bool isdata)
return converted;
}
/* Determine the sequence number of the given buffer in the circular list. */
int buffer_number(openfilestruct *buffer)
{
int count = 1;
while (buffer != firstfile) {
buffer = buffer->prev;
count++;
}
return count;
}
/* If path is NULL, we're in normal editing mode, so display the current
* version of nano, the current filename, and whether the current file
* has been modified on the titlebar. If path isn't NULL, we're either
@@ -1979,21 +2070,21 @@ void titlebar(const char *path)
/* The width that "Modified" would take up. */
size_t offset = 0;
/* The position at which the center part of the titlebar starts. */
const char *branding = BRANDING;
const char *upperleft = "";
/* What is shown in the top left corner. */
const char *prefix = "";
/* What is shown before the path -- "File:", "DIR:", or "". */
/* What is shown before the path -- "DIR:" or nothing. */
const char *state = "";
/* The state of the current buffer -- "Modified", "View", or "". */
char *caption;
/* The presentable form of the pathname. */
char *indicator = NULL;
/* The buffer sequence number plus buffer count. */
/* If the screen is too small, there is no titlebar. */
if (topwin == NULL)
return;
assert(path != NULL || openfile->filename != NULL);
wattron(topwin, interface_color_pair[TITLE_BAR]);
blank_titlebar();
@@ -2004,19 +2095,25 @@ void titlebar(const char *path)
* then sacrifice the prefix, and only then start dottifying. */
/* Figure out the path, prefix and state strings. */
if (inhelp)
branding = "";
#ifdef ENABLE_BROWSER
else if (path != NULL)
if (!inhelp && path != NULL)
prefix = _("DIR:");
else
#endif
else {
if (!inhelp) {
/* If there are/were multiple buffers, show which out of how many. */
if (more_than_one) {
indicator = charalloc(24);
sprintf(indicator, "[%i/%i]", buffer_number(openfile),
buffer_number(firstfile->prev));
upperleft = indicator;
} else
upperleft = BRANDING;
if (openfile->filename[0] == '\0')
path = _("New Buffer");
else {
else
path = openfile->filename;
prefix = _("File:");
}
if (openfile->modified)
state = _("Modified");
@@ -2027,7 +2124,7 @@ void titlebar(const char *path)
}
/* Determine the widths of the four elements, including their padding. */
verlen = strlenpt(branding) + 3;
verlen = strlenpt(upperleft) + 3;
prefixlen = strlenpt(prefix);
if (prefixlen > 0)
prefixlen++;
@@ -2040,7 +2137,7 @@ void titlebar(const char *path)
/* Only print the version message when there is room for it. */
if (verlen + prefixlen + pathlen + pluglen + statelen <= COLS)
mvwaddstr(topwin, 0, 2, branding);
mvwaddstr(topwin, 0, 2, upperleft);
else {
verlen = 2;
/* If things don't fit yet, give up the placeholder. */
@@ -2053,6 +2150,8 @@ void titlebar(const char *path)
}
}
free(indicator);
/* If we have side spaces left, center the path name. */
if (verlen > 0)
offset = verlen + (COLS - (verlen + pluglen + statelen) -
@@ -2148,14 +2247,12 @@ void statusline(message_type importance, const char *msg, ...)
if (importance == ALERT) {
if (++alerts > 3 && !ISSET(NO_PAUSES))
msg = _("Further warnings were suppressed");
beep();
else if (alerts < 4)
beep();
}
lastmessage = importance;
/* Turn the cursor off while fiddling in the statusbar. */
curs_set(0);
blank_statusbar();
/* Construct the message out of all the arguments. */
@@ -2241,7 +2338,7 @@ void bottombars(int menu)
wmove(bottomwin, 1 + i % 2, (i / 2) * itemwidth);
onekey(s->keystr, _(f->desc), itemwidth + (COLS % itemwidth));
post_one_key(s->keystr, _(f->desc), itemwidth + (COLS % itemwidth));
i++;
}
@@ -2250,32 +2347,29 @@ void bottombars(int menu)
wrefresh(bottomwin);
}
/* Write a shortcut key to the help area at the bottom of the window.
* keystroke is e.g. "^G" and desc is e.g. "Get Help". We are careful
* to write at most length characters, even if length is very small and
* keystroke and desc are long. Note that waddnstr(,,(size_t)-1) adds
* the whole string! We do not bother padding the entry with blanks. */
void onekey(const char *keystroke, const char *desc, int length)
/* Write a key's representation plus a minute description of its function
* to the screen. For example, the key could be "^C" and its tag "Cancel".
* Key plus tag may occupy at most width columns. */
void post_one_key(const char *keystroke, const char *tag, int width)
{
assert(keystroke != NULL && desc != NULL);
wattron(bottomwin, interface_color_pair[KEY_COMBO]);
waddnstr(bottomwin, keystroke, actual_x(keystroke, length));
waddnstr(bottomwin, keystroke, actual_x(keystroke, width));
wattroff(bottomwin, interface_color_pair[KEY_COMBO]);
length -= strlenpt(keystroke) + 1;
/* If the remaning space is too small, skip the description. */
width -= strlenpt(keystroke);
if (width < 2)
return;
if (length > 0) {
waddch(bottomwin, ' ');
wattron(bottomwin, interface_color_pair[FUNCTION_TAG]);
waddnstr(bottomwin, desc, actual_x(desc, length));
wattroff(bottomwin, interface_color_pair[FUNCTION_TAG]);
}
waddch(bottomwin, ' ');
wattron(bottomwin, interface_color_pair[FUNCTION_TAG]);
waddnstr(bottomwin, tag, actual_x(tag, width - 1));
wattroff(bottomwin, interface_color_pair[FUNCTION_TAG]);
}
/* Redetermine current_y from the position of current relative to edittop,
* and put the cursor in the edit window at (current_y, "current_x"). */
void place_the_cursor(bool forreal)
void place_the_cursor(void)
{
ssize_t row = 0;
size_t col, xpt = xplustabs();
@@ -2306,8 +2400,7 @@ void place_the_cursor(bool forreal)
if (row < editwinrows)
wmove(edit, row, margin + col);
if (forreal)
openfile->current_y = row;
openfile->current_y = row;
}
/* edit_draw() takes care of the job of actually painting a line into
@@ -2321,7 +2414,7 @@ void place_the_cursor(bool forreal)
void edit_draw(filestruct *fileptr, const char *converted,
int row, size_t from_col)
{
#if !defined(NANO_TINY) || !defined(DISABLE_COLOR)
#if !defined(NANO_TINY) || defined(ENABLE_COLOR)
size_t from_x = actual_x(fileptr->data, from_col);
/* The position in fileptr->data of the leftmost character
* that displays at least partially on the window. */
@@ -2331,20 +2424,17 @@ void edit_draw(filestruct *fileptr, const char *converted,
* might be beyond the null terminator of the string. */
#endif
assert(openfile != NULL && fileptr != NULL && converted != NULL);
assert(strlenpt(converted) <= editwincols);
#ifdef ENABLE_LINENUMBERS
/* If line numbering is switched on, put a line number in front of
* the text -- but only for the parts that are not softwrapped. */
if (margin > 0) {
wattron(edit, interface_color_pair[LINE_NUMBER]);
#ifndef NANO_TINY
if (ISSET(SOFTWRAP) && from_x != 0)
if (ISSET(SOFTWRAP) && from_col != 0)
mvwprintw(edit, row, 0, "%*s", margin - 1, " ");
else
#endif
mvwprintw(edit, row, 0, "%*ld", margin - 1, (long)fileptr->lineno);
mvwprintw(edit, row, 0, "%*zd", margin - 1, fileptr->lineno);
wattroff(edit, interface_color_pair[LINE_NUMBER]);
}
#endif
@@ -2361,7 +2451,7 @@ void edit_draw(filestruct *fileptr, const char *converted,
wredrawln(edit, row, 1);
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
/* If color syntaxes are available and turned on, apply them. */
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
const colortype *varnish = openfile->colorstrings;
@@ -2609,15 +2699,15 @@ void edit_draw(filestruct *fileptr, const char *converted,
wattroff(edit, varnish->attributes);
}
}
#endif /* !DISABLE_COLOR */
#endif /* ENABLE_COLOR */
#ifndef NANO_TINY
/* If the mark is on, and fileptr is at least partially selected, we
* need to paint it. */
if (openfile->mark_set &&
(fileptr->lineno <= openfile->mark_begin->lineno ||
if (openfile->mark &&
(fileptr->lineno <= openfile->mark->lineno ||
fileptr->lineno <= openfile->current->lineno) &&
(fileptr->lineno >= openfile->mark_begin->lineno ||
(fileptr->lineno >= openfile->mark->lineno ||
fileptr->lineno >= openfile->current->lineno)) {
const filestruct *top, *bot;
/* The lines where the marked region begins and ends. */
@@ -2654,9 +2744,9 @@ void edit_draw(filestruct *fileptr, const char *converted,
paintlen = actual_x(thetext, end_col - start_col);
}
wattron(edit, hilite_attribute);
wattron(edit, interface_color_pair[SELECTED_TEXT]);
mvwaddnstr(edit, row, margin + start_col, thetext, paintlen);
wattroff(edit, hilite_attribute);
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
}
}
#endif /* !NANO_TINY */
@@ -2788,7 +2878,7 @@ int update_softwrapped_line(filestruct *fileptr)
bool line_needs_update(const size_t old_column, const size_t new_column)
{
#ifndef NANO_TINY
if (openfile->mark_set)
if (openfile->mark)
return TRUE;
else
#endif
@@ -2803,10 +2893,6 @@ int go_back_chunks(int nrows, filestruct **line, size_t *leftedge)
{
int i;
/* Don't move more chunks than the window can hold. */
if (nrows > editwinrows - 1)
nrows = (editwinrows < 2) ? 1 : editwinrows - 1;
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
/* Recede through the requested number of chunks. */
@@ -2896,7 +2982,7 @@ bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge)
/* Scroll the edit window in the given direction and the given number of rows,
* and draw new lines on the blank lines left after the scrolling. */
void edit_scroll(scroll_dir direction, int nrows)
void edit_scroll(bool direction, int nrows)
{
filestruct *line;
size_t leftedge;
@@ -2906,7 +2992,7 @@ void edit_scroll(scroll_dir direction, int nrows)
/* Move the top line of the edit window the requested number of rows up or
* down, and reduce the number of rows with the amount we couldn't move. */
if (direction == UPWARD)
if (direction == BACKWARD)
nrows -= go_back_chunks(nrows, &openfile->edittop, &openfile->firstcolumn);
else
nrows -= go_forward_chunks(nrows, &openfile->edittop, &openfile->firstcolumn);
@@ -2929,7 +3015,7 @@ void edit_scroll(scroll_dir direction, int nrows)
/* Scroll the text of the edit window a number of rows up or down. */
scrollok(edit, TRUE);
wscrl(edit, (direction == UPWARD) ? -nrows : nrows);
wscrl(edit, (direction == BACKWARD) ? -nrows : nrows);
scrollok(edit, FALSE);
/* Part 2: nrows is now the number of rows in the scrolled region of the
@@ -2945,7 +3031,7 @@ void edit_scroll(scroll_dir direction, int nrows)
leftedge = openfile->firstcolumn;
/* If we scrolled forward, move down to the start of the blank region. */
if (direction == DOWNWARD)
if (direction == FORWARD)
go_forward_chunks(editwinrows - nrows, &line, &leftedge);
#ifndef NANO_TINY
@@ -2976,61 +3062,55 @@ void edit_scroll(scroll_dir direction, int nrows)
size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
bool *end_of_line)
{
size_t index = 0;
/* Current index in text. */
size_t goal_column = leftedge + editwincols;
/* The place at or before which text must be broken. */
size_t breaking_col = goal_column;
/* The column where text can be broken, when there's no better. */
size_t column = 0;
/* Current column position in text. */
size_t prev_column = 0;
/* Previous column position in text. */
size_t goal_column;
/* Column of the last character where we can break the text. */
bool found_blank = FALSE;
/* Did we find at least one blank? */
size_t lastblank_index = 0;
/* Current index of the last blank in text. */
size_t lastblank_column = 0;
/* Current column position of the last blank in text. */
int char_len = 0;
/* Length of current character, in bytes. */
size_t last_blank_col = 0;
/* The column position of the last seen whitespace character. */
const char *farthest_blank = NULL;
/* A pointer to the last seen whitespace character in text. */
/* First find the place in text where the current chunk starts. */
while (*text != '\0' && column < leftedge)
text += parse_mbchar(text, NULL, &column);
/* Use a full screen row for text. */
goal_column = column + editwincols;
/* Now find the place in text where this chunk should end. */
while (*text != '\0' && column <= goal_column) {
/* When breaking at blanks, do it *before* the target column. */
if (ISSET(AT_BLANKS) && is_blank_mbchar(text) && column < goal_column) {
found_blank = TRUE;
lastblank_index = index;
lastblank_column = column;
farthest_blank = text;
last_blank_col = column;
}
prev_column = column;
char_len = parse_mbchar(text, NULL, &column);
text += char_len;
index += char_len;
breaking_col = (*text == '\t' ? goal_column : column);
text += parse_mbchar(text, NULL, &column);
}
/* If we didn't overshoot the target, we've found a breaking point. */
/* If we didn't overshoot the limit, we've found a breaking point;
* and we've reached EOL if we didn't even *reach* the limit. */
if (column <= goal_column) {
/* We've reached EOL if we didn't even reach the target. */
*end_of_line = (column < goal_column);
return column;
}
/* If we're softwrapping at blanks and we found at least one blank, move
* the pointer back to the last blank, step beyond it, and we're done. */
if (found_blank) {
text = text - index + lastblank_index;
parse_mbchar(text, NULL, &lastblank_column);
return lastblank_column;
/* If we're softwrapping at blanks and we found at least one blank, break
* after that blank -- if it doesn't overshoot the screen's edge. */
if (farthest_blank != NULL) {
parse_mbchar(farthest_blank, NULL, &last_blank_col);
if (last_blank_col <= goal_column)
return last_blank_col;
/* If it's a tab that overshoots, break at the screen's edge. */
if (*farthest_blank == '\t')
breaking_col = goal_column;
}
/* Otherwise, return the column of the last character that doesn't
* overshoot the target, since we can't break the text anywhere else. */
return (editwincols > 1) ? prev_column : column - 1;
/* Otherwise, break at the last character that doesn't overshoot. */
return (editwincols > 1) ? breaking_col : column - 1;
}
/* Get the row of the softwrapped chunk of the given line that column is on,
@@ -3060,7 +3140,10 @@ size_t get_chunk_and_edge(size_t column, filestruct *line, size_t *leftedge)
* relative to the first row (zero-based). */
size_t chunk_for(size_t column, filestruct *line)
{
return get_chunk_and_edge(column, line, NULL);
if (ISSET(SOFTWRAP))
return get_chunk_and_edge(column, line, NULL);
else
return 0;
}
/* Return the leftmost column of the softwrapped chunk of the given line that
@@ -3069,6 +3152,9 @@ size_t leftedge_for(size_t column, filestruct *line)
{
size_t leftedge;
if (!ISSET(SOFTWRAP))
return 0;
get_chunk_and_edge(column, line, &leftedge);
return leftedge;
@@ -3108,7 +3194,7 @@ size_t actual_last_column(size_t leftedge, size_t column)
/* If we're not on the last chunk, we're one column past the end of
* the row. Shifting back one column might put us in the middle of
* a multi-column character, but actual_x() will fix that later. */
* a multi-column character, but actual_x() will fix that later. */
if (!last_chunk)
end_col--;
@@ -3167,7 +3253,7 @@ bool current_is_offscreen(void)
/* Update any lines between old_current and current that need to be
* updated. Use this if we've moved without changing any text. */
void edit_redraw(filestruct *old_current)
void edit_redraw(filestruct *old_current, update_type manner)
{
size_t was_pww = openfile->placewewant;
@@ -3175,14 +3261,14 @@ void edit_redraw(filestruct *old_current)
/* If the current line is offscreen, scroll until it's onscreen. */
if (current_is_offscreen()) {
adjust_viewport((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTERING : FLOWING);
adjust_viewport(ISSET(SMOOTH_SCROLL) ? manner : CENTERING);
refresh_needed = TRUE;
return;
}
#ifndef NANO_TINY
/* If the mark is on, update all lines between old_current and current. */
if (openfile->mark_set) {
if (openfile->mark) {
filestruct *line = old_current;
while (line != openfile->current) {
@@ -3213,24 +3299,15 @@ void edit_refresh(void)
filestruct *line;
int row = 0;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
/* When needed, initialize the colors for the current syntax. */
if (!have_palette)
color_init();
#endif
/* If the current line is out of view, get it back on screen. */
if (current_is_offscreen()) {
#ifdef DEBUG
fprintf(stderr, "edit-refresh: line = %ld, edittop = %ld and editwinrows = %d\n",
(long)openfile->current->lineno, (long)openfile->edittop->lineno, editwinrows);
#endif
adjust_viewport((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTERING : STATIONARY);
}
#ifdef DEBUG
fprintf(stderr, "edit-refresh: now edittop = %ld\n", (long)openfile->edittop->lineno);
#endif
if (current_is_offscreen())
adjust_viewport((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTERING : FLOWING);
line = openfile->edittop;
@@ -3245,7 +3322,7 @@ void edit_refresh(void)
while (row < editwinrows)
blank_row(edit, row++, 0, COLS);
place_the_cursor(TRUE);
place_the_cursor();
wnoutrefresh(edit);
refresh_needed = FALSE;
@@ -3275,10 +3352,6 @@ void adjust_viewport(update_type manner)
/* Move edittop back goal rows, starting at current[current_x]. */
go_back_chunks(goal, &openfile->edittop, &openfile->firstcolumn);
#ifdef DEBUG
fprintf(stderr, "adjust_viewport(): setting edittop to lineno %ld\n", (long)openfile->edittop->lineno);
#endif
}
/* Unconditionally redraw the entire screen. */
@@ -3315,7 +3388,7 @@ void total_refresh(void)
* portion of the window. */
void display_main_list(void)
{
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
if (openfile->syntax &&
(openfile->syntax->formatter || openfile->syntax->linter))
set_lint_or_format_shortcuts();
@@ -3342,9 +3415,6 @@ void do_cursorpos(bool force)
return;
}
/* Hide the cursor while we are calculating. */
curs_set(0);
/* Determine the size of the file up to the cursor. */
saved_byte = openfile->current->data[openfile->current_x];
openfile->current->data[openfile->current_x] = '\0';
@@ -3398,7 +3468,7 @@ void spotlight(bool active, size_t from_col, size_t to_col)
char *word;
size_t word_span, room;
place_the_cursor(FALSE);
place_the_cursor();
#ifndef NANO_TINY
if (ISSET(SOFTWRAP)) {
@@ -3425,7 +3495,7 @@ void spotlight(bool active, size_t from_col, size_t to_col)
room--;
if (active)
wattron(edit, hilite_attribute);
wattron(edit, interface_color_pair[SELECTED_TEXT]);
waddnstr(edit, word, actual_x(word, room));
@@ -3433,7 +3503,7 @@ void spotlight(bool active, size_t from_col, size_t to_col)
waddch(edit, '$');
if (active)
wattroff(edit, hilite_attribute);
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
free(word);
@@ -3472,12 +3542,12 @@ void spotlight_softwrapped(bool active, size_t from_col, size_t to_col)
break_col - from_col, FALSE);
if (active)
wattron(edit, hilite_attribute);
wattron(edit, interface_color_pair[SELECTED_TEXT]);
waddnstr(edit, word, actual_x(word, break_col));
if (active)
wattroff(edit, hilite_attribute);
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
free(word);
@@ -3494,7 +3564,7 @@ void spotlight_softwrapped(bool active, size_t from_col, size_t to_col)
}
#endif
#ifndef DISABLE_EXTRA
#ifdef ENABLE_EXTRA
#define CREDIT_LEN 54
#define XLCREDIT_LEN 9
@@ -3580,7 +3650,6 @@ void do_credits(void)
window_init();
}
curs_set(0);
nodelay(edit, TRUE);
blank_titlebar();
@@ -3644,4 +3713,4 @@ void do_credits(void)
total_refresh();
}
#endif /* !DISABLE_EXTRA */
#endif /* ENABLE_EXTRA */

View File

@@ -1,7 +1,7 @@
## Here is an example for assembler.
syntax "asm" "\.(S|s|asm)$"
magic "[Aa]ssembl(y|er)"
magic "assembler source"
comment "//"
color red "\<[A-Z_]{2,}\>"

View File

@@ -1,7 +1,7 @@
## Here is an example for awk.
syntax "awk" "\.awk$"
magic "awk.*script text"
magic "awk script"
comment "#"
# Records.

View File

@@ -1,10 +1,14 @@
## Here is an example for C/C++.
syntax "c" "\.(c(c|pp|xx|\+\+)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
magic "(ASCII|UTF-8 Unicode) C(\+\+)? program text"
magic "^(C|C\+\+) (source|program)"
comment "//"
# Constants.
color brightred "\<[A-Z_][0-9A-Z_]+\>"
# Labels.
color brightmagenta "^[[:space:]]*[A-Z_a-z]+:[[:space:]]*$"
color green "\<(float|double|bool|char|int|short|long|sizeof|enum|void|auto|static|const|struct|union|typedef|extern|(un)?signed|inline)\>"
color green "\<((s?size)|((u_?)?int(8|16|32|64|ptr)))_t\>"
color green "\<(class|namespace|template|public|protected|private|typename|this|friend|virtual|override|using|mutable|volatile|register|explicit)\>"

View File

@@ -14,4 +14,4 @@ color ,red " + +"
color brightred "(GNU )?nano [1-9]\.[0-9]\.[^[:space:][:punct:]]+"
# Email addresses.
color yellow "<[[:alnum:].%_+-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}>"
color magenta "<[[:alnum:].%_+-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}>"

View File

@@ -1,6 +1,7 @@
## Here is an example for Emacs Lisp.
syntax "elisp" "\.el$"
magic "Lisp/Scheme program"
comment ";"
# Basic functions/macros

View File

@@ -2,7 +2,6 @@
syntax "guile" "\.scm$"
header "^#!.*guile"
magic "guile"
comment ";"
# Basic scheme functions

View File

@@ -1,11 +1,11 @@
## Here is an example for HTML.
syntax "html" "\.html?$"
magic "HTML document text"
magic "HTML document"
comment "<!--|-->"
# Tags:
color cyan start="<[[:alpha:]/!?]" end=">"
color cyan "<[[:alpha:]/!?][^>]*>"
# Bold, italic, and underlined:
color brightmagenta "</?[biu]>"

View File

@@ -5,6 +5,7 @@
## Version: 2011-05-05
syntax "lua" "\.lua$"
magic "Lua script"
comment "--"
color brightwhite "\[\[.*\]\]"

View File

@@ -1,6 +1,7 @@
## Here is an example for Makefiles.
syntax "makefile" "Makefile[^/]*$" "\.(make|mk)$"
magic "makefile script"
comment "#"
color red "[:=]"

View File

@@ -1,7 +1,7 @@
## Here is an example for manpages.
syntax "man" "\.[1-9]x?$"
magic "troff or preprocessor input text"
magic "troff or preprocessor input"
comment ".\""
color green "\.(SH|SS|TH) .*$"

View File

@@ -4,9 +4,8 @@
syntax "nanohelp"
# Key combos:
color cyan "\^([]4-8A-Z^\_←→↑↓]|Home|End)" "[←→↑↓]"
color cyan "\<(Tab|Enter|Home|End|Ins|Del|Bsp|PgUp|PgDn)\>"
color cyan "\<M-." "\<F1?[0-9]" "(\^|M-)Space"
color cyan "\^[]4-8A-Z^\_◀▶▲▼]" "[◀▶▲▼]" "(\^|M-)Space" "\<M-." "\<F1?[0-9]"
color cyan "\<(Tab|Enter|Ins|Del|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
# Quoted indicators:
color brightred "'(\^|M-)'"

View File

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

View File

@@ -1,6 +1,7 @@
## Here is an example for C/C++/Obj-C.
syntax "m" "\.m$"
magic "Objective-C source"
comment "//"
# Stuffs,

View File

@@ -1,6 +1,7 @@
## Syntax highlighting for OCaml.
syntax "ocaml" "\.mli?$"
magic "OCaml"
comment "(*|*)"
# Uid:

View File

@@ -1,7 +1,7 @@
## Here is an example for patch files.
syntax "patch" "\.(patch|diff|debdiff)$"
magic "diff output text"
magic "diff output"
# There is no official support for comments in patch files.
comment ""

View File

@@ -2,7 +2,7 @@
syntax "perl" "\.p[lm]$"
header "^#!.*perl[-0-9._]*"
magic "Perl script text"
magic "Perl script"
comment "#"
color red "\<(accept|alarm|atan2|bin(d|mode)|c(aller|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork))\>" "\<(get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join)\>" "\<(keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek(dir)?)\>" "\<(se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr(y)?|truncate|umask)\>" "\<(un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\>"

View File

@@ -1,7 +1,7 @@
## Here is an example for PHP.
syntax "php" "\.ph(p[23457s~]?|tml)$"
magic "PHP script text"
magic "PHP script"
comment "//"
# PHP markings.

View File

@@ -1,7 +1,6 @@
## Here is an example for PostgreSQL.
syntax "sql" "\.sql[2345s~]?$"
magic "PostgreSQL script text"
comment "-- "
# Functions.

View File

@@ -2,6 +2,7 @@
syntax "python" "\.py$"
header "^#!.*python[-0-9._]*"
magic "Python script"
linter pyflakes
comment "#"
@@ -17,8 +18,8 @@ color brightgreen ""([^"\]|\\.)+""
# Comments.
color brightred "(^|[[:blank:]])#.*$"
# Triple-quoted strings.
color brightgreen start="'''[^'),]" end="(^|[^(\])'''"
color brightgreen start="\"\"\"[^"),]" end="(^|[^(\])\"\"\""
color brightgreen start="'''([^'),]|$)" end="(^|[^(\])'''"
color brightgreen start="\"\"\"([^"),]|$)" end="(^|[^(\])\"\"\""
# Reminders.
color ,yellow "(FIXME|TODO|XXX)"

View File

@@ -2,6 +2,7 @@
syntax "ruby" "\.rb$"
header "^#!.*ruby[-0-9._]*"
magic "Ruby script"
linter ruby -w -c
comment "#"

View File

@@ -2,7 +2,7 @@
syntax "sh" "\.sh$"
header "^#!.*((ba|da|k|pdk)?sh[-0-9_]*|openrc-run|runscript)"
magic "(POSIX|Bourne.*) shell script text"
magic "(POSIX|Bourne-Again) shell script.*text"
linter dash -n
comment "#"

View File

@@ -1,6 +1,7 @@
## Syntax highlighting for Tcl files.
syntax "tcl" "\.tcl$"
magic "Tcl(/Tk)? script"
comment "#"
# Standard Tcl [info commands]:

View File

@@ -1,6 +1,7 @@
## Here is a short example for TeX files.
syntax "tex" "\.tex$"
magic "(La)?TeX document"
linter chktex -v0 -q -I
comment "%"

View File

@@ -2,7 +2,7 @@
syntax "texinfo" "\.texi$"
header "^\\input texinfo"
magic "Texinfo source text"
magic "Texinfo source"
comment "@c "
# Command arguments, trailing and enclosed.

View File

@@ -2,7 +2,7 @@
syntax "xml" "\.([jrsx]html?|jnlp|mml|pom|rng|sgml?|svg|w[as]dl|wsdd|xjb|xml|xs(d|lt?)|xul)$"
header "<\?xml.*version=.*\?>"
magic "(XML|SGML) (sub)?document text"
magic "(XML|SGML) (sub)?document"
comment "<!--|-->"
# The entire content of the tag: