Compare commits

...

154 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
93 changed files with 24911 additions and 23494 deletions

176
ChangeLog
View File

@@ -1,3 +1,179 @@
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:
----------------------------------

View File

@@ -1,6 +1,13 @@
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.

25
NEWS
View File

@@ -1,3 +1,26 @@
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,
@@ -1627,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="a1971db1d4fe4430a48475a751602f861812503e"
gnulib_hash="b9d0b50f6cd122a1748e1e5b79ecca7a0fef214e"
modules="
futimens

2
cgitrc
View File

@@ -1,2 +0,0 @@
branch-sort=age
repo.branch-sort=age

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.7], [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.7</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
<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.7" "August 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.7
@set UPDATED August 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.7
@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.7.
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,7 +705,8 @@ 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,
@@ -747,8 +750,8 @@ The name of the foreground color may be prefixed with @code{bright}.
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
@@ -1080,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.
@@ -1199,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
@@ -1243,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).
@@ -1304,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
@@ -1463,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.
@@ -1591,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.7" "August 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,7 +76,8 @@ 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,
@@ -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
@@ -437,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.
@@ -559,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
@@ -603,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
@@ -664,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
@@ -789,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.7" "August 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
@@ -269,9 +261,8 @@
## Key bindings.
## See nanorc(5) (section REBINDING KEYS) for more details on this.
##
## The following three 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
## 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

1205
po/bg.po

File diff suppressed because it is too large Load Diff

1284
po/ca.po

File diff suppressed because it is too large Load Diff

1266
po/cs.po

File diff suppressed because it is too large Load Diff

1283
po/da.po

File diff suppressed because it is too large Load Diff

1251
po/de.po

File diff suppressed because it is too large Load Diff

1279
po/eo.po

File diff suppressed because it is too large Load Diff

1270
po/es.po

File diff suppressed because it is too large Load Diff

1212
po/eu.po

File diff suppressed because it is too large Load Diff

1265
po/fi.po

File diff suppressed because it is too large Load Diff

1395
po/fr.po

File diff suppressed because it is too large Load Diff

1379
po/ga.po

File diff suppressed because it is too large Load Diff

1267
po/gl.po

File diff suppressed because it is too large Load Diff

1288
po/hr.po

File diff suppressed because it is too large Load Diff

1269
po/hu.po

File diff suppressed because it is too large Load Diff

1200
po/id.po

File diff suppressed because it is too large Load Diff

1238
po/it.po

File diff suppressed because it is too large Load Diff

1454
po/ja.po

File diff suppressed because it is too large Load Diff

1237
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1288
po/nb.po

File diff suppressed because it is too large Load Diff

1282
po/nl.po

File diff suppressed because it is too large Load Diff

1186
po/nn.po

File diff suppressed because it is too large Load Diff

1267
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1317
po/ro.po

File diff suppressed because it is too large Load Diff

1265
po/ru.po

File diff suppressed because it is too large Load Diff

1266
po/sl.po

File diff suppressed because it is too large Load Diff

1261
po/sr.po

File diff suppressed because it is too large Load Diff

1285
po/sv.po

File diff suppressed because it is too large Load Diff

1259
po/tr.po

File diff suppressed because it is too large Load Diff

1271
po/uk.po

File diff suppressed because it is too large Load Diff

1268
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 *
@@ -55,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. */
@@ -106,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) {
@@ -170,7 +165,7 @@ char *do_browser(char *path)
#else
say_there_is_no_help();
#endif
} else if (func == do_search) {
} else if (func == do_search_forward) {
do_filesearch();
} else if (func == do_research) {
do_fileresearch(TRUE);
@@ -230,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"));
@@ -251,7 +243,7 @@ char *do_browser(char *path)
sprintf(path, "%s%s", present_path, answer);
}
#ifndef DISABLE_OPERATINGDIR
#ifdef ENABLE_OPERATINGDIR
if (outside_of_confinement(path, FALSE)) {
/* TRANSLATORS: This refers to the confining effect of the
* option --operatingdir, not of --restricted. */
@@ -281,7 +273,7 @@ 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. */
@@ -380,7 +372,7 @@ 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 (outside_of_confinement(path, FALSE))
@@ -490,7 +482,7 @@ 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;
@@ -684,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. */
@@ -776,7 +765,7 @@ 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);

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 *
@@ -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 *
@@ -28,7 +28,16 @@
#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. */
@@ -59,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;
@@ -91,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);
}
}
@@ -125,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;
@@ -175,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);
@@ -210,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;
@@ -222,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 |
@@ -243,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
}
}
@@ -263,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;
@@ -435,4 +433,4 @@ void precalc_multicolorinfo(void)
}
}
#endif /* !DISABLE_COLOR */
#endif /* ENABLE_COLOR */

View File

@@ -129,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;
}
@@ -150,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();
@@ -191,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
@@ -219,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;
@@ -227,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);
@@ -292,7 +289,7 @@ void do_uncut_text(void)
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

@@ -103,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;
@@ -149,7 +149,7 @@ void do_help(void)
margin = 0;
#endif
tabsize = 8;
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
syntaxstr = "nanohelp";
#endif
curs_set(0);
@@ -158,6 +158,7 @@ void do_help(void)
help_init();
inhelp = TRUE;
location = 0;
didfind = 0;
bottombars(MHELP);
wnoutrefresh(bottomwin);
@@ -181,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);
@@ -203,7 +205,7 @@ 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) {
@@ -224,13 +226,11 @@ 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. */
curs_set(didfind == 1 ? 1 : 0);
currmenu = MHELP;
edit_refresh();
@@ -251,12 +251,12 @@ 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)) {
currmenu = oldmenu;
@@ -389,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 "
@@ -403,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 "
@@ -575,7 +575,7 @@ 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;

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 *
@@ -65,25 +65,27 @@ 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 index lands on a tab, and
* this tab starts on an earlier chunk, and the tab ends on this row OR we're
* going forward, then increment the index and recalculate leftedge. */
* 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 ||
*leftedge / tabsize < (*leftedge + editwincols) / tabsize) &&
*leftedge % tabsize != 0 && column < *leftedge + tabsize) {
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++;
*leftedge = leftedge_for(strnlenpt(line->data, index), line);
if (shifted != NULL)
*shifted = TRUE;
}
if (ISSET(SOFTWRAP))
*leftedge = leftedge_for(strnlenpt(line->data, index), line);
#endif
return index;
@@ -94,17 +96,15 @@ size_t proper_x(filestruct *line, size_t *leftedge, bool forward,
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) {
size_t newer_x = actual_x(openfile->current->data, *leftedge + target);
if (newer_x > openfile->current_x)
openfile->current_x = newer_x;
}
if (shifted || *leftedge < was_edge)
openfile->current_x = proper_x(openfile->current, leftedge, forward,
actual_last_column(*leftedge, target), &shifted);
openfile->placewewant = *leftedge + target;
}
@@ -119,9 +119,8 @@ 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;
leftedge = openfile->firstcolumn;
openfile->current_y = 0;
leftedge = leftedge_for(openfile->firstcolumn, openfile->edittop);
target_column = 0;
} else
get_edge_and_target(&leftedge, &target_column);
@@ -150,9 +149,8 @@ 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;
leftedge = openfile->firstcolumn;
openfile->current_y = 0;
leftedge = leftedge_for(openfile->firstcolumn, openfile->edittop);
target_column = 0;
} else
get_edge_and_target(&leftedge, &target_column);
@@ -171,18 +169,18 @@ void do_page_down(void)
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;
@@ -231,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;
@@ -255,7 +253,7 @@ void do_prev_block(void)
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;
@@ -273,9 +271,8 @@ void do_next_block(void)
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;
@@ -317,10 +314,9 @@ void do_prev_word(bool allow_punct, bool update_screen)
edit_redraw(was_current, FLOWING);
}
/* 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;
@@ -332,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;
@@ -424,7 +420,7 @@ void do_home(void)
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". */
@@ -506,7 +502,7 @@ void do_up(bool scroll_only)
set_proper_index_and_pww(&leftedge, target_column, FALSE);
if (scroll_only)
edit_scroll(UPWARD, 1);
edit_scroll(BACKWARD, 1);
edit_redraw(was_current, FLOWING);
@@ -530,7 +526,7 @@ void do_down(bool scroll_only)
set_proper_index_and_pww(&leftedge, target_column, TRUE);
if (scroll_only)
edit_scroll(DOWNWARD, 1);
edit_scroll(FORWARD, 1);
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 *
@@ -71,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
@@ -88,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
@@ -128,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);
@@ -306,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
@@ -368,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;
@@ -412,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;
@@ -445,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
@@ -456,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
@@ -507,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;
@@ -522,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);
}
@@ -561,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
@@ -717,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)
@@ -803,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"));
@@ -821,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))
@@ -844,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"));
@@ -871,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"));
@@ -895,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"));
@@ -926,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
@@ -956,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
@@ -1005,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
@@ -1017,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 */
@@ -1077,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"));
@@ -1397,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;
@@ -1570,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)
@@ -1589,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;
@@ -1627,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
@@ -1639,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)
@@ -1676,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)
@@ -1686,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
@@ -1703,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
@@ -1721,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)
@@ -1765,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);
@@ -1852,9 +1836,9 @@ 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
@@ -1872,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;
@@ -1893,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
@@ -1903,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
@@ -1928,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'},
@@ -1951,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'},
@@ -1994,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. */
@@ -2070,7 +2059,7 @@ int main(int argc, char **argv)
SET(LOCKING);
break;
#endif
#ifndef DISABLE_HISTORIES
#ifdef ENABLE_HISTORIES
case 'H':
SET(HISTORYLOG);
break;
@@ -2094,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;
@@ -2133,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;
@@ -2168,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;
@@ -2177,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;
@@ -2210,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
@@ -2263,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;
@@ -2285,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
@@ -2307,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
@@ -2327,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;
@@ -2354,34 +2344,34 @@ 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
/* If backups are enabled and a backup directory was specified and
@@ -2391,14 +2381,14 @@ int main(int argc, char **argv)
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. */
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, "!.?");
@@ -2422,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);
}
@@ -2463,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)
@@ -2486,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;
@@ -2497,7 +2489,7 @@ 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;
@@ -2573,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. */
@@ -2604,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;
@@ -2643,9 +2638,6 @@ int main(int argc, char **argv)
} 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;

View File

@@ -48,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)
@@ -60,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;
}
@@ -439,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;
@@ -452,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;
@@ -465,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
@@ -487,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;
@@ -504,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);
@@ -521,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
@@ -567,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
@@ -584,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);
@@ -614,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;
@@ -643,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;
@@ -671,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. */
@@ -694,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");
@@ -706,7 +685,6 @@ int do_yesno_prompt(bool all, const char *msg)
while (response == -2) {
int kbinput;
functionptrtype func;
if (!ISSET(NO_HELP)) {
char shortstr[MAXCHARLEN + 2];
@@ -721,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. */
@@ -744,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) {
@@ -764,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)
@@ -779,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;
@@ -81,7 +79,7 @@ extern int shiftaltup;
extern int shiftaltdown;
#endif
#ifndef DISABLE_WRAPJUSTIFY
#ifdef ENABLED_WRAPORJUSTIFY
extern ssize_t fill;
extern ssize_t wrap_at;
#endif
@@ -100,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
@@ -113,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;
@@ -121,7 +117,7 @@ extern char *quotestr;
extern regex_t quotereg;
extern int quoterc;
extern char *quoteerr;
#endif /* !DISABLE_JUSTIFY */
#endif
extern char *word_chars;
@@ -134,17 +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;
#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;
@@ -155,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
@@ -169,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);
@@ -220,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
@@ -228,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
@@ -239,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);
@@ -265,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,
@@ -274,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,
@@ -285,7 +287,7 @@ 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 outside_of_confinement(const char *currpath, bool allow_tabcomp);
#endif
@@ -301,30 +303,17 @@ 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);
@@ -335,7 +324,7 @@ 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
@@ -357,12 +346,32 @@ size_t help_line_len(const char *ptr);
#endif
void do_help_void(void);
/* 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_end(bool update_screen);
void do_para_begin_void(void);
@@ -461,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
@@ -481,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);
@@ -499,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. */
@@ -540,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);
@@ -565,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
@@ -580,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
@@ -589,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,
@@ -624,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);
@@ -651,7 +651,7 @@ 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 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);
@@ -663,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);
@@ -686,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 *
@@ -31,7 +31,7 @@
#ifdef ENABLE_NANORC
#ifndef RCFILE_NAME
#define RCFILE_NAME ".nanorc"
#define RCFILE_NAME "nanorc"
#endif
static const rcoption rcopts[] = {
@@ -39,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},
@@ -60,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
@@ -79,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},
@@ -111,7 +111,7 @@ static const rcoption rcopts[] = {
{"wordbounds", WORD_BOUNDS},
{"wordchars", 0},
#endif
#ifndef DISABLE_COLOR
#ifdef ENABLE_COLOR
{"titlecolor", 0},
{"numbercolor", 0},
{"selectedcolor", 0},
@@ -122,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. */
@@ -138,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);
@@ -162,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. */
@@ -182,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
@@ -221,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)
@@ -344,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
@@ -448,14 +441,6 @@ void parse_binding(char *ptr, bool dobind)
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;
@@ -490,20 +475,12 @@ void parse_binding(char *ptr, bool dobind)
rcfile_error(N_("Sorry, keystroke \"%s\" may not be rebound"), newsc->keystr);
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) {
@@ -527,11 +504,15 @@ void parse_binding(char *ptr, bool dobind)
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))) {
@@ -542,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)
{
@@ -888,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"). */
@@ -951,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;
@@ -1011,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
;
@@ -1022,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)
@@ -1034,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;
@@ -1103,7 +1083,7 @@ 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)
@@ -1118,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"),
@@ -1155,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)) {
@@ -1182,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
@@ -1198,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);
@@ -1225,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
@@ -1236,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. */
@@ -1252,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 *
@@ -28,10 +28,6 @@
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? */
@@ -69,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);
}
@@ -94,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();
@@ -142,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. */
@@ -154,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);
@@ -176,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
}
@@ -216,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);
@@ -287,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,
@@ -302,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;
}
@@ -316,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;
}
@@ -326,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. */
@@ -347,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;
@@ -363,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;
}
@@ -385,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)
@@ -446,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
@@ -454,6 +445,8 @@ 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);
@@ -555,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)) {
@@ -586,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. */
@@ -598,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) ||
@@ -619,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. */
@@ -653,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) {
@@ -694,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))
@@ -712,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();
@@ -755,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);
@@ -792,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();
}
@@ -823,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"));
@@ -1087,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 *
@@ -53,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)
@@ -170,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)
@@ -179,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], "[[:");
@@ -194,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)
@@ -224,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
@@ -481,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)
@@ -513,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;
}
@@ -552,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;
}
}
@@ -563,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 *
@@ -49,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:
*
@@ -109,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. */
@@ -120,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++;
@@ -169,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. */
@@ -285,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);
@@ -962,6 +1029,7 @@ 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. */
@@ -1431,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;
@@ -1524,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)
;
@@ -1553,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)
@@ -1884,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 == ' ') {
@@ -1977,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
@@ -1990,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();
@@ -2015,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");
@@ -2038,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++;
@@ -2051,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. */
@@ -2064,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) -
@@ -2159,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. */
@@ -2252,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++;
}
@@ -2261,27 +2347,24 @@ 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,
@@ -2331,7 +2414,7 @@ void place_the_cursor(void)
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. */
@@ -2341,9 +2424,6 @@ 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. */
@@ -2354,7 +2434,7 @@ void edit_draw(filestruct *fileptr, const char *converted,
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
@@ -2371,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;
@@ -2619,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. */
@@ -2798,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
@@ -2902,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;
@@ -2912,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);
@@ -2935,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
@@ -2951,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
@@ -2982,72 +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. */
while (*text != '\0' && column < leftedge) {
char_len = parse_mbchar(text, NULL, &column);
text += char_len;
}
/* The intention is to use the entire available width. */
goal_column = leftedge + editwincols;
/* First find the place in text where the current chunk starts. */
while (*text != '\0' && column < leftedge)
text += parse_mbchar(text, NULL, &column);
/* 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);
/* 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 we've now overshot the screen's edge, then break there. */
if (lastblank_column > goal_column)
return goal_column;
if (last_blank_col <= goal_column)
return last_blank_col;
return lastblank_column;
/* If it's a tab that overshoots, break at the screen's edge. */
if (*farthest_blank == '\t')
breaking_col = goal_column;
}
/* If a tab is split over two chunks, break at the screen's edge. */
if (*(text - char_len) == '\t')
prev_column = 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,
@@ -3205,7 +3268,7 @@ void edit_redraw(filestruct *old_current, update_type manner)
#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) {
@@ -3236,7 +3299,7 @@ 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();
@@ -3325,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();
@@ -3352,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';
@@ -3504,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
@@ -3590,7 +3650,6 @@ void do_credits(void)
window_init();
}
curs_set(0);
nodelay(edit, TRUE);
blank_titlebar();
@@ -3654,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,7 +1,7 @@
## 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.

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,7 +1,7 @@
## Here is an example for HTML.
syntax "html" "\.html?$"
magic "HTML document text"
magic "HTML document"
comment "<!--|-->"
# Tags:

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,7 +8,7 @@ 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 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:]]*$)"

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 "#"

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: