Compare commits
169 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8d2f552bd | ||
|
|
f2ae08ab19 | ||
|
|
325d774393 | ||
|
|
0856f53703 | ||
|
|
7f0bfdfeb2 | ||
|
|
51371e0ca5 | ||
|
|
3bd66b78c1 | ||
|
|
5ea6054a75 | ||
|
|
04738996fc | ||
|
|
07a9477213 | ||
|
|
a5b48f9a0d | ||
|
|
d141e849a3 | ||
|
|
da68ee19e7 | ||
|
|
8b2f7bd5a2 | ||
|
|
6119756347 | ||
|
|
06c80b6ccd | ||
|
|
7ce1f6d86d | ||
|
|
88087f2b2f | ||
|
|
16c4f5bbd0 | ||
|
|
e877c2406e | ||
|
|
b6a1583e8e | ||
|
|
48df800db3 | ||
|
|
ee05daab92 | ||
|
|
74f4c37d5f | ||
|
|
3f5ba950d6 | ||
|
|
0a52e92d4c | ||
|
|
7c57806c6f | ||
|
|
a2f8703df5 | ||
|
|
073251fdb1 | ||
|
|
5a0ee3c2f9 | ||
|
|
6bd5dce954 | ||
|
|
f25059c244 | ||
|
|
856f2c433e | ||
|
|
38c5a4465b | ||
|
|
f494bfcbb9 | ||
|
|
b856fc4664 | ||
|
|
faa96ead44 | ||
|
|
26444bf8df | ||
|
|
4eaade2938 | ||
|
|
662e8b2d20 | ||
|
|
4502295a34 | ||
|
|
25b0bf0ae8 | ||
|
|
f6b6bc47d6 | ||
|
|
a692b01c04 | ||
|
|
a197ccf12d | ||
|
|
67e5913edf | ||
|
|
e864107046 | ||
|
|
7984ea4eb6 | ||
|
|
f38bd5030d | ||
|
|
a2fea9928d | ||
|
|
c64f506933 | ||
|
|
445cd2a6c5 | ||
|
|
fb073ec88d | ||
|
|
c09e96f294 | ||
|
|
0b54785fe5 | ||
|
|
8835c0d486 | ||
|
|
0442eef95b | ||
|
|
6ae11071b3 | ||
|
|
3c177c1bb9 | ||
|
|
e0213b1a41 | ||
|
|
e70ff87c86 | ||
|
|
db10a421dc | ||
|
|
5725336149 | ||
|
|
b8ba27bbc0 | ||
|
|
e3f6638a76 | ||
|
|
f8553f6d3a | ||
|
|
a78da18aa4 | ||
|
|
d764d7094f | ||
|
|
2651554721 | ||
|
|
fa686457c2 | ||
|
|
a65f0ec80c | ||
|
|
e01e1d8ab5 | ||
|
|
58597b6d9b | ||
|
|
196e913681 | ||
|
|
620553b795 | ||
|
|
6df50790cd | ||
|
|
6cd98e32f7 | ||
|
|
f9baa4de71 | ||
|
|
1cd5005d06 | ||
|
|
f7a3b996fa | ||
|
|
ea874112d8 | ||
|
|
25d397e7b3 | ||
|
|
5111b20bf5 | ||
|
|
f571d6ba36 | ||
|
|
0e21baf611 | ||
|
|
1e78881a70 | ||
|
|
077d307b30 | ||
|
|
998992ddcb | ||
|
|
0ff9499583 | ||
|
|
eb1668ce81 | ||
|
|
54b97a6f03 | ||
|
|
5e48c36877 | ||
|
|
9e3fca4021 | ||
|
|
5130c35b85 | ||
|
|
e01651cde1 | ||
|
|
12cf1c9980 | ||
|
|
092711e412 | ||
|
|
0e6d693dc8 | ||
|
|
aac3126183 | ||
|
|
63cddceeaa | ||
|
|
486d4956ff | ||
|
|
7567a67cdd | ||
|
|
c4939c76a5 | ||
|
|
04e557fdaf | ||
|
|
7dcc8f1d7a | ||
|
|
343f97b3ac | ||
|
|
706f3e93f4 | ||
|
|
f47ef539db | ||
|
|
2148e857e5 | ||
|
|
afa4c6b9fc | ||
|
|
27127853db | ||
|
|
a81ba0215a | ||
|
|
3e0bd533db | ||
|
|
e8d20a8e4b | ||
|
|
6896d8df47 | ||
|
|
8455251c35 | ||
|
|
5cf351913e | ||
|
|
416386edcd | ||
|
|
497f126bb2 | ||
|
|
4687322398 | ||
|
|
99f0265d34 | ||
|
|
7b0b9a12ea | ||
|
|
7d483987ce | ||
|
|
f705a9674b | ||
|
|
3233e9cfe0 | ||
|
|
5a98a51173 | ||
|
|
2eaba21a4c | ||
|
|
9a227de3e7 | ||
|
|
3f57200e10 | ||
|
|
1486f32d42 | ||
|
|
e3edce4e7b | ||
|
|
0e559c5bbc | ||
|
|
edfbfbfd0a | ||
|
|
a4eae770ce | ||
|
|
72e5c15110 | ||
|
|
97c8140cea | ||
|
|
c5b03ca4ae | ||
|
|
c2f2c659d9 | ||
|
|
9364bd6c81 | ||
|
|
baa2be3217 | ||
|
|
12742586e5 | ||
|
|
194620c5f0 | ||
|
|
67d37adf98 | ||
|
|
3f0d2fd5ca | ||
|
|
5b07e5fd1f | ||
|
|
3cae32390d | ||
|
|
1be0285832 | ||
|
|
2867f1bbde | ||
|
|
c4d2bf59fb | ||
|
|
5527883c43 | ||
|
|
ade93ccf25 | ||
|
|
84b305f3f0 | ||
|
|
67b89459d5 | ||
|
|
6d916c6c4a | ||
|
|
87542eeaf1 | ||
|
|
29f2e3181a | ||
|
|
8255696b45 | ||
|
|
fc00e89499 | ||
|
|
55946c15e7 | ||
|
|
2e539e2c97 | ||
|
|
38c286c019 | ||
|
|
56d842258c | ||
|
|
8ed8ab69d5 | ||
|
|
4dcbd40c49 | ||
|
|
72645b160d | ||
|
|
dda1b167c9 | ||
|
|
074cf40409 | ||
|
|
6c09504040 | ||
|
|
4991b3bb1a |
176
ChangeLog
176
ChangeLog
@@ -1,3 +1,179 @@
|
||||
Changes between v4.7 and v4.8:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (166):
|
||||
bindings: allow to bind shifted Meta+letter combinations with Sh-M-X
|
||||
bindings: allow to rebind also ^`, although it is synonymous with ^Space
|
||||
bindings: do not show the Full-Justify keystroke when in View mode
|
||||
bindings: force the first letter in a key name to uppercase
|
||||
build: exclude bracketed pasting from the tiny version
|
||||
build: exclude option '-g' when configured without browser and help
|
||||
build: exclude the escape sequences for F13...F16 from the tiny version
|
||||
build: fix compilation for --enable-{tiny,help,multibuffer}
|
||||
build: restrict the use of --with-slang to together with --enable-tiny
|
||||
bump version numbers and add a news item for the 4.8 release
|
||||
copyright: update the years for significantly changed files
|
||||
copyright: update the years for the FSF
|
||||
display: adjust line and column count upon a resize also when using Slang
|
||||
display: clear the help lines before a briefly shown warning
|
||||
display: don't let a message write over the second help line
|
||||
display: ensure the guiding stripe can be shown when not softwrapping
|
||||
display: exclude a bit of feedback from the tiny version
|
||||
display: show the cursor during suspension also when built with Slang
|
||||
display: skip zero-width characters on a Linux console, to avoid a mess
|
||||
docs: add a FAQ item about a self-compiled nano not reading /etc/nanorc
|
||||
docs: document the new -f/--rcfile option
|
||||
docs: document the new Sh-M-X format for binding <Shift+Meta+letter>
|
||||
docs: for the alternative bindings, rebind ^C only in the main menu
|
||||
docs: improve the description of which rc-files are read during startup
|
||||
docs: mention in the FAQ that auto-indentation is suppressed when pasting
|
||||
docs: mention that -D/--boldtext gets overridden by some nanorc options
|
||||
docs: put the three new behaviors in a bulletted list, to catch the eye
|
||||
docs: stop saying that 'set fill' enables hard-wrapping -- it does not
|
||||
docs: use more generally available arrows in the cheatsheet
|
||||
feedback: ask a clearer question when a valid lock file is encountered
|
||||
feedback: report Ctrl+Alt keystrokes as unbindable
|
||||
feedback: restore a message that can occur in help viewer or file browser
|
||||
files: alert the user afterward when an overwritten file is being edited
|
||||
files: revert the previous commit, as the extra warning is annoying
|
||||
files: warn doubly when the user is about to overwrite an existing file
|
||||
files: write a lock file also for a new file and when the name changed
|
||||
gnulib: update to its current upstream state
|
||||
help: don't waste the last column in the help viewer on narrow terminals
|
||||
help: increase the minimum help-text width from 24 to 32 columns
|
||||
help: prevent double spaces from protruding across the right edge
|
||||
help: when a key description wraps, indent its wrapped part
|
||||
input: consume and ignore the raw escape sequences for F17 to F24
|
||||
input: correct the escape sequence for PageUp/PageDown on Eterm/Urxvt
|
||||
input: Ctrl+arrow is "Esc O x" on Eterm, as on rxvt -- not "Esc o x"
|
||||
input: discard partial sequences that Slang produces for F17 to F24
|
||||
input: do not auto-indent when something is pasted into nano from outside
|
||||
input: don't discard the first keystroke after a resize when using Slang
|
||||
input: filter out Ctrl+Meta keystrokes, as they can never be shortcuts
|
||||
input: ignore bracketed pastes in help viewer and file browser
|
||||
input: ignore modifiers on a VT while executing a macro or a string bind
|
||||
input: prevent unintentional marking of text for shifted Meta keystrokes
|
||||
input: read in an external paste in one go, to allow undoing with one M-U
|
||||
input: recognize the raw escape sequences for F13 to F16 on xterm too
|
||||
locking: accept a minimal amount of data, enough for PID plus username
|
||||
locking: avoid crashing when there is a problem writing the lock file
|
||||
locking: check two magic bytes, to verify that it is a lock file
|
||||
locking: do not write a lock file when in view mode
|
||||
locking: when a lock file is unreadable, open the file itself anyway
|
||||
locking: when finding a lock file at startup, quit when user cancels
|
||||
new feature: allow specifying a custom nanorc file on the command line
|
||||
pasting: retain the mark's position when it was set at the cursor
|
||||
prompt: for a Yes-No-All, accept the first character of an external paste
|
||||
rcfile: do set the meta flag for plain <Meta+ASCII> combinations
|
||||
rcfile: require "bright", "start=", and "end=" to be in lowercase too
|
||||
rcfile: unbind keys by their key code instead of by their key string
|
||||
softwrap: suppress the guiding stripe on unaffected chunks
|
||||
speller: avoid messing up the screen when an unknown locale is used
|
||||
suspension: put in an extra terminal-initialization call for Slang
|
||||
syntax: nanohelp, nanorc: colorize the Sh-M-X format as a valid key name
|
||||
syntax: nanorc: colorize all-lowercase Meta key binds as valid too
|
||||
tweaks: add a little change that was overlooked in the previous commit
|
||||
tweaks: add an error message for something that should never occur
|
||||
tweaks: adjust or reword a few items in the FAQ
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: allocate the lock data only when ready to write them
|
||||
tweaks: avoid analyzing the key string when the target key code is known
|
||||
tweaks: avoid determining the key code from the key string twice
|
||||
tweaks: avoid fiddling with the keybuffer when it's not needed
|
||||
tweaks: comment fully, so that all handled escape sequences are findable
|
||||
tweaks: condense a fragment of code
|
||||
tweaks: condense five more fragments of repetitious code
|
||||
tweaks: condense three comments to one, and do the masking more directly
|
||||
tweaks: condense three fragments of repetitious code
|
||||
tweaks: condense two comments, and reshuffle an #endif
|
||||
tweaks: correct a comment
|
||||
tweaks: correct a couple of comments about escape sequences
|
||||
tweaks: correct the description of what nano writes into the lock file
|
||||
tweaks: delete some fragments of code that have become irrelevant
|
||||
tweaks: do not leak a file descriptor when fdopen() fails
|
||||
tweaks: don't bother including Haiku escape sequences in the tiny version
|
||||
tweaks: don't enable bracketed pasting when not handling such pastes
|
||||
tweaks: drop a message that will never be seen
|
||||
tweaks: drop an unneeded call of keypad() -- we never read from topwin
|
||||
tweaks: drop a pointless suffix from two function names
|
||||
tweaks: elide a function that has become too small for its two calls
|
||||
tweaks: elide a helper function, in preparation for an improvement
|
||||
tweaks: elide an 'if', by moving the relevant code to a better place
|
||||
tweaks: elide a small function, as it's in fact needed just once
|
||||
tweaks: elide a somewhat costly call by remembering some state
|
||||
tweaks: elide a variable, and rename its sister
|
||||
tweaks: elide three checks of a shortcut's meta flag
|
||||
tweaks: ensure that editor name and user name are NUL terminated
|
||||
tweaks: exclude an unneeded fragment of code from the tiny version
|
||||
tweaks: exclude two unneeded fragments of code from the tiny version
|
||||
tweaks: free two strings as soon as they are no longer needed
|
||||
tweaks: frob a couple of indentations and white lines
|
||||
tweaks: fuse two nearly identical functions into a single one
|
||||
tweaks: gather four calls that are always done together into a function
|
||||
tweaks: harmonize the amount of lock data that we read and write
|
||||
tweaks: improve a comment by indirectly referring to the ncurses docs
|
||||
tweaks: in comments, reword "titlebar" and "statusbar" to two words each
|
||||
tweaks: initialize three booleans straightaway, when they are declared
|
||||
tweaks: initialize three more booleans straightaway, at declaration
|
||||
tweaks: judge from the key code itself whether it is a Meta keystroke
|
||||
tweaks: make a couple of comments more precise
|
||||
tweaks: move a function to after the one that it calls
|
||||
tweaks: move a function to be before the ones that call it
|
||||
tweaks: move a function to before the one that calls it
|
||||
tweaks: move a function to related ones, and after one that it calls
|
||||
tweaks: move a function to right before the one that calls it
|
||||
tweaks: move another function to after the one that it calls
|
||||
tweaks: move another function to before the one that calls it
|
||||
tweaks: move another function, to group the deleting ones together
|
||||
tweaks: move three functions to the file where they are mainly used
|
||||
tweaks: rearrange a few global variables, to group things better
|
||||
tweaks: recompute the wrapping point just once
|
||||
tweaks: reduce the scope of a variable, and reshuffle a declaration
|
||||
tweaks: reduce the scope of two constants and of four variables
|
||||
tweaks: reformat a comment, and resuffle a line to match byte order
|
||||
tweaks: remove a feedback message that is never shown
|
||||
tweaks: remove a redundant call, as there is nothing to free there
|
||||
tweaks: remove a superfluous check
|
||||
tweaks: remove some superfluous conditions for rewriting a lock file
|
||||
tweaks: remove the now-unneeded code related to bracketed pasting
|
||||
tweaks: remove the now-unused meta flag from 'keystruct'
|
||||
tweaks: remove two superfluous assignments, and rename a variable
|
||||
tweaks: rename a function and its parameter, to be more fitting
|
||||
tweaks: rename a function, to be a bit more expressive
|
||||
tweaks: rename a function, to make it not contain the name of another
|
||||
tweaks: rename a parameter and invert its logic, and correct a comment
|
||||
tweaks: rename five variables, away from a single letter
|
||||
tweaks: rename two functions, to make more sense
|
||||
tweaks: rename two parameters, to be more general and to sound shorter
|
||||
tweaks: rename two variables, to make more sense
|
||||
tweaks: renumber some FAQ items in preparation for adding another
|
||||
tweaks: reorder two symbols
|
||||
tweaks: reshuffle some assignments for a return value
|
||||
tweaks: reshuffle some declarations
|
||||
tweaks: reshuffle some declarations, and expand a few variable names
|
||||
tweaks: reshuffle some lines, to avoid tallying the menus when not needed
|
||||
tweaks: reshuffle some lines, to group all ignored keystrokes together
|
||||
tweaks: reshuffle three lines, to make the grouping tighther
|
||||
tweaks: reshuffle two lines, to do the linking first, then the content
|
||||
tweaks: reword two comments, and rewrap another
|
||||
tweaks: rewrap a comment and a line, and reshuffle a fragment of code
|
||||
tweaks: rewrap two lines, for consistency with similar lines
|
||||
tweaks: rewrite the same file name into the lock file as the first time
|
||||
tweaks: slightly condense a function by conflating case
|
||||
tweaks: stop recognizing escape sequences for a key without meaning
|
||||
tweaks: suggest a few more alternative key bindings and unbindings
|
||||
tweaks: take just one shot at reading the lock file, and correct a type
|
||||
tweaks: trim some excessive error checking and key-name frobbing
|
||||
tweaks: tumble three conditions, for consistency in comparisons
|
||||
tweaks: unabbreviate "argument" in the documentation
|
||||
tweaks: use a simple subtraction instead of a function call
|
||||
usage: improve the description of --restricted and --quickblank
|
||||
|
||||
Brand Huntsman (2):
|
||||
input: beep when invalid key is pressed at yesno prompt or in linter menu
|
||||
input: recognize the start and stop sequences of a bracketed paste
|
||||
|
||||
|
||||
Changes between v4.6 and v4.7:
|
||||
------------------------------
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@ Improvements in GNU nano
|
||||
========================
|
||||
|
||||
Since 4.0:
|
||||
- Pasting from outside into nano suppresses auto-indentation.
|
||||
- Such an external paste can be undone with a single M-U.
|
||||
- Shift+Meta+letter key combos can be bound with 'bind Sh-M-letter ...'.
|
||||
- A custom nanorc file may be specified with -f / --rcfile.
|
||||
- What the <Tab> key produces can be specified per syntax with 'tabgives'.
|
||||
- The ability to perform a search at startup with +/string or +?string.
|
||||
- Comment characters are copied when automatic hard-wrapping occurs.
|
||||
|
||||
13
NEWS
13
NEWS
@@ -1,3 +1,16 @@
|
||||
2020.02.07 - GNU nano 4.8 "Jaška"
|
||||
• When something is pasted into nano, auto-indentation is suppressed,
|
||||
and the paste can be undone as a whole with a single M-U.
|
||||
• When a lock file is encountered during startup, pressing ^C/Cancel
|
||||
quits nano. (Pressing 'No' just skips the file and continues.)
|
||||
• Shift+Meta+letter key combos can be bound with 'bind Sh-M-letter'.
|
||||
Making any such binding dismisses the default behavior of ignoring
|
||||
Shift for all Meta+letter keystrokes.
|
||||
• The configuration option --with-slang (to be avoided when possible)
|
||||
can now be used only together with --enable-tiny.
|
||||
• A custom nanorc file can be specified on the command line, with
|
||||
-f filename or --rcfile=filename.
|
||||
|
||||
2019.12.23 - GNU nano 4.7 "Havikskruid"
|
||||
• A <Tab> will indent a marked region only when mark and cursor are
|
||||
on different lines.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="129087dbb4f8721d750d2ec58261c56b2bda2536"
|
||||
gnulib_hash="e313a5367b1e4edfa19ab5f0d001d0b060a77066"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
11
configure.ac
11
configure.ac
@@ -1,6 +1,6 @@
|
||||
# Configuration for GNU nano - a small and user-friendly text editor
|
||||
#
|
||||
# Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2014, 2017 Mike Frysinger
|
||||
#
|
||||
# GNU nano is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
AC_INIT([GNU nano], [4.7], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [4.8], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.14])
|
||||
@@ -89,6 +89,12 @@ AC_CHECK_HEADERS(libintl.h limits.h pwd.h termios.h sys/param.h)
|
||||
|
||||
dnl Checks for options.
|
||||
|
||||
if test "x$with_slang" = xyes; then
|
||||
if test "x$enable_tiny" != xyes; then
|
||||
AC_MSG_ERROR([--with-slang is supported only together with --enable-tiny])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(browser,
|
||||
AS_HELP_STRING([--disable-browser], [Disable the built-in file browser]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
@@ -516,7 +522,6 @@ int main(void)
|
||||
;;
|
||||
esac], [AC_MSG_RESULT(no)])
|
||||
|
||||
|
||||
dnl Checks for functions.
|
||||
|
||||
if test "x$enable_utf8" != xno; then
|
||||
|
||||
@@ -79,14 +79,14 @@
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+B </td><td>One character backward</td></tr>
|
||||
<tr><td>Ctrl+F</td><td>One character forward</td></tr>
|
||||
<tr><td>Ctrl+⯇</td><td>One word backward</td></tr>
|
||||
<tr><td>Ctrl+⯈</td><td>One word forward</td></tr>
|
||||
<tr><td>Ctrl+<b>←</b></td><td>One word backward</td></tr>
|
||||
<tr><td>Ctrl+<b>→</b></td><td>One word forward</td></tr>
|
||||
<tr><td>Ctrl+A</td><td>To start of line</td></tr>
|
||||
<tr><td>Ctrl+E</td><td>To end of line</td></tr>
|
||||
<tr><td>Ctrl+P</td><td>One line up</td></tr>
|
||||
<tr><td>Ctrl+N</td><td>One line down</td></tr>
|
||||
<tr><td>Ctrl+⯅</td><td>To previous block</td></tr>
|
||||
<tr><td>Ctrl+⯆</td><td>To next block</td></tr>
|
||||
<tr><td>Ctrl+<b>↑</b></td><td>To previous block</td></tr>
|
||||
<tr><td>Ctrl+<b>↓</b></td><td>To next block</td></tr>
|
||||
<tr><td>Ctrl+Y</td><td>One page up</td></tr>
|
||||
<tr><td>Ctrl+V</td><td>One page down</td></tr>
|
||||
<tr><td>Alt+\</td><td>To top of buffer</td></tr>
|
||||
@@ -98,8 +98,8 @@
|
||||
<table><tbody>
|
||||
<tr><td>Alt+G </td><td>Go to specified line</td></tr>
|
||||
<tr><td>Alt+]</td><td>Go to complementary bracket</td></tr>
|
||||
<tr><td>Alt+⯅</td><td>Scroll viewport up</td></tr>
|
||||
<tr><td>Alt+⯆</td><td>Scroll viewport down</td></tr>
|
||||
<tr><td>Alt+<b>↑</b></td><td>Scroll viewport up</td></tr>
|
||||
<tr><td>Alt+<b>↓</b></td><td>Scroll viewport down</td></tr>
|
||||
<tr><td>Alt+<</td><td>Switch to preceding buffer</td></tr>
|
||||
<tr><td>Alt+></td><td>Switch to succeeding buffer</td></tr>
|
||||
</tbody></table>
|
||||
|
||||
49
doc/faq.html
49
doc/faq.html
@@ -31,11 +31,12 @@
|
||||
<a href="#3.1">3.1. How do I install the RPM or DEB package?</a><br>
|
||||
<a href="#3.2">3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</a><br>
|
||||
<a href="#3.3">3.3. Why does everything go into /usr/local?</a><br>
|
||||
<a href="#3.5">3.5. nano should automatically run strip on the binary when installing it!</a><br>
|
||||
<a href="#3.6">3.6. How can I make the executable smaller? This is too bloated!</a><br>
|
||||
<a href="#3.7">3.7. Tell me more about this multibuffer stuff!</a><br>
|
||||
<a href="#3.8">3.8. Tell me more about this verbatim input stuff!</a><br>
|
||||
<a href="#3.9">3.9. How do I make a .nanorc file that nano will read when I start it?</a><br>
|
||||
<a href="#3.4">3.4. nano should automatically run strip on the binary when installing it!</a><br>
|
||||
<a href="#3.5">3.5. How can I make the executable smaller? This is too bloated!</a><br>
|
||||
<a href="#3.6">3.6. Tell me more about this multibuffer stuff!</a><br>
|
||||
<a href="#3.7">3.7. Tell me more about this verbatim input stuff!</a><br>
|
||||
<a href="#3.8">3.8. How do I make a .nanorc file that nano will read when I start it?</a><br>
|
||||
<a href="#3.9">3.9. Why does my self-compiled nano not read /etc/nanorc?</a><br>
|
||||
</p></blockquote>
|
||||
<h3><a href="#4">4. Running</a></h3>
|
||||
<blockquote><p>
|
||||
@@ -88,7 +89,7 @@
|
||||
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
|
||||
<blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program "establishes a full duplex terminal connection to a remote host", and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote>
|
||||
<h3><a name="1.4"></a>1.4. What is the current version of nano?</h3>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>4.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>4.8</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<h3><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h3>
|
||||
<blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/latest/nano.1.html">here</a>.</p></blockquote>
|
||||
<hr width="100%">
|
||||
@@ -97,8 +98,8 @@
|
||||
<h3><a name="2.1"></a>2.1. Web sites that carry nano.</h3>
|
||||
<blockquote><p>The nano source tarballs can be downloaded from the following web sites:</p>
|
||||
<ul>
|
||||
<li><a href="https://nano-editor.org/dist/">https://nano-editor.org/dist/</a></li>
|
||||
<li><a href="https://ftp.gnu.org/gnu/nano/">https://ftp.gnu.org/gnu/nano/</a></li>
|
||||
<li><a href="https://nano-editor.org/dist/latest/">https://nano-editor.org/dist/latest/</a></li>
|
||||
<li><a href="https://ftpmirror.gnu.org/gnu/nano/">https://ftpmirror.gnu.org/gnu/nano/</a></li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<h3><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h3>
|
||||
@@ -136,10 +137,10 @@
|
||||
<h3><a name="3.3"></a>3.3. Why does everything go into /usr/local?</h3>
|
||||
<blockquote><p>Well, that's what the <b>configure</b> script defaults to. If you wish to change this, simply do this:</p>
|
||||
<p><b>./configure --prefix=/usr</b></p>
|
||||
<p>to put nano into /usr/bin when you run <b>make install</b>.</p></blockquote>
|
||||
<h3><a name="3.5"></a>3.5. nano should automatically run strip on the binary when installing it!</h3>
|
||||
<blockquote><p>Actually, it does, but you have to use <b>make install-strip</b>. The default make install does not, and will not, run strip automatically.</p></blockquote>
|
||||
<h3><a name="3.6"></a>3.6. How can I make the executable smaller? This is too bloated!</h3>
|
||||
<p>This will put nano into /usr/bin when you run <b>make install</b>.</p></blockquote>
|
||||
<h3><a name="3.4"></a>3.4. nano should automatically run strip on the binary when installing it!</h3>
|
||||
<blockquote><p>It does when you use <b>make install-strip</b>. The default <b>make install</b> does not, and will not, run strip automatically.</p></blockquote>
|
||||
<h3><a name="3.5"></a>3.5. How can I make the executable smaller? This is too bloated!</h3>
|
||||
<blockquote><p>Actually, there are several parts of the editor that can be disabled. You can pass arguments to the <b>configure</b> script that disable certain features. Here's a brief list:</p>
|
||||
<pre>
|
||||
<b>--disable-browser</b> Disable the built-in file browser
|
||||
@@ -159,26 +160,28 @@
|
||||
<b>--disable-tabcomp</b> Disable the tab-completion functions
|
||||
<b>--disable-wordcomp</b> Disable the word-completion function
|
||||
<b>--disable-wrapping</b> Disable all hard-wrapping of text</pre>
|
||||
<p>There's also the <b>--enable-tiny</b> option which disables everything above, as well as some larger chunks of the program (like the marker code that you use with Control-^ to select text). Also, if you know you aren't going to be using other languages, you can use <b>--disable-nls</b> to disable internationalization and save a few K to a few dozen K depending on whether you have locale support on your system. And finally, there's always good old <b>strip</b> to strip all debugging code and code that exists in libraries on your system.</p>
|
||||
<p>There's also the <b>--enable-tiny</b> option which disables everything above, as well as some larger chunks of the program (like the undo/redo code and the code for selecting text). Also, if you know you don't need other languages, you can use <b>--disable-nls</b> to disable internationalization and save a few kilobytes. And finally, there's always good old <b>strip</b> to remove all unneeded symbols.</p>
|
||||
</blockquote>
|
||||
<h3><a name="3.7"></a>3.7. Tell me more about this multibuffer stuff!</h3>
|
||||
<h3><a name="3.6"></a>3.6. Tell me more about this multibuffer stuff!</h3>
|
||||
<blockquote><p>To use multiple file buffers, you must not have configured nano with <b>--disable-multibuffer</b> nor with <b>--enable-tiny</b> (use <b>nano -V</b> to check the compilation options). Then when you want to insert a file into its own buffer instead of into the current file, just hit <b>Meta-F</b> after typing <b>^R</b>. If you always want files to be loaded into their own buffers, use the <b>-F</b> or <b>--multibuffer</b> flag when you invoke nano, or add <b>set multibuffer</b> to your .nanorc file.</p>
|
||||
<p>You can move between the buffers you have open with the <b>Meta-<</b> and <b>Meta-></b> keys, or more easily without holding Shift: <b>Meta-,</b> and <b>Meta-.</b> (clear as mud, right? =-). When you have more than one buffer open, the ^X shortcut will say "Close", instead of "Exit".</p></blockquote>
|
||||
<h3><a name="3.8"></a>3.8. Tell me more about this verbatim input stuff!</h3>
|
||||
<h3><a name="3.7"></a>3.7. Tell me more about this verbatim input stuff!</h3>
|
||||
<blockquote><p>When you want to insert a literal character into the file you're editing, such as a control character that nano usually treats as a command, first press <b>Meta-V</b> (if you're not at a prompt, you'll get the message "Verbatim Input" on the status bar), then press the key(s) that generate the character you want.</p>
|
||||
<p>Alternatively, if Unicode support is enabled (see section <a href="#5.3">5.3</a>), you can press <b>Meta-V</b> and then type a six-digit hexadecimal code (from 000000 to 10FFFF, case-insensitive), and the character with the corresponding value will be inserted. The status bar will change to "Unicode Input: ......" when you do this.</p></blockquote>
|
||||
<h3><a name="3.9"></a>3.9. How do I make a .nanorc file that will be read when I start nano?</h3>
|
||||
<blockquote><p>It's not hard at all! But, your nano must <b>not</b> have been compiled with <b>--disable-nanorc</b>. Then simply copy the <b>sample.nanorc</b> that came with the nano source or your nano package (most likely in /usr/doc/nano) to .nanorc in your home directory. If you didn't get one, the syntax of the file is simple. Flags are turned on and off by using the words <b>set</b> and <b>unset</b> plus the long option name for the feature. For example, "set nowrap" or "set smarthome".</p></blockquote>
|
||||
<h3><a name="3.8"></a>3.8. How do I make a .nanorc file that will be read when I start nano?</h3>
|
||||
<blockquote><p>It's not hard at all! Simply copy the <b>sample.nanorc</b> from the doc/ directory in the nano source package (or from /usr/doc/nano on your system) to <b>.nanorc</b> in your home directory, and then edit it. If you didn't get a sample nanorc, the syntax of the file is simple: features are turned on and off by using the words <b>set</b> and <b>unset</b> followed by the long option name of the feature (see <b>man nanorc</b> for the full list of options). For example, "set quickblank" or "set smarthome". Of course, for this to work, your nano must <b>not</b> have been compiled with <b>--disable-nanorc</b>.</p></blockquote>
|
||||
<h3><a name="3.9"></a>3.9. Why does my self-compiled nano not read /etc/nanorc?</h3>
|
||||
<blockquote><p>By default (see <a href="#3.3">3.3</a>), nano gets installed into /usr/local. This also means that, at startup, nano will read <b>/usr/local/etc/nanorc</b> instead of <b>/etc/nanorc</b>. You can make a symlink from the former to the latter if you want your self-compiled nano to read the same nanorc as the system-installed nano. Or you can configure your nano to overwrite the system nano (again, see <a href="#3.3">3.3</a>).</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="4"></a>4. Running</h1>
|
||||
<h3><a name="4.1"></a>4.1. How do I open a file with a name beginning with '+' from the command line?</h3>
|
||||
<blockquote><p>If a command-line option that begins with '+' is followed by another option, the former is always treated as a starting line and column number, and the latter is always treated as a filename. If a command-line option that begins with '+' isn't followed by another option, it's always treated as a filename. Examples:</p>
|
||||
<p>To open '+filename.txt' starting on line 1: <b>nano +filename.txt</b><br>
|
||||
<blockquote><p>If a command-line argument that begins with '+' is followed by another argument, the former is always treated as a starting line (plus column number), and the latter always as a filename. If a command-line argument that begins with '+' isn't followed by another argument, it's treated as a filename. Examples:</p>
|
||||
<p>To open '+filename.txt': <b>nano +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 10: <b>nano +10 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 1, column 20: <b>nano +,20 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 10, column 20: <b>nano +10,20 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 1 and 'filename.txt' starting on line 40 (if nano has been compiled with multibuffer support): <b>nano +1 +filename.txt +40 filename.txt</b></p></blockquote>
|
||||
To open '+filename.txt' starting on line 1 and 'filename.txt' starting on line 40: <b>nano +1 +filename.txt +40 filename.txt</b></p></blockquote>
|
||||
<h3><a name="4.2"></a>4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</h3>
|
||||
<blockquote><p>Try setting your $TERM variable to 'vt100'. nano doesn't yet support every term entry under the sun.</p>
|
||||
<p>Bourne shell users (bash and sh): <b>export TERM=vt100</b><br>
|
||||
@@ -190,9 +193,11 @@
|
||||
<h3><a name="4.5"></a>4.5. How do I select text for or paste text from the clipboard when nano's mouse support is turned on?</h3>
|
||||
<blockquote><p>Try holding down the Shift key and selecting or pasting the text as you normally would.</p></blockquote>
|
||||
<h3><a name="4.6"></a>4.6. When I paste text into a document, each line gets indented further than the last. Why? And how can I stop this?</h3>
|
||||
<blockquote><p>You have the <i>autoindent</i> feature turned on. Hit <b>Meta-I</b> to turn it off, paste your text, and then hit <b>Meta-I</b> again to turn it back on.</p></blockquote>
|
||||
<blockquote><p>You have the <i>autoindent</i> feature turned on. Hit <b>Meta-I</b> to turn it off, paste your text, and then hit <b>Meta-I</b> again to turn it back on.</p>
|
||||
<p><i>Update:</i> Since version 4.8, nano will suppress auto-indentation during a paste, so you no longer need to toggle it off and on manually.</p></blockquote>
|
||||
<h3><a name="4.7"></a>4.7. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</h3>
|
||||
<blockquote><p>When pasting from Windows, in some situations linefeeds are sent instead of carriage returns (Enters). And linefeeds are <b>^J</b>s, which make nano justify (rewrap) the current paragraph. To prevent these linefeeds from causing these unwanted justifications, add this line to your .nanorc on the remote Linux box: <b>unbind ^J main</b> or <b>bind ^J enter main</b>, depending on whether the paste contains CR + LF or only LF.</p></blockquote>
|
||||
<blockquote><p>When pasting from Windows, in some situations linefeeds are sent instead of carriage returns (Enters). And linefeeds are <b>^J</b>s, which make nano justify (rewrap) the current paragraph. To prevent these linefeeds from causing these unwanted justifications, add this line to your .nanorc on the remote Linux box: <b>unbind ^J main</b> or <b>bind ^J enter main</b>, depending on whether the paste contains CR + LF or only LF.</p>
|
||||
<p><i>Update:</i> Since version 4.8, nano will ignore linefeed characters in a paste, so you no longer need the above workaround.</p></blockquote>
|
||||
<h3><a name="4.8"></a>4.8. I've compiled nano with color support, but I don't see any color when I run it!</h3>
|
||||
<blockquote><p>If you want nano to actually use color, you have to specify the color configurations you want it to use in your .nanorc. Several example configurations are in the <b>syntax/</b> subdirectory of the nano source, which are normally installed to <b>/usr/local/share/nano/</b>. To enable all of them, uncomment the line <b># include "/usr/local/share/nano/*.nanorc"</b> in your nanorc. See also section <a href="#3.9">3.9</a>.</p></blockquote>
|
||||
<h3><a name="4.9"></a>4.9. How do I make nano my default editor (in Pine, mutt, etc.)?</h3>
|
||||
|
||||
31
doc/nano.1
31
doc/nano.1
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 4.7" "December 2019"
|
||||
.TH NANO 1 "version 4.8" "February 2020"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, inspired by Pico
|
||||
@@ -28,12 +28,18 @@ nano \- Nano's ANOther editor, inspired by Pico
|
||||
.BR nano " [" \fIoptions "] [[" + [ crCR ]( / | ? ) \fIstring "] " \fIfile ]...
|
||||
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
line by default. It further uses smooth scrolling by default, and by
|
||||
default includes the line below the title bar into the editing area.
|
||||
Since version 4.0, \fBnano\fR by default:
|
||||
.sp
|
||||
.RS 4
|
||||
\(bu does not automatically hard-wrap lines that become overlong,
|
||||
.br
|
||||
\(bu includes the line below the title bar in the editing area,
|
||||
.br
|
||||
\(bu does linewise (smooth) scrolling.
|
||||
.RE
|
||||
.sp
|
||||
If you want the old, Pico behavior back, you can use \fB\-\-breaklonglines\fR,
|
||||
\fB\-\-jumpyscrolling\fR, and \fB\-\-emptyline\fR (or \fB\-bje\fR for short).
|
||||
\fB\-\-emptyline\fR, and \fB\-\-jumpyscrolling\fR (or \fB\-bej\fR for short).
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBnano\fP is a small and friendly editor. It copies the look and feel
|
||||
@@ -106,7 +112,10 @@ 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.
|
||||
.TP
|
||||
.BR \-D ", " \-\-boldtext
|
||||
Use bold text instead of reverse video text.
|
||||
For the interface, use bold instead of reverse video. This will be overridden
|
||||
by setting the options \fBtitlecolor\fP, \fBstatuscolor\fP, \fBkeycolor\fP,
|
||||
\fBfunctioncolor\fP, \fBnumbercolor\fP, and/or \fBselectedcolor\fP in your
|
||||
nanorc file. See \fBnanorc\fR(5).
|
||||
.TP
|
||||
.BR \-E ", " \-\-tabstospaces
|
||||
Convert typed tabs to spaces.
|
||||
@@ -226,6 +235,10 @@ system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
.BR \-e ", " \-\-emptyline
|
||||
Do not use the line below the title bar, leaving it entirely blank.
|
||||
.TP
|
||||
.BR \-f\ \fIfile ", " \-\-rcfile= \fIfile
|
||||
Read only this \fIfile\fR for setting nano's options, instead of reading
|
||||
both the system-wide and the user's nanorc files.
|
||||
.TP
|
||||
.BR \-g ", " \-\-showcursor
|
||||
Make the cursor visible in the file browser (putting it on the
|
||||
highlighted item) and in the help viewer. Useful for braille users
|
||||
@@ -278,7 +291,7 @@ at the width of the screen minus \fInumber\fR columns, allowing the wrap
|
||||
point to vary along with the width of the screen if the screen is resized.
|
||||
The default value is \-8.
|
||||
.TP
|
||||
.B "\-s ""\fIprogram\fR [\fIarg\fR...]\fB""\fR, \fB\-\-speller=""\fIprogram\fR [\fIarg\fR...]\fB"""
|
||||
.B "\-s ""\fIprogram\fR [\fIargument \fR...]\fB""\fR, \fB\-\-speller=""\fIprogram\fR [\fIargument \fR...]\fB"""
|
||||
Use this command to perform spell checking and correcting, instead of
|
||||
using the built-in corrector that calls \fBhunspell\fR or GNU \fBspell\fR.
|
||||
.TP
|
||||
@@ -327,6 +340,8 @@ hard-wrapping of long lines, \fBM\-S\fR toggles soft-wrapping,
|
||||
See at the end of the \fB^G\fR help text for a complete list.
|
||||
|
||||
.SH FILES
|
||||
When \fB\-\-rcfile\fR is given, \fBnano\fR will read just the specified file
|
||||
for setting its options and syntaxes and key bindings. Without that option,
|
||||
\fBnano\fR will read two configuration files: first the system's
|
||||
\fInanorc\fR (if it exists), and then the user's \fInanorc\fR (if it
|
||||
exists), either \fI~/.nanorc\fR or \fI$XDG_CONFIG_HOME/nano/nanorc\fR
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 4.7
|
||||
@set UPDATED December 2019
|
||||
@set VERSION 4.8
|
||||
@set UPDATED February 2020
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 4.7
|
||||
@subtitle version 4.8
|
||||
|
||||
@author Chris Allegretta
|
||||
@page
|
||||
@@ -33,7 +33,7 @@ This manual documents the GNU @command{nano} editor.
|
||||
This manual is part of the GNU @command{nano} distribution.@*
|
||||
|
||||
@sp 4
|
||||
Copyright @copyright{} 1999-2009, 2014-2019 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1999-2009, 2014-2020 Free Software Foundation, Inc.
|
||||
|
||||
@sp 1
|
||||
This document is dual-licensed. You may distribute and/or modify it
|
||||
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
|
||||
@node Top
|
||||
@top
|
||||
|
||||
This manual documents the GNU @command{nano} editor, version 4.7.
|
||||
This manual documents the GNU @command{nano} editor, version 4.8.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@@ -186,7 +186,10 @@ The uniquely numbered files are stored in the specified directory.
|
||||
|
||||
@item -D
|
||||
@itemx --boldtext
|
||||
Use bold text instead of reverse video text.
|
||||
For the interface, use bold instead of reverse video. This will be overridden
|
||||
by setting the options @code{titlecolor}, @code{statuscolor}, @code{keycolor},
|
||||
@code{functioncolor}, @code{numbercolor}, and/or @code{selectedcolor} in your
|
||||
nanorc file. @xref{@code{set functioncolor}} for details.
|
||||
|
||||
@item -E
|
||||
@itemx --tabstospaces
|
||||
@@ -334,6 +337,11 @@ system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
@itemx --emptyline
|
||||
Do not use the line below the title bar, leaving it entirely blank.
|
||||
|
||||
@item -f @var{file}
|
||||
@itemx --rcfile=@var{file}
|
||||
Read only this @var{file} for setting nano's options, instead of reading
|
||||
both the system-wide and the user's nanorc files.
|
||||
|
||||
@item -g
|
||||
@itemx --showcursor
|
||||
Make the cursor visible in the file browser (putting it on the
|
||||
@@ -398,8 +406,8 @@ point to vary along with the width of the screen if the screen is resized.
|
||||
The default value is @t{-8}.
|
||||
|
||||
@anchor{@option{--speller}}
|
||||
@item -s "@var{program} [@var{arg} @dots{}]"
|
||||
@itemx --speller="@var{program} [@var{arg} @dots{}]"
|
||||
@item -s "@var{program} [@var{argument} @dots{}]"
|
||||
@itemx --speller="@var{program} [@var{argument} @dots{}]"
|
||||
Use the given program to do spell checking and correcting. By default,
|
||||
@command{nano} uses the command specified in the @env{SPELL} environment
|
||||
variable. If @env{SPELL} is not set, and @option{--speller} is
|
||||
@@ -434,7 +442,6 @@ This is the default. (This option is the opposite of @option{-b}
|
||||
(@option{--breaklonglines}) --- the last one given takes effect.)
|
||||
|
||||
|
||||
@anchor{Expert Mode}
|
||||
@item -x
|
||||
@itemx --nohelp
|
||||
Expert Mode: don't show the Shortcut List at the bottom of the screen.
|
||||
@@ -685,10 +692,13 @@ The following global toggles are available:
|
||||
|
||||
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,
|
||||
if @option{--rcfile} is not given, @command{nano} will read two files:
|
||||
first the system-wide settings, from @file{/etc/nanorc} (the exact path
|
||||
might be different on your system), and then the user-specific settings,
|
||||
either from @file{~/.nanorc} or from @file{$XDG_CONFIG_HOME/nano/nanorc}
|
||||
or from @file{.config/nano/nanorc}, whichever exists first.
|
||||
If @option{--rcfile} is given, @command{nano} will read just the
|
||||
specified settings file.
|
||||
|
||||
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
|
||||
@@ -748,9 +758,9 @@ The uniquely numbered files are stored in the specified directory.
|
||||
|
||||
@item set boldtext
|
||||
Use bold instead of reverse video for the title bar, status bar, key combos,
|
||||
function tags, line numbers, and selected text. This can be overridden by
|
||||
function tags, line numbers, and selected text. This is overridden by
|
||||
setting the options @code{titlecolor}, @code{statuscolor}, @code{keycolor},
|
||||
@code{functioncolor}, @code{numbercolor}, and @code{selectedcolor}.
|
||||
@code{functioncolor}, @code{numbercolor}, and/or @code{selectedcolor}.
|
||||
|
||||
@item set brackets "@var{characters}"
|
||||
Set the characters treated as closing brackets when justifying
|
||||
@@ -927,7 +937,7 @@ When needed, use @code{unset jumpyscrolling} instead.
|
||||
@item set softwrap
|
||||
Enable soft line wrapping for easier viewing of very long lines.
|
||||
|
||||
@item set speller "@var{program} [@var{arg} @dots{}]"
|
||||
@item set speller "@var{program} [@var{argument} @dots{}]"
|
||||
Use the given program to do spell checking and correcting.
|
||||
@xref{@option{--speller}} for details.
|
||||
|
||||
@@ -1050,13 +1060,13 @@ file, to determine whether this syntax should be used for it.
|
||||
(This functionality only works when @code{libmagic} is installed
|
||||
on the system and will be silently ignored otherwise.)
|
||||
|
||||
@item formatter @var{program} [@var{arg} @dots{}]
|
||||
@item formatter @var{program} [@var{argument} @dots{}]
|
||||
Run the given @var{program} on the full contents of the current buffer.
|
||||
(The current buffer is written out to a temporary file, the program is
|
||||
run on it, and then the temporary file is read back in, replacing the
|
||||
contents of the buffer.)
|
||||
|
||||
@item linter @var{program} [@var{arg} @dots{}]
|
||||
@item linter @var{program} [@var{argument} @dots{}]
|
||||
Use the given @var{program} to do a syntax check on the current buffer.
|
||||
|
||||
@item comment "@var{string}"
|
||||
@@ -1109,10 +1119,11 @@ Read in self-contained color syntaxes from "syntaxfile". Note that
|
||||
"syntaxfile" may contain only the above commands, from @code{syntax}
|
||||
to @code{icolor}.
|
||||
|
||||
@item extendsyntax @var{name} @var{command} [@var{arg} @dots{}]
|
||||
@item extendsyntax @var{name} @var{command} @var{argument} @dots{}
|
||||
Extend the syntax previously defined as "@var{name}" with another @var{command}.
|
||||
This allows you to add a new @code{color}, @code{icolor}, @code{header},
|
||||
@code{magic}, @code{comment}, @code{linter}, or @code{formatter} command to an already
|
||||
@code{magic}, @code{formatter}, @code{linter}, @code{comment},
|
||||
or @code{tabgives} command to an already
|
||||
defined syntax --- useful when you want to slightly improve a syntax defined
|
||||
in one of the system-installed files (which normally are not writable).
|
||||
|
||||
@@ -1155,7 +1166,14 @@ Example: @code{^C}.
|
||||
@item
|
||||
@code{M-@var{X}} ------ where @var{X} is any ASCII character except [,
|
||||
or the word "Space".
|
||||
Example: @code{M-C}.
|
||||
Example: @code{M-8}.
|
||||
|
||||
@item
|
||||
@code{Sh-M-@var{X}} ------ where @var{X} is a Latin letter.
|
||||
Example: @code{Sh-M-U}.
|
||||
By default, each Meta+letter keystroke does the same as the corresponding
|
||||
Shift+Meta+letter. But when any Shift+Meta bind is made, that will
|
||||
no longer be the case, for all letters.
|
||||
|
||||
@item
|
||||
@code{F@var{n}} ------ where @var{n} is a numeric value from 1 to 24.
|
||||
@@ -1600,7 +1618,7 @@ whereas Pico does it at screen width minus six columns. You can make
|
||||
By default, @command{nano} will scroll just one line (instead of half
|
||||
a screen) when the cursor is moved to a line that is just out of view.
|
||||
And when paging up or down, @command{nano} keeps the cursor in the same
|
||||
screen position as much as possible, instead always placing it on the
|
||||
screen position as much as possible, instead of always placing it on the
|
||||
first line of the viewport. The Pico-like behavior can be obtained
|
||||
with the @option{--jumpyscrolling} option.
|
||||
|
||||
|
||||
57
doc/nanorc.5
57
doc/nanorc.5
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 2003-2011, 2013-2019 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 2003-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,27 +16,36 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 4.7" "December 2019"
|
||||
.TH NANORC 5 "version 4.8" "February 2020"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
line by default. It further uses smooth scrolling by default, and by
|
||||
default includes the line below the title bar into the editing area.
|
||||
.sp
|
||||
If you want the old, Pico behavior back, you can use \fBset breaklonglines\fR,
|
||||
\fBset jumpyscrolling\fR, and \fBset emptyline\fR.
|
||||
|
||||
.SH DESCRIPTION
|
||||
The \fInanorc\fP file contains the default settings for \fBnano\fP, a
|
||||
small and friendly editor. The file should be in Unix format, not in
|
||||
DOS or Mac format. During startup, \fBnano\fP will first read the
|
||||
The \fInanorc\fP files contain the default settings for \fBnano\fP, a
|
||||
small and friendly editor. They should be in Unix format, not in
|
||||
DOS or Mac format. During startup, if \fB\-\-rcfile\fR is not given,
|
||||
\fBnano\fR will read two files: first the
|
||||
system-wide settings, from \fI/etc/nanorc\fP (the exact path might be
|
||||
different on your system), and then the user-specific settings, either
|
||||
from \fI~/.nanorc\fR or from \fI$XDG_CONFIG_HOME/nano/nanorc\fR
|
||||
or from \fI~/.config/nano/nanorc\fR, whichever is encountered first.
|
||||
If \fB\-\-rcfile\fR is given, \fBnano\fR will read just the specified
|
||||
settings file.
|
||||
|
||||
.SH NOTICE
|
||||
Since version 4.0, \fBnano\fR by default:
|
||||
.sp
|
||||
.RS 4
|
||||
\(bu does not automatically hard-wrap lines that become overlong,
|
||||
.br
|
||||
\(bu includes the line below the title bar in the editing area,
|
||||
.br
|
||||
\(bu does linewise (smooth) scrolling.
|
||||
.RE
|
||||
.sp
|
||||
To get the old, Pico behavior back, you can use \fBset breaklonglines\fR,
|
||||
\fBset emptyline\fR, and \fBset jumpyscrolling\fR.
|
||||
|
||||
.SH OPTIONS
|
||||
The configuration file accepts a series of \fBset\fP and \fBunset\fP
|
||||
@@ -261,7 +270,7 @@ When needed, use \fBunset jumpyscrolling\fR instead.
|
||||
.B set softwrap
|
||||
Enable soft line wrapping for easier viewing of very long lines.
|
||||
.TP
|
||||
.B set speller """\fIprogram\fR [\fIarg\fR...]\fB"""
|
||||
.B set speller """\fIprogram\fR [\fIargument \fR...]\fB"""
|
||||
Use the given \fIprogram\fR to do spell checking and correcting, instead of
|
||||
using the built-in corrector that calls \fBhunspell\fR or GNU \fBspell\fR.
|
||||
.TP
|
||||
@@ -382,13 +391,13 @@ file, to determine whether this syntax should be used for it.
|
||||
(This functionality only works when \fBlibmagic\fP is installed on the
|
||||
system and will be silently ignored otherwise.)
|
||||
.TP
|
||||
.BI formatter " program " \fR[ "arg " \fR...]
|
||||
.BI formatter " program " \fR[ "argument " \fR...]
|
||||
Run the given \fIprogram\fR on the full contents of the current buffer.
|
||||
(The current buffer is written out to a temporary file, the program is
|
||||
run on it, and then the temporary file is read back in, replacing the
|
||||
contents of the buffer.)
|
||||
.TP
|
||||
.BI linter " program " \fR[ "arg " \fR...]
|
||||
.BI linter " program " \fR[ "argument " \fR...]
|
||||
Use the given \fIprogram\fR to run a syntax check on the current buffer.
|
||||
.TP
|
||||
.BI "comment """ string """
|
||||
@@ -441,10 +450,11 @@ Read in self-contained color syntaxes from \fIsyntaxfile\fP. Note that
|
||||
\fIsyntaxfile\fP may contain only the above commands, from \fBsyntax\fP
|
||||
to \fBicolor\fP.
|
||||
.TP
|
||||
.BI extendsyntax " name command " \fR[ "arg " \fR...]
|
||||
.BI extendsyntax " name command argument " \fR...
|
||||
Extend the syntax previously defined as \fIname\fR with another
|
||||
\fIcommand\fR. This allows adding a new \fBcolor\fP, \fBicolor\fP,
|
||||
\fBheader\fP, \fBmagic\fP, \fBcomment\fP, \fBlinter\fP, or \fBformatter\fR
|
||||
\fBheader\fR, \fBmagic\fR, \fBformatter\fR, \fBlinter\fR, \fBcomment\fR,
|
||||
or \fBtabgives\fR
|
||||
command to an already defined syntax -- useful when you want to
|
||||
slightly improve a syntax defined in one of the system-installed
|
||||
files (which normally are not writable).
|
||||
@@ -472,7 +482,7 @@ menus where the key exists when \fBall\fP is used).
|
||||
.TP
|
||||
The format of \fIkey\fP should be one of:
|
||||
.RS 3
|
||||
.TP 5
|
||||
.TP 7
|
||||
.BI ^ X
|
||||
where \fIX\fR is a Latin letter, or one of several ASCII characters
|
||||
(@, ], \\, ^, _), or the word "Space".
|
||||
@@ -480,7 +490,14 @@ Example: ^C.
|
||||
.TP
|
||||
.BI M\- X
|
||||
where \fIX\fR is any ASCII character except [, or the word "Space".
|
||||
Example: M\-C.
|
||||
Example: M\-8.
|
||||
.TP
|
||||
.BI Sh\-M\- X
|
||||
where \fIX\fR is a Latin letter.
|
||||
Example: Sh\-M\-U.
|
||||
By default, each Meta+letter keystroke does the same as the corresponding
|
||||
Shift+Meta+letter. But when any Shift+Meta bind is made, that will
|
||||
no longer be the case, for all letters.
|
||||
.TP
|
||||
.BI F N
|
||||
where \fIN\fR is a numeric value from 1 to 24.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 2002-2007, 2014-2019 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 2002-2007, 2014-2020 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 4.7" "December 2019"
|
||||
.TH RNANO 1 "version 4.8" "February 2020"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
|
||||
@@ -54,9 +54,9 @@
|
||||
## Do not use the line below the title bar, leaving it entirely blank.
|
||||
# set emptyline
|
||||
|
||||
## Enable hard-wrapping and set the target width, both for automatic
|
||||
## line wrapping and for justifying paragraphs. If the value is 0 or
|
||||
## less, the wrapping point will be the screen width minus this number.
|
||||
## Set the target width for automatic hard-wrapping and for justifying
|
||||
## paragraphs. If the specified value is 0 or less, the wrapping point
|
||||
## will be the terminal's width minus this number.
|
||||
# set fill -8
|
||||
|
||||
## Remember the used search/replace strings for the next session.
|
||||
@@ -268,6 +268,9 @@
|
||||
## such as ^O for Open, ^F for Find, ^H for Help, and ^Q for Quit,
|
||||
## then uncomment these:
|
||||
#bind ^Q exit all
|
||||
#bind ^S savefile main
|
||||
#bind ^W writeout main
|
||||
#bind ^O insert main
|
||||
#bind ^H help all
|
||||
#bind ^H exit help
|
||||
#bind ^F whereis all
|
||||
@@ -275,23 +278,23 @@
|
||||
#bind ^B wherewas all
|
||||
#bind ^D findprevious all
|
||||
#bind ^R replace main
|
||||
#bind ^W writeout main
|
||||
#bind ^O insert main
|
||||
#unbind ^V all
|
||||
#unbind ^Y all
|
||||
#bind M-X flipnewbuffer all
|
||||
#bind ^X cut all
|
||||
#bind ^C copy all
|
||||
#bind ^C copy main
|
||||
#bind ^V paste all
|
||||
#bind ^P curpos main
|
||||
#bind ^A mark main
|
||||
#unbind ^K main
|
||||
#unbind ^U all
|
||||
#unbind ^N main
|
||||
#unbind ^Y all
|
||||
#unbind M-J main
|
||||
#unbind M-T main
|
||||
#bind ^T gotoline main
|
||||
#bind ^T gotodir browser
|
||||
#bind ^Y speller main
|
||||
#unbind ^K all
|
||||
#unbind ^U all
|
||||
#bind M-U undo main
|
||||
#bind M-R redo main
|
||||
#bind ^U undo main
|
||||
#bind ^E redo main
|
||||
#unbind M-J main
|
||||
#unbind M-T main
|
||||
#set multibuffer
|
||||
|
||||
1144
po/nano.pot
1144
po/nano.pot
File diff suppressed because it is too large
Load Diff
1204
po/pt_BR.po
1204
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1156
po/zh_CN.po
1156
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1150
po/zh_TW.po
1150
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION="4.7"
|
||||
VERSION="4.8"
|
||||
|
||||
./configure -C --enable-tiny && make && ./configure -C &&
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* browser.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2016 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -138,14 +138,20 @@ char *do_browser(char *path)
|
||||
/* If we selected the same filename as last time, fake a
|
||||
* press of the Enter key so that the file is read in. */
|
||||
if (old_selected == selected)
|
||||
unget_kbinput(KEY_ENTER, FALSE);
|
||||
kbinput = KEY_ENTER;
|
||||
}
|
||||
|
||||
continue;
|
||||
if (kbinput == KEY_MOUSE)
|
||||
continue;
|
||||
}
|
||||
#endif /* ENABLE_MOUSE */
|
||||
|
||||
func = parse_browser_input(&kbinput);
|
||||
#ifndef NANO_TINY
|
||||
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) {
|
||||
beep();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
func = interpret(&kbinput);
|
||||
|
||||
if (func == total_refresh) {
|
||||
total_redraw();
|
||||
@@ -219,7 +225,7 @@ char *do_browser(char *path)
|
||||
selected = 0;
|
||||
} else if (func == to_last_file) {
|
||||
selected = filelist_len - 1;
|
||||
} else if (func == goto_dir_void) {
|
||||
} else if (func == goto_dir) {
|
||||
/* Ask for the directory to go to. */
|
||||
if (do_prompt(TRUE, FALSE, MGOTODIR, "", NULL,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
@@ -447,49 +453,10 @@ void read_the_list(const char *path, DIR *dir)
|
||||
width = (COLS + 2) / (longest + 2);
|
||||
}
|
||||
|
||||
/* Return the function that is bound to the given key, accepting certain
|
||||
* plain characters too, for compatibility with Pico. */
|
||||
functionptrtype parse_browser_input(int *kbinput)
|
||||
{
|
||||
if (!meta_key) {
|
||||
switch (*kbinput) {
|
||||
case '-':
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
return do_page_down;
|
||||
case 'W':
|
||||
case 'w':
|
||||
case '/':
|
||||
return do_search_forward;
|
||||
case 'N':
|
||||
return do_findprevious;
|
||||
case 'n':
|
||||
return do_findnext;
|
||||
case 'G':
|
||||
case 'g':
|
||||
return goto_dir_void;
|
||||
case '?':
|
||||
return do_help;
|
||||
case 'S':
|
||||
case 's':
|
||||
return do_enter;
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'Q':
|
||||
case 'q':
|
||||
case 'X':
|
||||
case 'x':
|
||||
return do_exit;
|
||||
}
|
||||
}
|
||||
return func_from_key(kbinput);
|
||||
}
|
||||
|
||||
/* Set width to the number of files that we can display per screen row,
|
||||
* if necessary, and display the list of files. */
|
||||
void browser_refresh(void)
|
||||
{
|
||||
size_t i;
|
||||
int row = 0, col = 0;
|
||||
/* The current row and column while the list is getting displayed. */
|
||||
int the_row = 0, the_column = 0;
|
||||
@@ -502,11 +469,10 @@ void browser_refresh(void)
|
||||
|
||||
wmove(edit, 0, 0);
|
||||
|
||||
i = selected - selected % (editwinrows * width);
|
||||
|
||||
for (; i < filelist_len && row < editwinrows; i++) {
|
||||
for (size_t index = selected - selected % (editwinrows * width);
|
||||
index < filelist_len && row < editwinrows; index++) {
|
||||
struct stat st;
|
||||
const char *thename = tail(filelist[i]);
|
||||
const char *thename = tail(filelist[index]);
|
||||
/* The filename we display, minus the path. */
|
||||
size_t namelen = breadth(thename);
|
||||
/* The length of the filename in columns. */
|
||||
@@ -525,7 +491,7 @@ void browser_refresh(void)
|
||||
|
||||
/* If this is the selected item, draw its highlighted bar upfront, and
|
||||
* remember its location to be able to place the cursor on it. */
|
||||
if (i == selected) {
|
||||
if (index == selected) {
|
||||
wattron(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
mvwprintw(edit, row, col, "%*s", longest, " ");
|
||||
the_row = row;
|
||||
@@ -544,8 +510,8 @@ void browser_refresh(void)
|
||||
/* Show information about the file: "--" for symlinks (except when
|
||||
* they point to a directory) and for files that have disappeared,
|
||||
* "(dir)" for directories, and the file size for normal files. */
|
||||
if (lstat(filelist[i], &st) == -1 || S_ISLNK(st.st_mode)) {
|
||||
if (stat(filelist[i], &st) == -1 || !S_ISDIR(st.st_mode))
|
||||
if (lstat(filelist[index], &st) == -1 || S_ISLNK(st.st_mode)) {
|
||||
if (stat(filelist[index], &st) == -1 || !S_ISDIR(st.st_mode))
|
||||
info = copy_of("--");
|
||||
else
|
||||
/* TRANSLATORS: Try to keep this at most 7 characters. */
|
||||
@@ -596,7 +562,7 @@ void browser_refresh(void)
|
||||
mvwaddstr(edit, row, col - infolen, info);
|
||||
|
||||
/* If this is the selected item, finish its highlighting. */
|
||||
if (i == selected)
|
||||
if (index == selected)
|
||||
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
|
||||
free(info);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* chars.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2018 Benno Schulenberg *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2019 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 *
|
||||
|
||||
32
src/color.c
32
src/color.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* color.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -67,7 +67,6 @@ void set_colorpairs(void)
|
||||
{
|
||||
syntaxtype *sint;
|
||||
bool using_defaults = FALSE;
|
||||
size_t i;
|
||||
|
||||
/* Tell ncurses to enable colors. */
|
||||
start_color();
|
||||
@@ -78,30 +77,31 @@ void set_colorpairs(void)
|
||||
#endif
|
||||
|
||||
/* Initialize the color pairs for nano's interface elements. */
|
||||
for (i = 0; i < NUMBER_OF_ELEMENTS; i++) {
|
||||
colortype *combo = color_combo[i];
|
||||
for (size_t index = 0; index < NUMBER_OF_ELEMENTS; index++) {
|
||||
colortype *combo = color_combo[index];
|
||||
|
||||
if (combo != NULL) {
|
||||
if (combo->fg == USE_THE_DEFAULT && !using_defaults)
|
||||
combo->fg = COLOR_WHITE;
|
||||
if (combo->bg == USE_THE_DEFAULT && !using_defaults)
|
||||
combo->bg = COLOR_BLACK;
|
||||
init_pair(i + 1, combo->fg, combo->bg);
|
||||
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BANDAID |
|
||||
combo->attributes;
|
||||
init_pair(index + 1, combo->fg, combo->bg);
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1) | A_BANDAID |
|
||||
combo->attributes;
|
||||
} else {
|
||||
if (i == FUNCTION_TAG)
|
||||
interface_color_pair[i] = A_NORMAL;
|
||||
else if (i == GUIDE_STRIPE)
|
||||
interface_color_pair[i] = A_REVERSE;
|
||||
else if (i == ERROR_MESSAGE) {
|
||||
init_pair(i + 1, COLOR_WHITE, COLOR_RED);
|
||||
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BOLD | A_BANDAID;
|
||||
if (index == FUNCTION_TAG)
|
||||
interface_color_pair[index] = A_NORMAL;
|
||||
else if (index == GUIDE_STRIPE)
|
||||
interface_color_pair[index] = A_REVERSE;
|
||||
else if (index == ERROR_MESSAGE) {
|
||||
init_pair(index + 1, COLOR_WHITE, COLOR_RED);
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1) |
|
||||
A_BOLD | A_BANDAID;
|
||||
} else
|
||||
interface_color_pair[i] = hilite_attribute;
|
||||
interface_color_pair[index] = hilite_attribute;
|
||||
}
|
||||
|
||||
free(color_combo[i]);
|
||||
free(color_combo[index]);
|
||||
}
|
||||
|
||||
/* For each loaded syntax, assign pair numbers to color combinations. */
|
||||
|
||||
174
src/cut.c
174
src/cut.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* cut.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014 Mark Majeres *
|
||||
* Copyright (C) 2016, 2018, 2019 Benno Schulenberg *
|
||||
* *
|
||||
@@ -210,6 +210,164 @@ void chop_next_word(void)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Move all text between (top, top_x) and (bot, bot_x) from the current buffer
|
||||
* into the cutbuffer. */
|
||||
void extract_segment(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x)
|
||||
{
|
||||
bool edittop_inside = (openfile->edittop->lineno >= top->lineno &&
|
||||
openfile->edittop->lineno <= bot->lineno);
|
||||
#ifndef NANO_TINY
|
||||
bool mark_inside = (openfile->mark &&
|
||||
openfile->mark->lineno >= top->lineno &&
|
||||
openfile->mark->lineno <= bot->lineno &&
|
||||
(openfile->mark != top || openfile->mark_x >= top_x) &&
|
||||
(openfile->mark != bot || openfile->mark_x <= bot_x));
|
||||
bool same_line = (openfile->mark == top);
|
||||
|
||||
if (top == bot && top_x == bot_x)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Reduce the buffer to cover just the text that needs to be extracted. */
|
||||
partition_buffer(top, top_x, bot, bot_x);
|
||||
|
||||
/* Subtract the number of characters in that text from the file size. */
|
||||
openfile->totsize -= get_totsize(top, bot);
|
||||
|
||||
/* If the cutbuffer is currently empty, just move all the text directly
|
||||
* into it; otherwise, append the text to what is already there. */
|
||||
if (cutbuffer == NULL) {
|
||||
cutbuffer = openfile->filetop;
|
||||
cutbottom = openfile->filebot;
|
||||
} else {
|
||||
/* Tack the data of the first line of the text onto the data of
|
||||
* the last line in the given buffer. */
|
||||
cutbottom->data = charealloc(cutbottom->data,
|
||||
strlen(cutbottom->data) +
|
||||
strlen(openfile->filetop->data) + 1);
|
||||
strcat(cutbottom->data, openfile->filetop->data);
|
||||
|
||||
/* Attach the second line of the text (if any) to the last line
|
||||
* of the buffer, then remove the now superfluous first line. */
|
||||
cutbottom->next = openfile->filetop->next;
|
||||
delete_node(openfile->filetop);
|
||||
|
||||
/* If there is a second line, make the reverse attachment too and
|
||||
* update the buffer pointer to point at the end of the text. */
|
||||
if (cutbottom->next != NULL) {
|
||||
cutbottom->next->prev = cutbottom;
|
||||
cutbottom = openfile->filebot;
|
||||
}
|
||||
}
|
||||
|
||||
/* Since the text has now been saved, remove it from the file buffer. */
|
||||
openfile->filetop = make_new_node(NULL);
|
||||
openfile->filetop->data = copy_of("");
|
||||
openfile->filebot = openfile->filetop;
|
||||
|
||||
/* Set the cursor at the point where the text was removed. */
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = top_x;
|
||||
#ifndef NANO_TINY
|
||||
/* If the mark was inside the partition, put it where the cursor now is. */
|
||||
if (mark_inside) {
|
||||
openfile->mark = openfile->current;
|
||||
openfile->mark_x = openfile->current_x;
|
||||
} else if (same_line)
|
||||
/* Update the pointer to this partially cut line. */
|
||||
openfile->mark = openfile->current;
|
||||
#endif
|
||||
|
||||
/* Glue the texts before and after the extraction together. */
|
||||
unpartition_buffer();
|
||||
|
||||
renumber_from(openfile->current);
|
||||
|
||||
/* If the top of the edit window was inside the old partition, put
|
||||
* it in range of current. */
|
||||
if (edittop_inside) {
|
||||
adjust_viewport(STATIONARY);
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* If the text doesn't end with a newline, and it should, add one. */
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
}
|
||||
|
||||
/* Meld the buffer that starts at topline into the current file buffer
|
||||
* at the current cursor position. */
|
||||
void ingraft_buffer(linestruct *topline)
|
||||
{
|
||||
size_t current_x_save = openfile->current_x;
|
||||
/* Remember whether the current line is at the top of the edit window. */
|
||||
bool edittop_inside = (openfile->edittop == openfile->current);
|
||||
#ifndef NANO_TINY
|
||||
/* Remember whether mark and cursor are on the same line, and their order. */
|
||||
bool same_line = (openfile->mark == openfile->current);
|
||||
bool right_side_up = (openfile->mark &&
|
||||
(openfile->mark->lineno < openfile->current->lineno ||
|
||||
(same_line && openfile->mark_x <= openfile->current_x)));
|
||||
#endif
|
||||
|
||||
/* Partition the buffer so that it contains no text, then delete it.*/
|
||||
partition_buffer(openfile->current, openfile->current_x,
|
||||
openfile->current, openfile->current_x);
|
||||
delete_node(openfile->filetop);
|
||||
|
||||
/* Replace the current buffer with the passed buffer. */
|
||||
openfile->filetop = topline;
|
||||
openfile->filebot = topline;
|
||||
while (openfile->filebot->next != NULL)
|
||||
openfile->filebot = openfile->filebot->next;
|
||||
|
||||
/* Put the cursor at the end of the pasted text. */
|
||||
openfile->current = openfile->filebot;
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
|
||||
/* When the pasted stuff contains no newline, adjust the cursor's
|
||||
* x coordinate for the text that is before the pasted stuff. */
|
||||
if (openfile->filetop == openfile->filebot)
|
||||
openfile->current_x += current_x_save;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When needed, refresh the mark's pointer and compensate the mark's
|
||||
* x coordinate for the change in the current line. */
|
||||
if (same_line) {
|
||||
if (!right_side_up) {
|
||||
openfile->mark = openfile->filebot;
|
||||
openfile->mark_x += openfile->current_x - current_x_save;
|
||||
} else
|
||||
openfile->mark = openfile->filetop;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add the number of characters in the copied text to the file size. */
|
||||
openfile->totsize += get_totsize(openfile->filetop, openfile->filebot);
|
||||
|
||||
/* If we pasted onto the first line of the edit window, the corresponding
|
||||
* record has been freed, so... point at the start of the copied text. */
|
||||
if (edittop_inside)
|
||||
openfile->edittop = openfile->filetop;
|
||||
|
||||
/* Weld the pasted text into the surrounding content of the buffer. */
|
||||
unpartition_buffer();
|
||||
|
||||
renumber_from(topline);
|
||||
|
||||
/* If the text doesn't end with a newline, and it should, add one. */
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
}
|
||||
|
||||
/* Meld a copy of the given buffer into the current file buffer. */
|
||||
void copy_from_buffer(linestruct *somebuffer)
|
||||
{
|
||||
linestruct *the_copy = copy_buffer(somebuffer);
|
||||
|
||||
ingraft_buffer(the_copy);
|
||||
}
|
||||
|
||||
/* Move the whole current line from the current buffer to the cutbuffer. */
|
||||
void cut_line(void)
|
||||
{
|
||||
@@ -217,9 +375,9 @@ void cut_line(void)
|
||||
* head of this line to the head of the next line into the cutbuffer;
|
||||
* otherwise, move all of the text of this line into the cutbuffer. */
|
||||
if (openfile->current != openfile->filebot)
|
||||
extract(openfile->current, 0, openfile->current->next, 0);
|
||||
extract_segment(openfile->current, 0, openfile->current->next, 0);
|
||||
else
|
||||
extract(openfile->current, 0,
|
||||
extract_segment(openfile->current, 0,
|
||||
openfile->current, strlen(openfile->current->data));
|
||||
|
||||
openfile->placewewant = 0;
|
||||
@@ -237,10 +395,10 @@ void cut_to_eol(void)
|
||||
* the cutbuffer. Otherwise, when not at the end of the buffer,
|
||||
* move the line separation into the cutbuffer. */
|
||||
if (openfile->current_x < data_len)
|
||||
extract(openfile->current, openfile->current_x,
|
||||
extract_segment(openfile->current, openfile->current_x,
|
||||
openfile->current, data_len);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
extract(openfile->current, openfile->current_x,
|
||||
extract_segment(openfile->current, openfile->current_x,
|
||||
openfile->current->next, 0);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
@@ -255,7 +413,7 @@ void cut_marked(bool *right_side_up)
|
||||
get_region((const linestruct **)&top, &top_x,
|
||||
(const linestruct **)&bot, &bot_x, right_side_up);
|
||||
|
||||
extract(top, top_x, bot, bot_x);
|
||||
extract_segment(top, top_x, bot, bot_x);
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
@@ -263,7 +421,7 @@ void cut_marked(bool *right_side_up)
|
||||
/* Move all text from the cursor position to end-of-file into the cutbuffer. */
|
||||
void cut_to_eof(void)
|
||||
{
|
||||
extract(openfile->current, openfile->current_x,
|
||||
extract_segment(openfile->current, openfile->current_x,
|
||||
openfile->filebot, strlen(openfile->filebot->data));
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
@@ -366,9 +524,9 @@ bool is_cuttable(bool test_cliff)
|
||||
#endif
|
||||
)) {
|
||||
#ifndef NANO_TINY
|
||||
statusbar(_("Nothing was cut"));
|
||||
openfile->mark = NULL;
|
||||
#endif
|
||||
statusbar(_("Nothing was cut"));
|
||||
return FALSE;
|
||||
} else
|
||||
return TRUE;
|
||||
|
||||
245
src/files.c
245
src/files.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* files.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -30,7 +30,12 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LOCKBUFSIZE 8192
|
||||
#ifndef NANO_TINY
|
||||
#define LOCKSIZE 1024
|
||||
const char *locking_prefix = ".";
|
||||
const char *locking_suffix = ".swp";
|
||||
/* Prefix and suffix for the name of the vim-style lock file. */
|
||||
#endif
|
||||
|
||||
/* Verify that the containing directory of the given filename exists. */
|
||||
bool has_valid_path(const char *filename)
|
||||
@@ -49,8 +54,10 @@ bool has_valid_path(const char *filename)
|
||||
statusline(ALERT, _("Path '%s' is not a directory"), parentdir);
|
||||
else if (access(parentdir, X_OK) == -1)
|
||||
statusline(ALERT, _("Path '%s' is not accessible"), parentdir);
|
||||
else if (ISSET(LOCKING) && access(parentdir, W_OK) == -1)
|
||||
#ifndef NANO_TINY
|
||||
else if (ISSET(LOCKING) && !ISSET(VIEW_MODE) && access(parentdir, W_OK) < 0)
|
||||
statusline(MILD, _("Directory '%s' is not writable"), parentdir);
|
||||
#endif
|
||||
else
|
||||
validity = TRUE;
|
||||
|
||||
@@ -124,41 +131,21 @@ void make_new_buffer(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Mark the current file as modified if it isn't already, and then
|
||||
* update the titlebar to display the file's new status. */
|
||||
void set_modified(void)
|
||||
{
|
||||
if (openfile->modified)
|
||||
return;
|
||||
|
||||
openfile->modified = TRUE;
|
||||
titlebar(NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (!ISSET(LOCKING) || openfile->filename[0] == '\0')
|
||||
return;
|
||||
|
||||
if (openfile->lock_filename != NULL) {
|
||||
char *fullname = get_full_path(openfile->filename);
|
||||
|
||||
write_lockfile(openfile->lock_filename, fullname, TRUE);
|
||||
free(fullname);
|
||||
/* Delete the lockfile. Return -1 if unsuccessful, and 1 otherwise. */
|
||||
int delete_lockfile(const char *lockfilename)
|
||||
{
|
||||
if (unlink(lockfilename) < 0 && errno != ENOENT) {
|
||||
statusline(MILD, _("Error deleting lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Actually write the lockfile. This function will ALWAYS annihilate
|
||||
* any previous version of the file. We'll borrow INSECURE_BACKUP here
|
||||
* to decide about lockfile paranoia here as well...
|
||||
*
|
||||
* Args:
|
||||
* lockfilename: file name for lock
|
||||
* origfilename: name of the file the lock is for
|
||||
* modified: whether to set the modified bit in the file
|
||||
*
|
||||
* Returns 1 on success, and 0 on failure (but continue anyway). */
|
||||
int write_lockfile(const char *lockfilename, const char *origfilename, bool modified)
|
||||
/* Write a lockfile, under the given lockfilename. This ALWAYS annihilates
|
||||
* an existing version of that file. Return 1 on success, and 0 on failure. */
|
||||
int write_lockfile(const char *lockfilename, const char *filename, bool modified)
|
||||
{
|
||||
#ifdef HAVE_PWD_H
|
||||
int cflags, fd;
|
||||
@@ -167,9 +154,8 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
uid_t myuid;
|
||||
struct passwd *mypwuid;
|
||||
struct stat fileinfo;
|
||||
char *lockdata = charalloc(1024);
|
||||
char *lockdata;
|
||||
char myhostname[32];
|
||||
size_t lockdatalen = 1024;
|
||||
size_t wroteamt;
|
||||
|
||||
mypid = getpid();
|
||||
@@ -179,7 +165,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
if ((mypwuid = getpwuid(myuid)) == NULL) {
|
||||
/* TRANSLATORS: Keep the next eight messages at most 76 characters. */
|
||||
statusline(MILD, _("Couldn't determine my identity for lock file"));
|
||||
goto free_the_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gethostname(myhostname, 31) < 0) {
|
||||
@@ -187,14 +173,14 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
myhostname[31] = '\0';
|
||||
else {
|
||||
statusline(MILD, _("Couldn't determine hostname: %s"), strerror(errno));
|
||||
goto free_the_data;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the lockfile exists, try to delete it. */
|
||||
if (stat(lockfilename, &fileinfo) != -1)
|
||||
if (delete_lockfile(lockfilename) < 0)
|
||||
goto free_the_data;
|
||||
return 0;
|
||||
|
||||
if (ISSET(INSECURE_BACKUP))
|
||||
cflags = O_WRONLY | O_CREAT | O_APPEND;
|
||||
@@ -206,136 +192,117 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
if (fd < 0) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
goto free_the_data;
|
||||
lockfilename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to associate a stream with the now open lockfile. */
|
||||
filestream = fdopen(fd, "wb");
|
||||
|
||||
if (filestream == NULL) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"), lockfilename,
|
||||
strerror(errno));
|
||||
goto free_the_data;
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is the lock data we will store:
|
||||
lockdata = charalloc(LOCKSIZE);
|
||||
memset(lockdata, 0, LOCKSIZE);
|
||||
|
||||
/* This is the lock data we will store (other bytes are 0x00):
|
||||
*
|
||||
* byte 0 - 0x62
|
||||
* byte 1 - 0x30
|
||||
* bytes 2-12 - program name which created the lock
|
||||
* bytes 24-27 - PID (little endian) of creator process
|
||||
* bytes 28-44 - username of who created the lock
|
||||
* bytes 68-100 - hostname of where the lock was created
|
||||
* bytes 108-876 - filename the lock is for
|
||||
* byte 1007 - 0x55 if file is modified
|
||||
* bytes 0-1 - 0x62 0x30
|
||||
* bytes 2-11 - name of program that created the lock
|
||||
* bytes 24-27 - PID (little endian) of creator process
|
||||
* bytes 28-43 - username of who created the lock
|
||||
* bytes 68-99 - hostname of where the lock was created
|
||||
* bytes 108-876 - filename the lock is for
|
||||
* byte 1007 - 0x55 if file is modified
|
||||
*
|
||||
* Looks like VIM also stores undo state in this file, so we're
|
||||
* gonna have to figure out how to slap a 'OMG don't use recover on
|
||||
* our lockfile' message in here...
|
||||
*
|
||||
* This is likely very wrong, so this is a WIP. */
|
||||
memset(lockdata, 0, lockdatalen);
|
||||
* Nano does not write the page size (bytes 12-15), nor the modification
|
||||
* time (bytes 16-19), nor the inode of the relevant file (bytes 20-23).
|
||||
* Nano also does not use all available space for user name (40 bytes),
|
||||
* host name (40 bytes), and file name (890 bytes). Nor does nano write
|
||||
* some byte-order-checking numbers (bytes 1008-1022). */
|
||||
lockdata[0] = 0x62;
|
||||
lockdata[1] = 0x30;
|
||||
snprintf(&lockdata[2], 10, "nano %s", VERSION);
|
||||
lockdata[24] = mypid % 256;
|
||||
lockdata[25] = (mypid / 256) % 256;
|
||||
lockdata[26] = (mypid / (256 * 256)) % 256;
|
||||
lockdata[27] = mypid / (256 * 256 * 256);
|
||||
snprintf(&lockdata[2], 11, "nano %s", VERSION);
|
||||
strncpy(&lockdata[28], mypwuid->pw_name, 16);
|
||||
strncpy(&lockdata[68], myhostname, 32);
|
||||
if (origfilename != NULL)
|
||||
strncpy(&lockdata[108], origfilename, 768);
|
||||
if (modified == TRUE)
|
||||
lockdata[1007] = 0x55;
|
||||
strncpy(&lockdata[108], filename, 768);
|
||||
lockdata[1007] = (modified) ? 0x55 : 0x00;
|
||||
|
||||
wroteamt = fwrite(lockdata, sizeof(char), lockdatalen, filestream);
|
||||
if (wroteamt < lockdatalen) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, ferror(filestream));
|
||||
fclose(filestream);
|
||||
goto free_the_data;
|
||||
}
|
||||
wroteamt = fwrite(lockdata, sizeof(char), LOCKSIZE, filestream);
|
||||
|
||||
if (fclose(filestream) == EOF) {
|
||||
free(lockdata);
|
||||
|
||||
if (fclose(filestream) == EOF || wroteamt < LOCKSIZE) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
goto free_the_data;
|
||||
lockfilename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
openfile->lock_filename = (char *)lockfilename;
|
||||
|
||||
free(lockdata);
|
||||
return 1;
|
||||
|
||||
free_the_data:
|
||||
free(lockdata);
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Delete the lockfile. Return -1 if unsuccessful, and 1 otherwise. */
|
||||
int delete_lockfile(const char *lockfilename)
|
||||
{
|
||||
if (unlink(lockfilename) < 0 && errno != ENOENT) {
|
||||
statusline(MILD, _("Error deleting lock file %s: %s"), lockfilename,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Deal with lockfiles. Return -1 on refusing to override the lockfile,
|
||||
* and 1 on successfully creating it; 0 means we were not successful in
|
||||
* creating the lockfile but we should continue to load the file. */
|
||||
int do_lockfile(const char *filename)
|
||||
int do_lockfile(const char *filename, bool ask_the_user)
|
||||
{
|
||||
char *namecopy = copy_of(filename);
|
||||
char *secondcopy = copy_of(filename);
|
||||
size_t locknamesize = strlen(filename) + strlen(locking_prefix)
|
||||
+ strlen(locking_suffix) + 3;
|
||||
size_t locknamesize = strlen(filename) + strlen(locking_prefix) +
|
||||
strlen(locking_suffix) + 3;
|
||||
char *lockfilename = charalloc(locknamesize);
|
||||
static char lockprog[11], lockuser[17];
|
||||
struct stat fileinfo;
|
||||
int lockfd, lockpid, retval = -1;
|
||||
int retval = 0;
|
||||
|
||||
snprintf(lockfilename, locknamesize, "%s/%s%s%s", dirname(namecopy),
|
||||
locking_prefix, basename(secondcopy), locking_suffix);
|
||||
free(secondcopy);
|
||||
free(namecopy);
|
||||
|
||||
if (stat(lockfilename, &fileinfo) != -1) {
|
||||
size_t readtot = 0;
|
||||
size_t readamt = 0;
|
||||
if (!ask_the_user && stat(lockfilename, &fileinfo) != -1)
|
||||
warn_and_shortly_pause(_("Someone else is also editing this file"));
|
||||
else if (stat(lockfilename, &fileinfo) != -1) {
|
||||
char *lockbuf, *question, *pidstring, *postedname, *promptstr;
|
||||
int room, choice;
|
||||
static char lockprog[11], lockuser[17];
|
||||
int lockfd, lockpid, room, choice;
|
||||
ssize_t readamt;
|
||||
|
||||
if ((lockfd = open(lockfilename, O_RDONLY)) < 0) {
|
||||
statusline(MILD, _("Error opening lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
statusline(ALERT, _("Error opening lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
goto free_the_name;
|
||||
}
|
||||
|
||||
lockbuf = charalloc(LOCKBUFSIZE);
|
||||
do {
|
||||
readamt = read(lockfd, &lockbuf[readtot], LOCKBUFSIZE - readtot);
|
||||
readtot += readamt;
|
||||
} while (readamt > 0 && readtot < LOCKBUFSIZE);
|
||||
lockbuf = charalloc(LOCKSIZE);
|
||||
|
||||
readamt = read(lockfd, lockbuf, LOCKSIZE);
|
||||
|
||||
close(lockfd);
|
||||
|
||||
if (readtot < 48) {
|
||||
statusline(MILD, _("Error reading lock file %s: "
|
||||
"Not enough data read"), lockfilename);
|
||||
/* If not enough data has been read to show the needed things,
|
||||
* or the two magic bytes are not there, skip the lock file. */
|
||||
if (readamt < 68 || lockbuf[0] != 0x62 || lockbuf[1] != 0x30) {
|
||||
statusline(ALERT, _("Bad lock file is ignored: %s"), lockfilename);
|
||||
free(lockbuf);
|
||||
goto free_the_name;
|
||||
}
|
||||
|
||||
strncpy(lockprog, &lockbuf[2], 10);
|
||||
lockprog[10] = '\0';
|
||||
lockpid = (((unsigned char)lockbuf[27] * 256 + (unsigned char)lockbuf[26]) * 256 +
|
||||
(unsigned char)lockbuf[25]) * 256 + (unsigned char)lockbuf[24];
|
||||
strncpy(lockuser, &lockbuf[28], 16);
|
||||
lockuser[16] = '\0';
|
||||
free(lockbuf);
|
||||
|
||||
pidstring = charalloc(11);
|
||||
@@ -345,7 +312,7 @@ int do_lockfile(const char *filename)
|
||||
as_an_at = FALSE;
|
||||
|
||||
/* TRANSLATORS: The second %s is the name of the user, the third that of the editor. */
|
||||
question = _("File %s is being edited (by %s with %s, PID %s); continue?");
|
||||
question = _("File %s is being edited by %s (with %s, PID %s); open anyway?");
|
||||
room = COLS - breadth(question) + 7 - breadth(lockuser) -
|
||||
breadth(lockprog) - breadth(pidstring);
|
||||
if (room < 4)
|
||||
@@ -370,7 +337,12 @@ int do_lockfile(const char *filename)
|
||||
choice = do_yesno_prompt(FALSE, promptstr);
|
||||
free(promptstr);
|
||||
|
||||
/* When the user cancelled while we're still starting up, quit. */
|
||||
if (choice < 0 && !we_are_running)
|
||||
finish();
|
||||
|
||||
if (choice < 1) {
|
||||
retval = -1;
|
||||
wipe_statusbar();
|
||||
goto free_the_name;
|
||||
}
|
||||
@@ -379,8 +351,6 @@ int do_lockfile(const char *filename)
|
||||
retval = write_lockfile(lockfilename, filename, FALSE);
|
||||
|
||||
free_the_name:
|
||||
free(namecopy);
|
||||
free(secondcopy);
|
||||
if (retval < 1)
|
||||
free(lockfilename);
|
||||
|
||||
@@ -455,9 +425,9 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
|
||||
if (has_valid_path(realname)) {
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(LOCKING) && filename[0] != '\0') {
|
||||
if (ISSET(LOCKING) && !ISSET(VIEW_MODE) && filename[0] != '\0') {
|
||||
/* When not overriding an existing lock, discard the buffer. */
|
||||
if (do_lockfile(realname) < 0) {
|
||||
if (do_lockfile(realname, TRUE) < 0) {
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (openfile != openfile->next)
|
||||
close_buffer();
|
||||
@@ -556,10 +526,26 @@ bool replace_buffer(const char *filename, undo_type action, bool marked,
|
||||
}
|
||||
#endif /* ENABLE_SPELLER */
|
||||
|
||||
/* Update the titlebar and the multiline cache to match the current buffer. */
|
||||
/* Mark the current file as modified if it isn't already, and
|
||||
* then update the title bar to display the file's new status. */
|
||||
void set_modified(void)
|
||||
{
|
||||
if (openfile->modified)
|
||||
return;
|
||||
|
||||
openfile->modified = TRUE;
|
||||
titlebar(NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->lock_filename != NULL)
|
||||
write_lockfile(openfile->lock_filename, openfile->filename, TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Update the title bar and the multiline cache to match the current buffer. */
|
||||
void prepare_for_display(void)
|
||||
{
|
||||
/* Update the titlebar, since the filename may have changed. */
|
||||
/* Update the title bar, since the filename may have changed. */
|
||||
if (!inhelp)
|
||||
titlebar(NULL);
|
||||
|
||||
@@ -614,7 +600,7 @@ void redecorate_after_switch(void)
|
||||
openfile->firstcolumn = 0;
|
||||
#endif
|
||||
|
||||
/* Update titlebar and multiline info to match the current buffer. */
|
||||
/* Update title bar and multiline info to match the current buffer. */
|
||||
prepare_for_display();
|
||||
|
||||
/* Ensure that the main loop will redraw the help lines. */
|
||||
@@ -1026,7 +1012,7 @@ void do_insertfile(void)
|
||||
int response;
|
||||
const char *msg;
|
||||
char *given = copy_of("");
|
||||
/* The last answer the user typed at the statusbar prompt. */
|
||||
/* The last answer the user typed at the status-bar prompt. */
|
||||
#ifndef NANO_TINY
|
||||
format_type was_fmt = openfile->fmt;
|
||||
bool execute = FALSE;
|
||||
@@ -1121,7 +1107,7 @@ void do_insertfile(void)
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (func == to_files_void) {
|
||||
if (func == to_files) {
|
||||
char *chosen = do_browse_from(answer);
|
||||
|
||||
/* If no file was chosen, go back to the prompt. */
|
||||
@@ -1867,8 +1853,17 @@ bool write_file(const char *name, FILE *thefile, bool tmp,
|
||||
|
||||
/* When having written an entire buffer, update some administrivia. */
|
||||
if (fullbuffer && method == OVERWRITE && !tmp) {
|
||||
/* If the filename was changed, check if this means a new syntax. */
|
||||
/* If the filename was changed, write a new lockfile when needed,
|
||||
* and check whether it means a different syntax gets used. */
|
||||
if (strcmp(openfile->filename, realname) != 0) {
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->lock_filename != NULL) {
|
||||
delete_lockfile(openfile->lock_filename);
|
||||
free(openfile->lock_filename);
|
||||
openfile->lock_filename = NULL;
|
||||
do_lockfile(realname, FALSE);
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
const char *oldname, *newname;
|
||||
|
||||
@@ -2046,7 +2041,7 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
given = mallocstrcpy(given, answer);
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (func == to_files_void) {
|
||||
if (func == to_files) {
|
||||
char *chosen = do_browse_from(answer);
|
||||
|
||||
if (chosen == NULL)
|
||||
@@ -2453,7 +2448,7 @@ char **cwd_tab_completion(const char *buf, bool allow_files,
|
||||
return matches;
|
||||
}
|
||||
|
||||
/* Do tab completion. place refers to how much the statusbar cursor
|
||||
/* Do tab completion. place refers to how much the status-bar cursor
|
||||
* position should be advanced. refresh_func is the function we will
|
||||
* call to refresh the edit window. */
|
||||
char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
|
||||
314
src/global.c
314
src/global.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* global.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -33,11 +33,33 @@ volatile sig_atomic_t the_window_resized = FALSE;
|
||||
|
||||
bool on_a_vt = FALSE;
|
||||
/* Whether we're running on a Linux console (a VT). */
|
||||
bool shifted_metas = FALSE;
|
||||
/* Whether any Sh-M-<letter> combo has been bound. */
|
||||
|
||||
bool meta_key;
|
||||
/* Whether the current keystroke is a Meta key. */
|
||||
bool shift_held;
|
||||
/* Whether Shift was being held together with a movement key. */
|
||||
bool mute_modifiers = FALSE;
|
||||
/* Whether to ignore modifier keys while running a macro or string bind. */
|
||||
bool bracketed_paste = FALSE;
|
||||
/* Whether text is being pasted into nano from outside. */
|
||||
|
||||
bool started_curses = FALSE;
|
||||
/* Becomes TRUE when curses mode has been entered the first time. */
|
||||
bool we_are_running = FALSE;
|
||||
/* Becomes TRUE as soon as all options and files have been read. */
|
||||
bool more_than_one = FALSE;
|
||||
/* Whether more than one buffer is or has been open. */
|
||||
|
||||
bool inhelp = FALSE;
|
||||
/* Whether we are in the help viewer. */
|
||||
char *title = NULL;
|
||||
/* When not NULL: the title of the current help text. */
|
||||
|
||||
bool refresh_needed = FALSE;
|
||||
/* Did a command mangle enough of the buffer that we should
|
||||
* repaint the screen? */
|
||||
bool focusing = TRUE;
|
||||
/* Whether an update of the edit window should center the cursor. */
|
||||
|
||||
@@ -47,8 +69,6 @@ bool as_an_at = TRUE;
|
||||
bool control_C_was_pressed = FALSE;
|
||||
/* Whether Ctrl+C was pressed (when a keyboard interrupt is enabled). */
|
||||
|
||||
bool started_curses = FALSE;
|
||||
|
||||
bool suppress_cursorpos = FALSE;
|
||||
/* Should we skip constant position display for current keystroke? */
|
||||
|
||||
@@ -58,22 +78,24 @@ message_type lastmessage = HUSH;
|
||||
linestruct *pletion_line = NULL;
|
||||
/* The line where the last completion was found, if any. */
|
||||
|
||||
bool inhelp = FALSE;
|
||||
/* Whether we are in the help viewer. */
|
||||
char *title = NULL;
|
||||
/* When not NULL: the title of the current help text. */
|
||||
|
||||
bool more_than_one = FALSE;
|
||||
/* Whether more than one buffer is or has been open. */
|
||||
bool also_the_last = FALSE;
|
||||
/* Whether indenting/commenting should include the last line of
|
||||
* the marked region. */
|
||||
bool is_shorter;
|
||||
/* Whether a row's text is narrower than the screen's width. */
|
||||
|
||||
char *answer = NULL;
|
||||
/* The answer string used by the status-bar prompt. */
|
||||
|
||||
char *last_search = NULL;
|
||||
/* The last string we searched for. */
|
||||
int didfind = 0;
|
||||
/* Whether the last search found something. */
|
||||
|
||||
char *present_path = NULL;
|
||||
/* The current browser directory when trying to do tab completion. */
|
||||
|
||||
unsigned flags[4] = {0, 0, 0, 0};
|
||||
/* Our flags array, containing the states of all global options. */
|
||||
|
||||
int controlleft, controlright, controlup, controldown;
|
||||
int controlhome, controlend;
|
||||
#ifndef NANO_TINY
|
||||
@@ -93,15 +115,6 @@ size_t wrap_at = 0;
|
||||
/* The actual column where we will wrap lines, based on fill. */
|
||||
#endif
|
||||
|
||||
char *last_search = NULL;
|
||||
/* The last string we searched for. */
|
||||
|
||||
char *present_path = NULL;
|
||||
/* The current browser directory when trying to do tab completion. */
|
||||
|
||||
unsigned flags[4] = {0, 0, 0, 0};
|
||||
/* Our flag containing the states of all global options. */
|
||||
|
||||
WINDOW *topwin = NULL;
|
||||
/* The top portion of the screen, showing the version number of nano,
|
||||
* the name of the file, and whether the buffer was modified. */
|
||||
@@ -110,7 +123,7 @@ WINDOW *edit = NULL;
|
||||
* contents of the current buffer, the file we are editing. */
|
||||
WINDOW *bottomwin = NULL;
|
||||
/* The bottom portion of the screen, where we display statusbar
|
||||
* messages, the statusbar prompt, and a list of shortcuts. */
|
||||
* messages, the status-bar prompt, and a list of shortcuts. */
|
||||
int editwinrows = 0;
|
||||
/* How many rows does the edit window take up? */
|
||||
int editwincols = -1;
|
||||
@@ -160,20 +173,12 @@ regex_t quotereg;
|
||||
char *word_chars = NULL;
|
||||
/* Nonalphanumeric characters that also form words. */
|
||||
|
||||
char *answer = NULL;
|
||||
/* The answer string used by the statusbar prompt. */
|
||||
|
||||
ssize_t tabsize = -1;
|
||||
/* The width of a tab in spaces. The default is set in main(). */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
char *backup_dir = NULL;
|
||||
/* The directory where we store backup files. */
|
||||
|
||||
const char *locking_prefix = ".";
|
||||
/* Prefix of how to store the vim-style lock file. */
|
||||
const char *locking_suffix = ".swp";
|
||||
/* Suffix of the vim-style lock file. */
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
char *operating_dir = NULL;
|
||||
@@ -194,10 +199,6 @@ bool have_palette = FALSE;
|
||||
/* Whether the colors for the current syntax have been initialized. */
|
||||
#endif
|
||||
|
||||
bool refresh_needed = FALSE;
|
||||
/* Did a command mangle enough of the buffer that we should
|
||||
* repaint the screen? */
|
||||
|
||||
int currmenu = MMOST;
|
||||
/* The currently active menu, initialized to a dummy value. */
|
||||
keystruct *sclist = NULL;
|
||||
@@ -252,6 +253,9 @@ char *statedir = NULL;
|
||||
char *startup_problem = NULL;
|
||||
/* An error message (if any) about nanorc files or history files. */
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
char *custom_nanorc = NULL;
|
||||
#endif
|
||||
|
||||
bool spotlighted = FALSE;
|
||||
/* Whether any text is spotlighted. */
|
||||
@@ -288,14 +292,17 @@ void flip_goto(void)
|
||||
{
|
||||
}
|
||||
#ifdef ENABLE_BROWSER
|
||||
void to_files_void(void)
|
||||
void to_files(void)
|
||||
{
|
||||
}
|
||||
void goto_dir_void(void)
|
||||
void goto_dir(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_nothing(void)
|
||||
{
|
||||
}
|
||||
void do_toggle_void(void)
|
||||
{
|
||||
}
|
||||
@@ -367,38 +374,37 @@ void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
#ifndef NANO_TINY
|
||||
static int counter = 0;
|
||||
#endif
|
||||
keystruct *s = nmalloc(sizeof(keystruct));
|
||||
keystruct *sc = nmalloc(sizeof(keystruct));
|
||||
|
||||
/* Start the list, or tack on the next item. */
|
||||
if (sclist == NULL)
|
||||
sclist = s;
|
||||
sclist = sc;
|
||||
else
|
||||
tailsc->next = s;
|
||||
s->next = NULL;
|
||||
tailsc->next = sc;
|
||||
sc->next = NULL;
|
||||
|
||||
/* Fill in the data. */
|
||||
s->menus = menus;
|
||||
s->func = func;
|
||||
sc->menus = menus;
|
||||
sc->func = func;
|
||||
#ifndef NANO_TINY
|
||||
s->toggle = toggle;
|
||||
sc->toggle = toggle;
|
||||
/* When not the same toggle as the previous one, increment the ID. */
|
||||
if (toggle)
|
||||
s->ordinal = (tailsc->toggle == toggle) ? counter : ++counter;
|
||||
sc->ordinal = (tailsc->toggle == toggle) ? counter : ++counter;
|
||||
#endif
|
||||
assign_keyinfo(s, scstring, keycode);
|
||||
sc->keystr = scstring;
|
||||
sc->keycode = (keycode ? keycode : keycode_from_string(scstring));
|
||||
|
||||
tailsc = s;
|
||||
tailsc = sc;
|
||||
}
|
||||
|
||||
/* Return the first shortcut in the list of shortcuts that
|
||||
* matches the given func in the given menu. */
|
||||
const keystruct *first_sc_for(int menu, void (*func)(void))
|
||||
{
|
||||
const keystruct *s;
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if ((s->menus & menu) && s->func == func)
|
||||
return s;
|
||||
for (keystruct *sc = sclist; sc != NULL; sc = sc->next)
|
||||
if ((sc->menus & menu) && sc->func == func)
|
||||
return sc;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -407,13 +413,14 @@ const keystruct *first_sc_for(int menu, void (*func)(void))
|
||||
* current menu, if any; otherwise, return the given default value. */
|
||||
int the_code_for(void (*func)(void), int defaultval)
|
||||
{
|
||||
const keystruct *s = first_sc_for(currmenu, func);
|
||||
const keystruct *sc = first_sc_for(currmenu, func);
|
||||
|
||||
if (s == NULL)
|
||||
if (sc == NULL)
|
||||
return defaultval;
|
||||
|
||||
meta_key = s->meta;
|
||||
return s->keycode;
|
||||
meta_key = (0x20 <= sc->keycode && sc->keycode <= 0x7E);
|
||||
|
||||
return sc->keycode;
|
||||
}
|
||||
|
||||
/* Return the number of entries that can be shown in the given menu. */
|
||||
@@ -436,37 +443,76 @@ size_t shown_entries_for(int menu)
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Return the shortcut that corresponds to the values of kbinput (the
|
||||
* key itself) and meta_key (whether the key is a meta sequence). The
|
||||
* returned shortcut will be the first in the list that corresponds to
|
||||
* the given sequence. */
|
||||
const keystruct *get_shortcut(int *kbinput)
|
||||
/* Return the first shortcut in the current menu that matches the given input. */
|
||||
const keystruct *get_shortcut(int *keycode)
|
||||
{
|
||||
/* Plain characters cannot be shortcuts, so just skip those. */
|
||||
if (!meta_key && ((*kbinput >= 0x20 && *kbinput < 0x7F) ||
|
||||
(*kbinput >= 0xA0 && *kbinput <= 0xFF)))
|
||||
/* Plain characters and upper control codes cannot be shortcuts. */
|
||||
if (!meta_key && 0x20 <= *keycode && *keycode <= 0xFF)
|
||||
return NULL;
|
||||
|
||||
for (keystruct *s = sclist; s != NULL; s = s->next) {
|
||||
if ((s->menus & currmenu) && *kbinput == s->keycode &&
|
||||
meta_key == s->meta)
|
||||
return s;
|
||||
/* Lower control codes with Meta cannot be shortcuts either. */
|
||||
if (meta_key && *keycode < 0x20)
|
||||
return NULL;
|
||||
|
||||
/* During a paste at a prompt, ignore all command keycodes. */
|
||||
if (bracketed_paste && *keycode != BRACKETED_PASTE_MARKER)
|
||||
return NULL;
|
||||
|
||||
for (keystruct *sc = sclist; sc != NULL; sc = sc->next) {
|
||||
if ((sc->menus & currmenu) && *keycode == sc->keycode)
|
||||
return sc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return a pointer to the function that is bound to the given key. */
|
||||
functionptrtype func_from_key(int *kbinput)
|
||||
functionptrtype func_from_key(int *keycode)
|
||||
{
|
||||
const keystruct *s = get_shortcut(kbinput);
|
||||
const keystruct *sc = get_shortcut(keycode);
|
||||
|
||||
if (s)
|
||||
return s->func;
|
||||
else
|
||||
return NULL;
|
||||
return (sc) ? sc->func : NULL;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
||||
/* Return the function that is bound to the given key in the file browser or
|
||||
* the help viewer. Accept also certain plain characters, for compatibility
|
||||
* with Pico or to mimic 'less' and similar text viewers. */
|
||||
functionptrtype interpret(int *keycode)
|
||||
{
|
||||
if (!meta_key) {
|
||||
if (*keycode == 'N')
|
||||
return do_findprevious;
|
||||
if (*keycode == 'n')
|
||||
return do_findnext;
|
||||
|
||||
switch (tolower(*keycode)) {
|
||||
case '-':
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
return do_page_down;
|
||||
case 'w':
|
||||
case '/':
|
||||
return do_search_forward;
|
||||
#ifdef ENABLE_BROWSER
|
||||
case 'g':
|
||||
return goto_dir;
|
||||
#endif
|
||||
case '?':
|
||||
return do_help;
|
||||
case 's':
|
||||
return do_enter;
|
||||
case 'e':
|
||||
case 'q':
|
||||
case 'x':
|
||||
return do_exit;
|
||||
}
|
||||
}
|
||||
|
||||
return func_from_key(keycode);
|
||||
}
|
||||
#endif /* ENABLE_BROWSER || ENABLE_HELP */
|
||||
|
||||
/* Parse the given keystring and return the corresponding keycode,
|
||||
* or return -1 when the string is invalid. */
|
||||
int keycode_from_string(const char *keystring)
|
||||
@@ -481,6 +527,8 @@ int keycode_from_string(const char *keystring)
|
||||
#endif
|
||||
if (keystring[1] <= '_')
|
||||
return keystring[1] - 64;
|
||||
else if (keystring[1] == '`')
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
} else if (strcasecmp(keystring, "^Space") == 0)
|
||||
@@ -494,6 +542,13 @@ int keycode_from_string(const char *keystring)
|
||||
return (int)' ';
|
||||
else
|
||||
return -1;
|
||||
#ifdef ENABLE_NANORC
|
||||
} else if (strncasecmp(keystring, "Sh-M-", 5) == 0 &&
|
||||
'a' <= (keystring[5] | 0x20) && (keystring[5] | 0x20) <= 'z' &&
|
||||
keystring[6] == '\0') {
|
||||
shifted_metas = TRUE;
|
||||
return (keystring[5] & 0x5F);
|
||||
#endif
|
||||
} else if (keystring[0] == 'F') {
|
||||
int fn = atoi(&keystring[1]);
|
||||
if (fn < 1 || fn > 24)
|
||||
@@ -507,14 +562,6 @@ int keycode_from_string(const char *keystring)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the string and its corresponding keycode for the given shortcut s. */
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode)
|
||||
{
|
||||
s->keystr = keystring;
|
||||
s->meta = (keystring[0] == 'M' && keycode == 0);
|
||||
s->keycode = (keycode ? keycode : keycode_from_string(keystring));
|
||||
}
|
||||
|
||||
/* These two tags are used elsewhere too, so they are global. */
|
||||
/* TRANSLATORS: Try to keep the next two strings at most 10 characters. */
|
||||
const char *exit_tag = N_("Exit");
|
||||
@@ -810,7 +857,7 @@ void shortcut_init(void)
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
add_to_funcs(goto_dir_void, MBROWSER,
|
||||
add_to_funcs(goto_dir, MBROWSER,
|
||||
/* TRANSLATORS: Try to keep the next seven strings at most 10 characters. */
|
||||
N_("Go To Dir"), WITHORSANS(gotodir_gist), TOGETHER, VIEW);
|
||||
|
||||
@@ -831,16 +878,16 @@ void shortcut_init(void)
|
||||
/* TRANSLATORS: This starts a backward search. */
|
||||
N_("Where Was"), WITHORSANS(wherewas_gist), TOGETHER, VIEW);
|
||||
#endif
|
||||
add_to_funcs(do_findprevious, MMAIN|MHELP|MBROWSER,
|
||||
add_to_funcs(do_findprevious, MMAIN|MBROWSER|MHELP,
|
||||
/* TRANSLATORS: This refers to searching the preceding occurrence. */
|
||||
N_("Previous"), WITHORSANS(findprev_gist), TOGETHER, VIEW);
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_findnext, MMAIN|MHELP|MBROWSER,
|
||||
add_to_funcs(do_findnext, MMAIN|MBROWSER|MHELP,
|
||||
N_("Next"), WITHORSANS(findnext_gist), BLANKAFTER, VIEW);
|
||||
#else
|
||||
/* In the tiny version, arrange things a bit differently, so that
|
||||
* the useful M-W and M-Q are shown in the help lines. */
|
||||
add_to_funcs(do_findnext, MMAIN|MHELP|MBROWSER,
|
||||
add_to_funcs(do_findnext, MMAIN|MBROWSER|MHELP,
|
||||
N_("Next"), WITHORSANS(findnext_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_search_backward, MMAIN|MHELP,
|
||||
N_("Where Was"), WITHORSANS(wherewas_gist), BLANKAFTER, VIEW);
|
||||
@@ -871,9 +918,9 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_end, MMAIN,
|
||||
N_("End"), WITHORSANS(end_gist), BLANKAFTER, VIEW);
|
||||
|
||||
add_to_funcs(do_up, MMAIN|MHELP|MBROWSER,
|
||||
add_to_funcs(do_up, MMAIN|MBROWSER|MHELP,
|
||||
N_("Prev Line"), WITHORSANS(prevline_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_down, MMAIN|MHELP|MBROWSER,
|
||||
add_to_funcs(do_down, MMAIN|MBROWSER|MHELP,
|
||||
N_("Next Line"), WITHORSANS(nextline_gist), TOGETHER, VIEW);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
add_to_funcs(do_scroll_up, MMAIN,
|
||||
@@ -1049,7 +1096,7 @@ void shortcut_init(void)
|
||||
#ifdef ENABLE_BROWSER
|
||||
/* The file browser is only available when not in restricted mode. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs(to_files_void, MWRITEFILE|MINSERTFILE,
|
||||
add_to_funcs(to_files, MWRITEFILE|MINSERTFILE,
|
||||
N_("To Files"), WITHORSANS(tofiles_gist), TOGETHER, VIEW);
|
||||
|
||||
add_to_funcs(do_page_up, MBROWSER,
|
||||
@@ -1091,19 +1138,19 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMOST, "Bsp", KEY_BACKSPACE, do_backspace, 0);
|
||||
add_to_sclist(MMOST, "Sh-Del", SHIFT_DELETE, do_backspace, 0);
|
||||
add_to_sclist(MMOST, "^D", 0, do_delete, 0);
|
||||
add_to_sclist(MMOST, "Del", 0, do_delete, 0);
|
||||
add_to_sclist(MMOST, "Del", KEY_DC, do_delete, 0);
|
||||
add_to_sclist(MMOST, "^I", 0, do_tab, 0);
|
||||
add_to_sclist(MMOST, "Tab", TAB_CODE, do_tab, 0);
|
||||
add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, "^G", 0, do_help, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", 0, do_exit, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "^X", 0, do_exit, 0);
|
||||
if (!ISSET(PRESERVE))
|
||||
add_to_sclist(MMAIN, "^S", 0, do_savefile, 0);
|
||||
add_to_sclist(MMAIN, "^O", 0, do_writeout_void, 0);
|
||||
add_to_sclist(MMAIN, "^R", 0, do_insertfile_void, 0);
|
||||
add_to_sclist(MMAIN, "Ins", 0, do_insertfile_void, 0);
|
||||
add_to_sclist(MMAIN, "Ins", KEY_IC, do_insertfile_void, 0);
|
||||
if (!ISSET(PRESERVE))
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^Q", 0, do_search_backward, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^W", 0, do_search_forward, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "^Q", 0, do_search_backward, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "^W", 0, do_search_forward, 0);
|
||||
add_to_sclist(MMAIN, "^\\", 0, do_replace, 0);
|
||||
add_to_sclist(MMAIN, "M-R", 0, do_replace, 0);
|
||||
add_to_sclist(MMOST, "^K", 0, cut_text, 0);
|
||||
@@ -1123,19 +1170,19 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN, "^C", 0, do_cursorpos_void, 0);
|
||||
add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn_void, 0);
|
||||
add_to_sclist(MMAIN, "M-G", 0, do_gotolinecolumn_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^Y", 0, do_page_up, 0);
|
||||
add_to_sclist(MHELP|MBROWSER, "Bsp", KEY_BACKSPACE, do_page_up, 0);
|
||||
add_to_sclist(MHELP|MBROWSER, "Sh-Del", SHIFT_DELETE, do_page_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgUp", KEY_PPAGE, do_page_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^V", 0, do_page_down, 0);
|
||||
add_to_sclist(MHELP|MBROWSER, "Space", 0x20, do_page_down, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgDn", KEY_NPAGE, do_page_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "^Y", 0, do_page_up, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "PgUp", KEY_PPAGE, do_page_up, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "^V", 0, do_page_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "PgDn", KEY_NPAGE, do_page_down, 0);
|
||||
add_to_sclist(MBROWSER|MHELP, "Bsp", KEY_BACKSPACE, do_page_up, 0);
|
||||
add_to_sclist(MBROWSER|MHELP, "Sh-Del", SHIFT_DELETE, do_page_up, 0);
|
||||
add_to_sclist(MBROWSER|MHELP, "Space", 0x20, do_page_down, 0);
|
||||
add_to_sclist(MMAIN|MHELP, "M-\\", 0, to_first_line, 0);
|
||||
add_to_sclist(MMAIN|MHELP, "^Home", CONTROL_HOME, to_first_line, 0);
|
||||
add_to_sclist(MMAIN|MHELP, "M-/", 0, to_last_line, 0);
|
||||
add_to_sclist(MMAIN|MHELP, "^End", CONTROL_END, to_last_line, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "M-W", 0, do_findnext, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "M-Q", 0, do_findprevious, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "M-W", 0, do_findnext, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "M-Q", 0, do_findprevious, 0);
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MMAIN, "M-]", 0, do_find_bracket, 0);
|
||||
add_to_sclist(MMAIN, "M-A", 0, do_mark, 0);
|
||||
@@ -1165,8 +1212,8 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMOST|MBROWSER, "^F", 0, do_right, 0);
|
||||
#ifdef ENABLE_UTF8
|
||||
if (using_utf8()) {
|
||||
add_to_sclist(MMOST|MHELP|MBROWSER, "\xE2\x97\x80", KEY_LEFT, do_left, 0);
|
||||
add_to_sclist(MMOST|MHELP|MBROWSER, "\xE2\x96\xb6", KEY_RIGHT, do_right, 0);
|
||||
add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x97\x80", KEY_LEFT, do_left, 0);
|
||||
add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x96\xb6", KEY_RIGHT, do_right, 0);
|
||||
add_to_sclist(MSOME, "^\xE2\x97\x80", CONTROL_LEFT, do_prev_word_void, 0);
|
||||
add_to_sclist(MSOME, "^\xE2\x96\xb6", CONTROL_RIGHT, do_next_word_void, 0);
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_MULTIBUFFER)
|
||||
@@ -1178,8 +1225,8 @@ void shortcut_init(void)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
add_to_sclist(MMOST|MHELP|MBROWSER, "Left", KEY_LEFT, do_left, 0);
|
||||
add_to_sclist(MMOST|MHELP|MBROWSER, "Right", KEY_RIGHT, do_right, 0);
|
||||
add_to_sclist(MMOST|MBROWSER|MHELP, "Left", KEY_LEFT, do_left, 0);
|
||||
add_to_sclist(MMOST|MBROWSER|MHELP, "Right", KEY_RIGHT, do_right, 0);
|
||||
add_to_sclist(MSOME, "^Left", CONTROL_LEFT, do_prev_word_void, 0);
|
||||
add_to_sclist(MSOME, "^Right", CONTROL_RIGHT, do_next_word_void, 0);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
@@ -1201,19 +1248,19 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMOST, "Home", KEY_HOME, do_home, 0);
|
||||
add_to_sclist(MMOST, "^E", 0, do_end, 0);
|
||||
add_to_sclist(MMOST, "End", KEY_END, do_end, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", 0, do_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", 0, do_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "^P", 0, do_up, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "^N", 0, do_down, 0);
|
||||
#ifdef ENABLE_UTF8
|
||||
if (using_utf8()) {
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xb2", KEY_UP, do_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xbc", KEY_DOWN, do_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "\xE2\x96\xb2", KEY_UP, do_up, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "\xE2\x96\xbc", KEY_DOWN, do_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MLINTER, "^\xE2\x96\xb2", CONTROL_UP, do_prev_block, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MLINTER, "^\xE2\x96\xbc", CONTROL_DOWN, do_next_block, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", KEY_UP, do_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", KEY_DOWN, do_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "Up", KEY_UP, do_up, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "Down", KEY_DOWN, do_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MLINTER, "^Up", CONTROL_UP, do_prev_block, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MLINTER, "^Down", CONTROL_DOWN, do_next_block, 0);
|
||||
}
|
||||
@@ -1255,10 +1302,11 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN, "M-D", 0, do_wordlinechar_count, 0);
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
add_to_sclist(MMAIN|MWHEREIS, "M-J", 0, do_full_justify, 0);
|
||||
if (!ISSET(VIEW_MODE))
|
||||
add_to_sclist(MMAIN|MWHEREIS, "M-J", 0, do_full_justify, 0);
|
||||
#endif
|
||||
if (!ISSET(PRESERVE))
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^L", 0, total_refresh, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "^L", 0, total_refresh, 0);
|
||||
else
|
||||
add_to_sclist(MMAIN|MBROWSER, "^L", 0, total_refresh, 0);
|
||||
add_to_sclist(MMAIN, "^Z", 0, do_suspend_void, 0);
|
||||
@@ -1333,8 +1381,8 @@ void shortcut_init(void)
|
||||
add_to_sclist(MBROWSER, "End", KEY_END, to_last_file, 0);
|
||||
add_to_sclist(MBROWSER, "^Home", CONTROL_HOME, to_first_file, 0);
|
||||
add_to_sclist(MBROWSER, "^End", CONTROL_END, to_last_file, 0);
|
||||
add_to_sclist(MBROWSER, "^_", 0, goto_dir_void, 0);
|
||||
add_to_sclist(MBROWSER, "M-G", 0, goto_dir_void, 0);
|
||||
add_to_sclist(MBROWSER, "^_", 0, goto_dir, 0);
|
||||
add_to_sclist(MBROWSER, "M-G", 0, goto_dir, 0);
|
||||
#endif
|
||||
if (ISSET(TEMP_FILE) && !ISSET(PRESERVE))
|
||||
add_to_sclist(MWRITEFILE, "^Q", 0, discard_buffer, 0);
|
||||
@@ -1363,9 +1411,9 @@ void shortcut_init(void)
|
||||
#ifdef ENABLE_BROWSER
|
||||
/* Only when not in restricted mode, allow entering the file browser. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files_void, 0);
|
||||
add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files, 0);
|
||||
#endif
|
||||
add_to_sclist(MHELP|MBROWSER, "^C", 0, do_exit, 0);
|
||||
add_to_sclist(MBROWSER|MHELP, "^C", 0, do_exit, 0);
|
||||
/* Allow exiting from the file browser and the help viewer with
|
||||
* the same key as they were entered. */
|
||||
#ifdef ENABLE_BROWSER
|
||||
@@ -1373,28 +1421,32 @@ void shortcut_init(void)
|
||||
#endif
|
||||
#ifdef ENABLE_HELP
|
||||
add_to_sclist(MHELP, "^G", 0, do_exit, 0);
|
||||
add_to_sclist(MHELP, "F1", 0, do_exit, 0);
|
||||
add_to_sclist(MHELP, "F1", KEY_F(1), do_exit, 0);
|
||||
add_to_sclist(MHELP, "Home", KEY_HOME, to_first_line, 0);
|
||||
add_to_sclist(MHELP, "End", KEY_END, to_last_line, 0);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
add_to_sclist(MLINTER, "^X", 0, do_cancel, 0);
|
||||
#endif
|
||||
add_to_sclist(MMOST & ~MFINDINHELP, "F1", 0, do_help, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", 0, do_exit, 0);
|
||||
add_to_sclist(MMAIN, "F3", 0, do_writeout_void, 0);
|
||||
add_to_sclist(MMOST & ~MFINDINHELP, "F1", KEY_F(1), do_help, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "F2", KEY_F(2), do_exit, 0);
|
||||
add_to_sclist(MMAIN, "F3", KEY_F(3), do_writeout_void, 0);
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
add_to_sclist(MMAIN, "F4", 0, do_justify_void, 0);
|
||||
add_to_sclist(MMAIN, "F4", KEY_F(4), do_justify_void, 0);
|
||||
#endif
|
||||
add_to_sclist(MMAIN, "F5", 0, do_insertfile_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "F6", 0, do_search_forward, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F7", 0, do_page_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F8", 0, do_page_down, 0);
|
||||
add_to_sclist(MMOST, "F9", 0, cut_text, 0);
|
||||
add_to_sclist(MMOST, "F10", 0, paste_text, 0);
|
||||
add_to_sclist(MMAIN, "F11", 0, do_cursorpos_void, 0);
|
||||
add_to_sclist(MMAIN, "F5", KEY_F(5), do_insertfile_void, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "F6", KEY_F(6), do_search_forward, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "F7", KEY_F(7), do_page_up, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "F8", KEY_F(8), do_page_down, 0);
|
||||
add_to_sclist(MMOST, "F9", KEY_F(9), cut_text, 0);
|
||||
add_to_sclist(MMOST, "F10", KEY_F(10), paste_text, 0);
|
||||
add_to_sclist(MMAIN, "F11", KEY_F(11), do_cursorpos_void, 0);
|
||||
#ifdef ENABLE_SPELLER
|
||||
add_to_sclist(MMAIN, "F12", 0, do_spell, 0);
|
||||
add_to_sclist(MMAIN, "F12", KEY_F(12), do_spell, 0);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
/* Catch and ignore bracketed paste marker keys. */
|
||||
add_to_sclist(MMOST|MBROWSER|MHELP|MYESNO, "", BRACKETED_PASTE_MARKER, do_nothing, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
92
src/help.c
92
src/help.c
@@ -1,9 +1,9 @@
|
||||
/**************************************************************************
|
||||
* help.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2000-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2000-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2017 Rishabh Dave *
|
||||
* Copyright (C) 2014-2018 Benno Schulenberg *
|
||||
* Copyright (C) 2014-2019 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 *
|
||||
@@ -43,16 +43,31 @@ static size_t location;
|
||||
void wrap_help_text_into_buffer(void)
|
||||
{
|
||||
size_t sum = 0;
|
||||
/* Avoid overtight and overwide paragraphs in the introductory text. */
|
||||
size_t wrapping_point = (COLS < 32) ? 32 : (COLS > 74) ? 74 : COLS;
|
||||
const char *ptr = start_of_body;
|
||||
|
||||
make_new_buffer();
|
||||
|
||||
/* Copy the help text into the just-created new buffer. */
|
||||
while (*ptr != '\0') {
|
||||
int length = help_line_len(ptr);
|
||||
char *oneline = nmalloc(length + 1);
|
||||
int length, shim;
|
||||
char *oneline;
|
||||
|
||||
if (ptr == end_of_intro)
|
||||
wrapping_point = (COLS < 32) ? 32 : COLS;
|
||||
|
||||
if (ptr > end_of_intro && *(ptr - 1) != '\n') {
|
||||
length = break_line(ptr, (COLS < 32) ? 14 : COLS - 18, TRUE);
|
||||
oneline = nmalloc(length + 5);
|
||||
snprintf(oneline, length + 5, "\t\t %s", ptr);
|
||||
} else {
|
||||
length = break_line(ptr, wrapping_point, TRUE);
|
||||
oneline = nmalloc(length + 1);
|
||||
shim = (*(ptr + length - 1) == ' ') ? 0 : 1;
|
||||
snprintf(oneline, length + shim, "%s", ptr);
|
||||
}
|
||||
|
||||
snprintf(oneline, length + 1, "%s", ptr);
|
||||
free(openfile->current->data);
|
||||
openfile->current->data = oneline;
|
||||
|
||||
@@ -172,7 +187,13 @@ void show_help(void)
|
||||
kbinput = get_kbinput(edit, didfind == 1 || ISSET(SHOW_CURSOR));
|
||||
didfind = 0;
|
||||
|
||||
func = parse_help_input(&kbinput);
|
||||
#ifndef NANO_TINY
|
||||
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) {
|
||||
beep();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
func = interpret(&kbinput);
|
||||
|
||||
if (func == total_refresh) {
|
||||
total_redraw();
|
||||
@@ -542,65 +563,6 @@ void help_init(void)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
}
|
||||
|
||||
/* Return the function that is bound to the given key, accepting certain
|
||||
* plain characters too, for consistency with the file browser. */
|
||||
functionptrtype parse_help_input(int *kbinput)
|
||||
{
|
||||
if (!meta_key) {
|
||||
switch (*kbinput) {
|
||||
case '-':
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
return do_page_down;
|
||||
case 'W':
|
||||
case 'w':
|
||||
case '/':
|
||||
return do_search_forward;
|
||||
case 'N':
|
||||
return do_findprevious;
|
||||
case 'n':
|
||||
return do_findnext;
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'Q':
|
||||
case 'q':
|
||||
case 'X':
|
||||
case 'x':
|
||||
return do_exit;
|
||||
}
|
||||
}
|
||||
return func_from_key(kbinput);
|
||||
}
|
||||
|
||||
/* Calculate the displayable length of the help-text line starting at ptr. */
|
||||
size_t help_line_len(const char *ptr)
|
||||
{
|
||||
size_t wrapping_point = (COLS > 24) ? COLS - 1 : 24;
|
||||
/* The target width for wrapping long lines. */
|
||||
ssize_t wrap_location;
|
||||
/* Actual position where the line can be wrapped. */
|
||||
size_t length = 0;
|
||||
/* Full length of the line, until the first newline. */
|
||||
|
||||
/* Avoid overwide paragraphs in the introductory text. */
|
||||
if (ptr < end_of_intro && COLS > 74)
|
||||
wrapping_point = 74;
|
||||
|
||||
wrap_location = break_line(ptr, wrapping_point, TRUE);
|
||||
|
||||
/* Get the length of the entire line up to a null or a newline. */
|
||||
while (*(ptr + length) != '\0' && *(ptr + length) != '\n')
|
||||
length = step_right(ptr, length);
|
||||
|
||||
/* If the entire line will just fit the screen, don't wrap it. */
|
||||
if (wideness(ptr, length) <= wrapping_point + 1)
|
||||
return length;
|
||||
else if (wrap_location > 0)
|
||||
return wrap_location;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
#endif /* ENABLE_HELP */
|
||||
|
||||
/* Start the help viewer, or indicate that there is no help. */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* history.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2003-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* Copyright (C) 2003-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2017, 2019 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 *
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* move.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2018 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
|
||||
462
src/nano.c
462
src/nano.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* nano.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -83,35 +83,17 @@ linestruct *make_new_node(linestruct *prevnode)
|
||||
{
|
||||
linestruct *newnode = nmalloc(sizeof(linestruct));
|
||||
|
||||
newnode->data = NULL;
|
||||
newnode->prev = prevnode;
|
||||
newnode->next = NULL;
|
||||
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
|
||||
|
||||
newnode->data = NULL;
|
||||
#ifdef ENABLE_COLOR
|
||||
newnode->multidata = NULL;
|
||||
#endif
|
||||
newnode->lineno = (prevnode) ? prevnode->lineno + 1 : 1;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* Make a copy of a linestruct node. */
|
||||
linestruct *copy_node(const linestruct *src)
|
||||
{
|
||||
linestruct *dst = nmalloc(sizeof(linestruct));
|
||||
|
||||
dst->data = copy_of(src->data);
|
||||
dst->next = src->next;
|
||||
dst->prev = src->prev;
|
||||
dst->lineno = src->lineno;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
dst->multidata = NULL;
|
||||
#endif
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* Splice a new node into an existing linked list of linestructs. */
|
||||
void splice_node(linestruct *afterthis, linestruct *newnode)
|
||||
{
|
||||
@@ -126,21 +108,6 @@ void splice_node(linestruct *afterthis, linestruct *newnode)
|
||||
openfile->filebot = newnode;
|
||||
}
|
||||
|
||||
/* Disconnect a node from a linked list of linestructs and delete it. */
|
||||
void unlink_node(linestruct *line)
|
||||
{
|
||||
if (line->prev != NULL)
|
||||
line->prev->next = line->next;
|
||||
if (line->next != NULL)
|
||||
line->next->prev = line->prev;
|
||||
|
||||
/* Update filebot when removing a node at the end of file. */
|
||||
if (openfile && openfile->filebot == line)
|
||||
openfile->filebot = line->prev;
|
||||
|
||||
delete_node(line);
|
||||
}
|
||||
|
||||
/* Free the data structures in the given node. */
|
||||
void delete_node(linestruct *line)
|
||||
{
|
||||
@@ -156,27 +123,19 @@ void delete_node(linestruct *line)
|
||||
free(line);
|
||||
}
|
||||
|
||||
/* Duplicate an entire linked list of linestructs. */
|
||||
linestruct *copy_buffer(const linestruct *src)
|
||||
/* Disconnect a node from a linked list of linestructs and delete it. */
|
||||
void unlink_node(linestruct *line)
|
||||
{
|
||||
linestruct *head, *copy;
|
||||
if (line->prev != NULL)
|
||||
line->prev->next = line->next;
|
||||
if (line->next != NULL)
|
||||
line->next->prev = line->prev;
|
||||
|
||||
copy = copy_node(src);
|
||||
copy->prev = NULL;
|
||||
head = copy;
|
||||
src = src->next;
|
||||
/* Update filebot when removing a node at the end of file. */
|
||||
if (openfile && openfile->filebot == line)
|
||||
openfile->filebot = line->prev;
|
||||
|
||||
while (src != NULL) {
|
||||
copy->next = copy_node(src);
|
||||
copy->next->prev = copy;
|
||||
copy = copy->next;
|
||||
|
||||
src = src->next;
|
||||
}
|
||||
|
||||
copy->next = NULL;
|
||||
|
||||
return head;
|
||||
delete_node(line);
|
||||
}
|
||||
|
||||
/* Free an entire linked list of linestructs. */
|
||||
@@ -193,6 +152,44 @@ void free_lines(linestruct *src)
|
||||
delete_node(src);
|
||||
}
|
||||
|
||||
/* Make a copy of a linestruct node. */
|
||||
linestruct *copy_node(const linestruct *src)
|
||||
{
|
||||
linestruct *dst = nmalloc(sizeof(linestruct));
|
||||
|
||||
dst->data = copy_of(src->data);
|
||||
#ifdef ENABLE_COLOR
|
||||
dst->multidata = NULL;
|
||||
#endif
|
||||
dst->lineno = src->lineno;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* Duplicate an entire linked list of linestructs. */
|
||||
linestruct *copy_buffer(const linestruct *src)
|
||||
{
|
||||
linestruct *head, *item;
|
||||
|
||||
head = copy_node(src);
|
||||
head->prev = NULL;
|
||||
|
||||
item = head;
|
||||
src = src->next;
|
||||
|
||||
while (src != NULL) {
|
||||
item->next = copy_node(src);
|
||||
item->next->prev = item;
|
||||
|
||||
item = item->next;
|
||||
src = src->next;
|
||||
}
|
||||
|
||||
item->next = NULL;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
/* Renumber the lines in a buffer, from the given line onwards. */
|
||||
void renumber_from(linestruct *line)
|
||||
{
|
||||
@@ -279,184 +276,6 @@ void unpartition_buffer(void)
|
||||
openfile->filebot = filetail;
|
||||
}
|
||||
|
||||
/* Move all text between (top, top_x) and (bot, bot_x) from the current buffer
|
||||
* into the cutbuffer. */
|
||||
void extract(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x)
|
||||
{
|
||||
bool edittop_inside;
|
||||
#ifndef NANO_TINY
|
||||
bool mark_inside = FALSE;
|
||||
bool same_line = FALSE;
|
||||
|
||||
if (top == bot && top_x == bot_x)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Partition the buffer so that it contains only the text from
|
||||
* (top, top_x) to (bot, bot_x), keep track of whether the top of
|
||||
* the edit window is inside the partition, and keep track of
|
||||
* whether the mark begins inside the partition. */
|
||||
partition_buffer(top, top_x, bot, bot_x);
|
||||
edittop_inside = (openfile->edittop->lineno >= openfile->filetop->lineno &&
|
||||
openfile->edittop->lineno <= openfile->filebot->lineno);
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->mark) {
|
||||
mark_inside = (openfile->mark->lineno >= openfile->filetop->lineno &&
|
||||
openfile->mark->lineno <= openfile->filebot->lineno &&
|
||||
(openfile->mark != openfile->filetop ||
|
||||
openfile->mark_x >= top_x) &&
|
||||
(openfile->mark != openfile->filebot ||
|
||||
openfile->mark_x <= bot_x));
|
||||
same_line = (openfile->mark == openfile->filetop);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Subtract the number of characters in the text from the file size. */
|
||||
openfile->totsize -= get_totsize(top, bot);
|
||||
|
||||
/* If the given buffer is empty, just move all the text directly into it;
|
||||
* otherwise, append the text to what is already there. */
|
||||
if (cutbuffer == NULL) {
|
||||
cutbuffer = openfile->filetop;
|
||||
cutbottom = openfile->filebot;
|
||||
} else {
|
||||
/* Tack the data of the first line of the text onto the data of
|
||||
* the last line in the given buffer. */
|
||||
cutbottom->data = charealloc(cutbottom->data,
|
||||
strlen(cutbottom->data) +
|
||||
strlen(openfile->filetop->data) + 1);
|
||||
strcat(cutbottom->data, openfile->filetop->data);
|
||||
|
||||
/* Attach the second line of the text (if any) to the last line
|
||||
* of the buffer, then remove the now superfluous first line. */
|
||||
cutbottom->next = openfile->filetop->next;
|
||||
delete_node(openfile->filetop);
|
||||
|
||||
/* If there is a second line, make the reverse attachment too and
|
||||
* update the buffer pointer to point at the end of the text. */
|
||||
if (cutbottom->next != NULL) {
|
||||
cutbottom->next->prev = cutbottom;
|
||||
cutbottom = openfile->filebot;
|
||||
}
|
||||
}
|
||||
|
||||
/* Since the text has now been saved, remove it from the file buffer. */
|
||||
openfile->filetop = make_new_node(NULL);
|
||||
openfile->filetop->data = copy_of("");
|
||||
openfile->filebot = openfile->filetop;
|
||||
|
||||
/* Restore the current line and cursor position. If the mark begins
|
||||
* inside the partition, set the beginning of the mark to where the
|
||||
* saved text used to start. */
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = top_x;
|
||||
#ifndef NANO_TINY
|
||||
if (mark_inside) {
|
||||
openfile->mark = openfile->current;
|
||||
openfile->mark_x = openfile->current_x;
|
||||
} else if (same_line)
|
||||
/* Update the pointer to this partially cut line. */
|
||||
openfile->mark = openfile->current;
|
||||
#endif
|
||||
|
||||
/* Unpartition the buffer so that it contains all the text
|
||||
* again, minus the saved text. */
|
||||
unpartition_buffer();
|
||||
|
||||
renumber_from(openfile->current);
|
||||
|
||||
/* If the top of the edit window was inside the old partition, put
|
||||
* it in range of current. */
|
||||
if (edittop_inside) {
|
||||
adjust_viewport(STATIONARY);
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* If the text doesn't end with a newline, and it should, add one. */
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
}
|
||||
|
||||
/* Meld the buffer that starts at topline into the current file buffer
|
||||
* at the current cursor position. */
|
||||
void ingraft_buffer(linestruct *topline)
|
||||
{
|
||||
size_t current_x_save = openfile->current_x;
|
||||
bool edittop_inside;
|
||||
#ifndef NANO_TINY
|
||||
bool right_side_up = FALSE;
|
||||
bool same_line = FALSE;
|
||||
|
||||
/* Remember whether mark and cursor are on the same line, and their order. */
|
||||
if (openfile->mark) {
|
||||
same_line = (openfile->mark == openfile->current);
|
||||
right_side_up = (openfile->mark->lineno < openfile->current->lineno ||
|
||||
(same_line && openfile->mark_x < openfile->current_x));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Partition the buffer so that it contains no text, and remember
|
||||
* whether the current line is at the top of the edit window. */
|
||||
partition_buffer(openfile->current, openfile->current_x,
|
||||
openfile->current, openfile->current_x);
|
||||
edittop_inside = (openfile->edittop == openfile->filetop);
|
||||
delete_node(openfile->filetop);
|
||||
|
||||
/* Put the top and bottom of the current buffer at the top and
|
||||
* bottom of the passed buffer. */
|
||||
openfile->filetop = topline;
|
||||
openfile->filebot = topline;
|
||||
while (openfile->filebot->next != NULL)
|
||||
openfile->filebot = openfile->filebot->next;
|
||||
|
||||
/* Put the cursor at the end of the pasted text. */
|
||||
openfile->current = openfile->filebot;
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
|
||||
/* When the pasted stuff contains no newline, adjust the cursor's
|
||||
* x coordinate for the text that is before the pasted stuff. */
|
||||
if (openfile->filetop == openfile->filebot)
|
||||
openfile->current_x += current_x_save;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When needed, refresh the mark's pointer and compensate the mark's
|
||||
* x coordinate for the change in the current line. */
|
||||
if (same_line) {
|
||||
if (!right_side_up) {
|
||||
openfile->mark = openfile->filebot;
|
||||
openfile->mark_x += openfile->current_x - current_x_save;
|
||||
} else
|
||||
openfile->mark = openfile->filetop;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add the number of characters in the copied text to the file size. */
|
||||
openfile->totsize += get_totsize(openfile->filetop, openfile->filebot);
|
||||
|
||||
/* If we pasted onto the first line of the edit window, the corresponding
|
||||
* record has been freed, so... point at the start of the copied text. */
|
||||
if (edittop_inside)
|
||||
openfile->edittop = openfile->filetop;
|
||||
|
||||
/* Unpartition the buffer so that it contains all the text
|
||||
* again, plus the copied text. */
|
||||
unpartition_buffer();
|
||||
|
||||
renumber_from(topline);
|
||||
|
||||
/* If the text doesn't end with a newline, and it should, add one. */
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
}
|
||||
|
||||
/* Meld a copy of the given buffer into the current file buffer. */
|
||||
void copy_from_buffer(linestruct *somebuffer)
|
||||
{
|
||||
linestruct *the_copy = copy_buffer(somebuffer);
|
||||
|
||||
ingraft_buffer(the_copy);
|
||||
}
|
||||
|
||||
/* Display a warning about a key disabled in view mode. */
|
||||
void print_view_warning(void)
|
||||
{
|
||||
@@ -482,10 +301,23 @@ void say_there_is_no_help(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure the cursor is visible, then exit from curses mode, disable
|
||||
* bracketed-paste mode, and restore the original terminal settings. */
|
||||
void restore_terminal(void)
|
||||
{
|
||||
curs_set(1);
|
||||
endwin();
|
||||
#ifndef NANO_TINY
|
||||
printf("\e[?2004l");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
}
|
||||
|
||||
/* Exit normally: restore the terminal state and save history files. */
|
||||
void finish(void)
|
||||
{
|
||||
/* Blank the statusbar and (if applicable) the shortcut list. */
|
||||
/* Blank the status bar and (if applicable) the shortcut list. */
|
||||
blank_statusbar();
|
||||
blank_bottombars();
|
||||
wrefresh(bottomwin);
|
||||
@@ -497,12 +329,8 @@ void finish(void)
|
||||
delwin(edit);
|
||||
delwin(bottomwin);
|
||||
#endif
|
||||
/* Switch on the cursor and exit from curses mode. */
|
||||
curs_set(1);
|
||||
endwin();
|
||||
|
||||
/* Restore the old terminal settings. */
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
/* Switch the cursor on, exit from curses, and restore terminal settings. */
|
||||
restore_terminal();
|
||||
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
display_rcfile_errors();
|
||||
@@ -528,12 +356,7 @@ void die(const char *msg, ...)
|
||||
va_list ap;
|
||||
openfilestruct *firstone = openfile;
|
||||
|
||||
/* Switch on the cursor and leave curses mode. */
|
||||
curs_set(1);
|
||||
endwin();
|
||||
|
||||
/* Restore the old terminal settings. */
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
restore_terminal();
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
display_rcfile_errors();
|
||||
@@ -621,12 +444,12 @@ void window_init(void)
|
||||
delwin(bottomwin);
|
||||
}
|
||||
|
||||
/* If the terminal is very flat, don't set up a titlebar. */
|
||||
/* If the terminal is very flat, don't set up a title bar. */
|
||||
if (LINES < 3) {
|
||||
topwin = NULL;
|
||||
editwinrows = 1;
|
||||
/* Set up two subwindows. If the terminal is just one line,
|
||||
* edit window and statusbar window will cover each other. */
|
||||
* edit window and status-bar window will cover each other. */
|
||||
edit = newwin(1, COLS, 0, 0);
|
||||
bottomwin = newwin(1, COLS, LINES - 1, 0);
|
||||
} else {
|
||||
@@ -646,7 +469,6 @@ void window_init(void)
|
||||
|
||||
/* When not disabled, turn escape-sequence translation on. */
|
||||
if (!ISSET(RAW_SEQUENCES)) {
|
||||
keypad(topwin, TRUE);
|
||||
keypad(edit, TRUE);
|
||||
keypad(bottomwin, TRUE);
|
||||
}
|
||||
@@ -773,10 +595,10 @@ void usage(void)
|
||||
N_("Regular expression to match quoting"));
|
||||
#endif
|
||||
if (!ISSET(RESTRICTED))
|
||||
print_opt("-R", "--restricted", N_("Restricted mode"));
|
||||
print_opt("-R", "--restricted", N_("Restrict access to the filesystem"));
|
||||
print_opt(_("-T <#cols>"), _("--tabsize=<#cols>"),
|
||||
N_("Set width of a tab to #cols columns"));
|
||||
print_opt("-U", "--quickblank", N_("Do quick statusbar blanking"));
|
||||
print_opt("-U", "--quickblank", N_("Wipe status bar upon next keystroke"));
|
||||
print_opt("-V", "--version", N_("Print version information and exit"));
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-W", "--wordbounds",
|
||||
@@ -800,9 +622,12 @@ void usage(void)
|
||||
print_opt("-d", "--rebinddelete",
|
||||
N_("Fix Backspace/Delete confusion problem"));
|
||||
print_opt("-e", "--emptyline", N_("Keep the line below the title bar empty"));
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (!ISSET(RESTRICTED))
|
||||
print_opt("-g", "--showcursor", N_("Show cursor in file browser & help text"));
|
||||
#ifdef ENABLE_NANORC
|
||||
print_opt(_("-f <file>"), _("--rcfile=<file>"),
|
||||
N_("Use only this file for configuring nano"));
|
||||
#endif
|
||||
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
||||
print_opt("-g", "--showcursor", N_("Show cursor in file browser & help text"));
|
||||
#endif
|
||||
print_opt("-h", "--help", N_("Show this help text and exit"));
|
||||
#ifndef NANO_TINY
|
||||
@@ -862,8 +687,8 @@ void version(void)
|
||||
#else
|
||||
printf(_(" GNU nano, version %s\n"), VERSION);
|
||||
#endif
|
||||
printf(" (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.\n");
|
||||
printf(_(" (C) 2014-%s the contributors to nano\n"), "2019");
|
||||
printf(" (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.\n");
|
||||
printf(_(" (C) 2014-%s the contributors to nano\n"), "2020");
|
||||
printf(_(" Email: nano@nano-editor.org Web: https://nano-editor.org/"));
|
||||
printf(_("\n Compiled options:"));
|
||||
|
||||
@@ -1094,9 +919,7 @@ bool scoop_stdin(void)
|
||||
{
|
||||
FILE *stream;
|
||||
|
||||
/* Exit from curses mode and put the terminal into its original state. */
|
||||
endwin();
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
restore_terminal();
|
||||
|
||||
/* When input comes from a terminal, show a helpful message. */
|
||||
if (isatty(STANDARD_INPUT))
|
||||
@@ -1211,18 +1034,14 @@ RETSIGTYPE do_suspend(int signal)
|
||||
#ifdef ENABLE_MOUSE
|
||||
disable_mouse_support();
|
||||
#endif
|
||||
restore_terminal();
|
||||
|
||||
/* Move the cursor to the last line of the screen. */
|
||||
move(LINES - 1, 0);
|
||||
endwin();
|
||||
printf("\n\n");
|
||||
|
||||
/* Display our helpful message. */
|
||||
printf(_("Use \"fg\" to return to nano.\n"));
|
||||
fflush(stdout);
|
||||
|
||||
/* Restore the old terminal settings. */
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
|
||||
/* The suspend keystroke must not elicit cursor-position display. */
|
||||
suppress_cursorpos=TRUE;
|
||||
|
||||
@@ -1318,19 +1137,9 @@ void regenerate_screen(void)
|
||||
/* Ensure that firstcolumn is the starting column of its chunk. */
|
||||
ensure_firstcolumn_is_aligned();
|
||||
|
||||
#ifdef USE_SLANG
|
||||
/* Slang curses emulation brain damage, part 1: If we just do what
|
||||
* curses does here, it'll only work properly if the resize made the
|
||||
* window smaller. Do what mutt does: Leave and immediately reenter
|
||||
* Slang screen management mode. */
|
||||
SLsmg_reset_smg();
|
||||
SLsmg_init_smg();
|
||||
#else
|
||||
/* Do the equivalent of what Minimum Profit does: leave and immediately
|
||||
* reenter curses mode. */
|
||||
/* Do as the website suggests: leave and immediately reenter curses mode. */
|
||||
endwin();
|
||||
doupdate();
|
||||
#endif
|
||||
|
||||
/* Put the terminal in the desired state again, recreate the subwindows
|
||||
* with their (new) sizes, and redraw the contents of these windows. */
|
||||
@@ -1389,8 +1198,7 @@ void do_toggle(int flag)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Disable extended input and output processing in our terminal
|
||||
* settings. */
|
||||
/* Disable extended input and output processing in our terminal settings. */
|
||||
void disable_extended_io(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
@@ -1477,7 +1285,6 @@ void terminal_init(void)
|
||||
nonl();
|
||||
noecho();
|
||||
disable_extended_io();
|
||||
disable_kb_interrupt();
|
||||
|
||||
if (ISSET(PRESERVE))
|
||||
enable_flow_control();
|
||||
@@ -1489,6 +1296,15 @@ void terminal_init(void)
|
||||
have_new_state = TRUE;
|
||||
} else
|
||||
tcsetattr(0, TCSANOW, &desired_state);
|
||||
|
||||
SLang_init_tty(-1, 0, 0);
|
||||
#endif
|
||||
disable_kb_interrupt();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Tell the terminal to enable bracketed pastes. */
|
||||
printf("\e[?2004h");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1540,14 +1356,24 @@ void unbound_key(int code)
|
||||
else if (meta_key) {
|
||||
if (code == '[')
|
||||
statusline(ALERT, _("Unbindable key: M-["));
|
||||
#ifndef NANO_TINY
|
||||
else if (code < 0x20)
|
||||
statusline(ALERT, _("Unbindable key: M-^%c"), code + 0x40);
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
else if (shifted_metas && 'A' <= code && code <= 'Z')
|
||||
statusline(ALERT, _("Unbound key: Sh-M-%c"), code);
|
||||
#endif
|
||||
else
|
||||
statusline(ALERT, _("Unbound key: M-%c"), toupper(code));
|
||||
} else if (code == ESC_CODE)
|
||||
statusline(ALERT, _("Unbindable key: ^["));
|
||||
else if (code < 0x20)
|
||||
statusline(ALERT, _("Unbound key: ^%c"), code + 0x40);
|
||||
#if defined(ENABLE_BROWSER) || defined (ENABLE_HELP)
|
||||
else
|
||||
statusline(ALERT, _("Unbound key: %c"), code);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
@@ -1631,6 +1457,42 @@ bool okay_for_view(const keystruct *shortcut)
|
||||
return (item == NULL || item->viewok);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Read in all waiting input bytes and paste them into the buffer in one go. */
|
||||
void suck_up_input_and_paste_it(void)
|
||||
{
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
linestruct *line = make_new_node(NULL);
|
||||
size_t index = 0;
|
||||
|
||||
line->data = copy_of("");
|
||||
cutbuffer = line;
|
||||
|
||||
while (bracketed_paste) {
|
||||
int input = get_kbinput(edit, BLIND);
|
||||
|
||||
if (input == CR_CODE) {
|
||||
line->next = make_new_node(line);
|
||||
line = line->next;
|
||||
line->data = copy_of("");
|
||||
index = 0;
|
||||
} else if ((0x20 <= input && input <= 0xFF && input != DEL_CODE) ||
|
||||
input == TAB_CODE) {
|
||||
line->data = charealloc(line->data, index + 2);
|
||||
line->data[index++] = (char)input;
|
||||
line->data[index] = '\0';
|
||||
} else if (input != BRACKETED_PASTE_MARKER)
|
||||
beep();
|
||||
}
|
||||
|
||||
cutbottom = line;
|
||||
|
||||
paste_text();
|
||||
|
||||
cutbuffer = was_cutbuffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read in a keystroke. Act on the keystroke if it is a shortcut or a toggle;
|
||||
* otherwise, insert it into the edit buffer. */
|
||||
void do_input(void)
|
||||
@@ -1702,9 +1564,9 @@ void do_input(void)
|
||||
if (shortcut || get_key_buffer_len() == 0) {
|
||||
if (puddle != NULL) {
|
||||
/* Insert all bytes in the input buffer into the edit buffer
|
||||
* at once, filtering out any low control codes. */
|
||||
* at once, filtering out any ASCII control codes. */
|
||||
puddle[depth] = '\0';
|
||||
do_output(puddle, depth, FALSE);
|
||||
inject(puddle, depth, TRUE);
|
||||
|
||||
/* Empty the input buffer. */
|
||||
free(puddle);
|
||||
@@ -1786,12 +1648,16 @@ void do_input(void)
|
||||
if (!refresh_needed && (shortcut->func == do_delete ||
|
||||
shortcut->func == do_backspace))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (bracketed_paste)
|
||||
suck_up_input_and_paste_it();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The user typed output_len multibyte characters. Add them to the edit
|
||||
* buffer, filtering out all ASCII control characters if allow_cntrls is
|
||||
* TRUE. */
|
||||
void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
* buffer, filtering out ASCII control characters when filtering is TRUE. */
|
||||
void inject(char *output, size_t output_len, bool filtering)
|
||||
{
|
||||
char onechar[MAXCHARLEN];
|
||||
int charlen;
|
||||
@@ -1818,7 +1684,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
i += charlen;
|
||||
|
||||
/* If controls are not allowed, ignore an ASCII control character. */
|
||||
if (!allow_cntrls && is_ascii_cntrl_char(*(output + i - charlen)))
|
||||
if (filtering && is_ascii_cntrl_char(*(output + i - charlen)))
|
||||
continue;
|
||||
|
||||
/* Make room for the new character and copy it into the line. */
|
||||
@@ -1910,8 +1776,10 @@ int main(int argc, char **argv)
|
||||
bool fill_used = FALSE;
|
||||
/* Was the fill option used on the command line? */
|
||||
#endif
|
||||
#ifdef ENABLE_WRAPPING
|
||||
int hardwrap = -2;
|
||||
/* Becomes 0 when --nowrap and 1 when --breaklonglines is used. */
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
int quoterc;
|
||||
/* Whether the quoting regex was compiled successfully. */
|
||||
@@ -1944,7 +1812,10 @@ int main(int argc, char **argv)
|
||||
{"constantshow", 0, NULL, 'c'},
|
||||
{"rebinddelete", 0, NULL, 'd'},
|
||||
{"emptyline", 0, NULL, 'e'},
|
||||
#ifdef ENABLE_BROWSER
|
||||
#ifdef ENABLE_NANORC
|
||||
{"rcfile", 1, NULL, 'f'},
|
||||
#endif
|
||||
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
||||
{"showcursor", 0, NULL, 'g'},
|
||||
#endif
|
||||
{"help", 0, NULL, 'h'},
|
||||
@@ -2050,10 +1921,8 @@ int main(int argc, char **argv)
|
||||
if (*(tail(argv[0])) == 'r')
|
||||
SET(RESTRICTED);
|
||||
|
||||
while ((optchr =
|
||||
getopt_long(argc, argv,
|
||||
"ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Zabcdeghijklmno:pr:s:tuvwxyz$",
|
||||
long_options, NULL)) != -1) {
|
||||
while ((optchr = getopt_long(argc, argv, "ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Z"
|
||||
"abcdef:ghijklmno:pr:s:tuvwxyz$", long_options, NULL)) != -1) {
|
||||
switch (optchr) {
|
||||
#ifndef NANO_TINY
|
||||
case 'A':
|
||||
@@ -2192,9 +2061,16 @@ int main(int argc, char **argv)
|
||||
case 'e':
|
||||
SET(EMPTY_LINE);
|
||||
break;
|
||||
#ifdef ENABLE_NANORC
|
||||
case 'f':
|
||||
custom_nanorc = mallocstrcpy(custom_nanorc, optarg);
|
||||
break;
|
||||
#endif
|
||||
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
||||
case 'g':
|
||||
SET(SHOW_CURSOR);
|
||||
break;
|
||||
#endif
|
||||
case 'h':
|
||||
usage();
|
||||
exit(0);
|
||||
@@ -2386,10 +2262,12 @@ int main(int argc, char **argv)
|
||||
}
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
#ifdef ENABLE_WRAPPING
|
||||
if (hardwrap == 0)
|
||||
UNSET(BREAK_LONG_LINES);
|
||||
else if (hardwrap == 1)
|
||||
SET(BREAK_LONG_LINES);
|
||||
#endif
|
||||
|
||||
/* If the user wants bold instead of reverse video for hilited text... */
|
||||
if (ISSET(BOLD_TEXT))
|
||||
@@ -2695,9 +2573,15 @@ int main(int argc, char **argv)
|
||||
statusbar(_("Welcome to nano. For basic help, type Ctrl+G."));
|
||||
#endif
|
||||
|
||||
we_are_running = TRUE;
|
||||
|
||||
while (TRUE) {
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
confirm_margin();
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
if (on_a_vt && get_key_buffer_len() == 0)
|
||||
mute_modifiers = FALSE;
|
||||
#endif
|
||||
if (currmenu != MMAIN)
|
||||
bottombars(MMAIN);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* nano.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -422,8 +422,6 @@ typedef struct rcoption {
|
||||
typedef struct keystruct {
|
||||
const char *keystr;
|
||||
/* The string that describes the keystroke, like "^C" or "M-R". */
|
||||
bool meta;
|
||||
/* Whether this is a Meta keystroke. */
|
||||
int keycode;
|
||||
/* The integer that, together with meta, identifies the keystroke. */
|
||||
int menus;
|
||||
@@ -569,6 +567,7 @@ enum
|
||||
/* Basic control codes. */
|
||||
#define BS_CODE 0x08
|
||||
#define TAB_CODE 0x09
|
||||
#define CR_CODE 0x0D
|
||||
#define ESC_CODE 0x1B
|
||||
#define DEL_CODE 0x7F
|
||||
|
||||
@@ -610,6 +609,9 @@ enum
|
||||
/* A special keycode for when <Tab> is pressed while the mark is on. */
|
||||
#define INDENT_KEY 0x4F1
|
||||
|
||||
/* A special keycode to signal the beginning and end of a bracketed paste. */
|
||||
#define BRACKETED_PASTE_MARKER 0x4FB
|
||||
|
||||
#ifdef USE_SLANG
|
||||
#ifdef ENABLE_UTF8
|
||||
#define KEY_BAD 0xFF /* Clipped error code. */
|
||||
|
||||
45
src/prompt.c
45
src/prompt.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* prompt.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2018 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -24,18 +24,18 @@
|
||||
#include <string.h>
|
||||
|
||||
static char *prompt = NULL;
|
||||
/* The prompt string used for statusbar questions. */
|
||||
/* The prompt string used for status-bar questions. */
|
||||
static size_t typing_x = HIGHEST_POSITIVE;
|
||||
/* The cursor position in answer. */
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
/* Handle a mouse click on the statusbar prompt or the shortcut list. */
|
||||
/* Handle a mouse click on the status-bar prompt or the shortcut list. */
|
||||
int do_statusbar_mouse(void)
|
||||
{
|
||||
int click_row, click_col;
|
||||
int retval = get_mouseinput(&click_row, &click_col, TRUE);
|
||||
|
||||
/* We can click on the statusbar window text to move the cursor. */
|
||||
/* We can click on the status-bar window text to move the cursor. */
|
||||
if (retval == 0 && wmouse_trafo(bottomwin, &click_row, &click_col, FALSE)) {
|
||||
size_t start_col = breadth(prompt) + 2;
|
||||
|
||||
@@ -115,7 +115,7 @@ int do_statusbar_input(bool *finished)
|
||||
if ((shortcut || get_key_buffer_len() == 0) && kbinput != NULL) {
|
||||
/* Inject all characters in the input buffer at once, filtering out
|
||||
* control characters. */
|
||||
do_statusbar_output(kbinput, kbinput_len, TRUE);
|
||||
inject_into_answer(kbinput, kbinput_len, TRUE);
|
||||
|
||||
/* Empty the input buffer. */
|
||||
kbinput_len = 0;
|
||||
@@ -185,8 +185,7 @@ int do_statusbar_input(bool *finished)
|
||||
|
||||
/* The user typed input_len multibyte characters. Add them to the answer,
|
||||
* filtering out ASCII control characters if filtering is TRUE. */
|
||||
void do_statusbar_output(int *the_input, size_t input_len,
|
||||
bool filtering)
|
||||
void inject_into_answer(int *the_input, size_t input_len, bool filtering)
|
||||
{
|
||||
char *output = charalloc(input_len + 1);
|
||||
char onechar[MAXCHARLEN];
|
||||
@@ -340,7 +339,7 @@ void do_statusbar_verbatim_input(void)
|
||||
|
||||
kbinput = get_verbatim_kbinput(bottomwin, &kbinput_len);
|
||||
|
||||
do_statusbar_output(kbinput, kbinput_len, FALSE);
|
||||
inject_into_answer(kbinput, kbinput_len, FALSE);
|
||||
|
||||
free(kbinput);
|
||||
}
|
||||
@@ -363,7 +362,7 @@ void do_statusbar_uncut_text(void)
|
||||
}
|
||||
|
||||
/* Return the column number of the first character of the answer that is
|
||||
* displayed in the statusbar when the cursor is at the given column,
|
||||
* displayed in the status bar when the cursor is at the given column,
|
||||
* with the available room for the answer starting at base. Note that
|
||||
* (0 <= column - get_statusbar_page_start(column) < COLS). */
|
||||
size_t get_statusbar_page_start(size_t base, size_t column)
|
||||
@@ -436,7 +435,7 @@ void add_or_remove_pipe_symbol_from_answer(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get a string of input at the statusbar prompt. */
|
||||
/* Get a string of input at the status-bar prompt. */
|
||||
functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
bool allow_files, bool *listed, linestruct **history_list,
|
||||
void (*refresh_func)(void))
|
||||
@@ -548,9 +547,13 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
* the help viewer or display a message indicating that help
|
||||
* is disabled, which means that finished has been set to TRUE.
|
||||
* Set it back to FALSE here, so that we aren't kicked out of
|
||||
* the statusbar prompt. */
|
||||
* the status-bar prompt. */
|
||||
finished = FALSE;
|
||||
}
|
||||
#ifndef NANO_TINY
|
||||
else if (func == do_nothing)
|
||||
finished = FALSE;
|
||||
#endif
|
||||
|
||||
/* If we have a shortcut with an associated function, break out if
|
||||
* we're finished after running or trying to run the function. */
|
||||
@@ -575,7 +578,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
return func;
|
||||
}
|
||||
|
||||
/* Ask a question on the statusbar. Return 0 when text was entered,
|
||||
/* Ask a question on the status bar. Return 0 when text was entered,
|
||||
* -1 for a cancelled entry, -2 for a blank string, and the relevant
|
||||
* keycode when a valid shortcut key was pressed.
|
||||
*
|
||||
@@ -591,7 +594,7 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
||||
int retval;
|
||||
functionptrtype func = NULL;
|
||||
bool listed = FALSE;
|
||||
/* Save a possible current statusbar x position and prompt. */
|
||||
/* Save a possible current status-bar x position and prompt. */
|
||||
size_t was_typing_x = typing_x;
|
||||
char *saved_prompt = prompt;
|
||||
|
||||
@@ -645,7 +648,7 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
||||
}
|
||||
|
||||
/* Ask a simple Yes/No (and optionally All) question, specified in msg,
|
||||
* on the statusbar. Return 1 for Yes, 0 for No, 2 for All (if all is
|
||||
* on the status bar. Return 1 for Yes, 0 for No, 2 for All (if all is
|
||||
* TRUE when passed in), and -1 for Cancel. */
|
||||
int do_yesno_prompt(bool all, const char *msg)
|
||||
{
|
||||
@@ -707,6 +710,12 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
/* When not replacing, show the cursor while waiting for a key. */
|
||||
kbinput = get_kbinput(bottomwin, !all);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Accept the first character of an external paste. */
|
||||
if (bracketed_paste && kbinput == BRACKETED_PASTE_MARKER)
|
||||
kbinput = get_kbinput(bottomwin, BLIND);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
letter[index++] = (unsigned char)kbinput;
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -762,6 +771,14 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_MOUSE */
|
||||
else
|
||||
beep();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Ignore the rest of an external paste. */
|
||||
while (bracketed_paste)
|
||||
kbinput = get_kbinput(bottomwin, BLIND);
|
||||
#endif
|
||||
}
|
||||
|
||||
return choice;
|
||||
|
||||
77
src/proto.h
77
src/proto.h
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* proto.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -27,9 +27,19 @@ extern volatile sig_atomic_t the_window_resized;
|
||||
#endif
|
||||
|
||||
extern bool on_a_vt;
|
||||
extern bool shifted_metas;
|
||||
|
||||
extern bool meta_key;
|
||||
extern bool shift_held;
|
||||
extern bool mute_modifiers;
|
||||
extern bool bracketed_paste;
|
||||
|
||||
extern bool started_curses;
|
||||
extern bool we_are_running;
|
||||
extern bool more_than_one;
|
||||
|
||||
extern bool inhelp;
|
||||
extern char *title;
|
||||
|
||||
extern bool focusing;
|
||||
|
||||
@@ -39,23 +49,21 @@ extern bool control_C_was_pressed;
|
||||
|
||||
extern bool suppress_cursorpos;
|
||||
|
||||
extern bool started_curses;
|
||||
|
||||
extern message_type lastmessage;
|
||||
|
||||
extern linestruct *pletion_line;
|
||||
|
||||
extern bool inhelp;
|
||||
extern char *title;
|
||||
|
||||
extern bool more_than_one;
|
||||
|
||||
extern bool also_the_last;
|
||||
|
||||
extern bool is_shorter;
|
||||
extern char *answer;
|
||||
|
||||
extern char *last_search;
|
||||
extern int didfind;
|
||||
|
||||
extern char *present_path;
|
||||
|
||||
extern unsigned flags[4];
|
||||
|
||||
extern int controlleft, controlright;
|
||||
extern int controlup, controldown;
|
||||
extern int controlhome, controlend;
|
||||
@@ -78,12 +86,6 @@ extern ssize_t fill;
|
||||
extern size_t wrap_at;
|
||||
#endif
|
||||
|
||||
extern char *last_search;
|
||||
|
||||
extern char *present_path;
|
||||
|
||||
extern unsigned flags[4];
|
||||
|
||||
extern WINDOW *topwin;
|
||||
extern WINDOW *edit;
|
||||
extern WINDOW *bottomwin;
|
||||
@@ -120,14 +122,10 @@ extern regex_t quotereg;
|
||||
|
||||
extern char *word_chars;
|
||||
|
||||
extern char *answer;
|
||||
|
||||
extern ssize_t tabsize;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern char *backup_dir;
|
||||
extern const char *locking_prefix;
|
||||
extern const char *locking_suffix;
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
extern char *operating_dir;
|
||||
@@ -176,6 +174,9 @@ extern char *statedir;
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
extern char *startup_problem;
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
extern char *custom_nanorc;
|
||||
#endif
|
||||
|
||||
extern bool spotlighted;
|
||||
extern size_t light_from_col;
|
||||
@@ -257,6 +258,12 @@ void do_backspace(void);
|
||||
#ifndef NANO_TINY
|
||||
void chop_previous_word(void);
|
||||
void chop_next_word(void);
|
||||
#endif
|
||||
void extract_segment(linestruct *top, size_t top_x,
|
||||
linestruct *bot, size_t bot_x);
|
||||
void ingraft_buffer(linestruct *somebuffer);
|
||||
void copy_from_buffer(linestruct *somebuffer);
|
||||
#ifndef NANO_TINY
|
||||
void cut_marked(bool *right_side_up);
|
||||
#endif
|
||||
void do_snip(bool copying, bool marked, bool until_eof, bool append);
|
||||
@@ -271,12 +278,15 @@ void paste_text(void);
|
||||
|
||||
/* Most functions in files.c. */
|
||||
void make_new_buffer(void);
|
||||
void set_modified(void);
|
||||
#ifndef NANO_TINY
|
||||
int delete_lockfile(const char *lockfilename);
|
||||
#endif
|
||||
bool open_buffer(const char *filename, bool new_buffer);
|
||||
#ifdef ENABLE_SPELLER
|
||||
bool replace_buffer(const char *filename, undo_type action, bool marked,
|
||||
const char *operation);
|
||||
#endif
|
||||
void set_modified(void);
|
||||
void prepare_for_display(void);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void mention_name_and_linecount(void);
|
||||
@@ -296,8 +306,6 @@ bool outside_of_confinement(const char *currpath, bool allow_tabcomp);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void init_backup_dir(void);
|
||||
int delete_lockfile(const char *lockfilename);
|
||||
int write_lockfile(const char *lockfilename, const char *origfilename, bool modified);
|
||||
#endif
|
||||
int copy_file(FILE *inn, FILE *out, bool close_out);
|
||||
bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
@@ -324,8 +332,10 @@ int the_code_for(void (*func)(void), int defaultval);
|
||||
size_t shown_entries_for(int menu);
|
||||
const keystruct *get_shortcut(int *kbinput);
|
||||
functionptrtype func_from_key(int *kbinput);
|
||||
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
||||
functionptrtype interpret(int *keycode);
|
||||
#endif
|
||||
int keycode_from_string(const char *keystring);
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode);
|
||||
void shortcut_init(void);
|
||||
const char *flagtostr(int flag);
|
||||
|
||||
@@ -334,7 +344,6 @@ const char *flagtostr(int flag);
|
||||
void wrap_help_text_into_buffer(void);
|
||||
void help_init(void);
|
||||
functionptrtype parse_help_input(int *kbinput);
|
||||
size_t help_line_len(const char *ptr);
|
||||
#endif
|
||||
void do_help(void);
|
||||
|
||||
@@ -395,11 +404,8 @@ linestruct *copy_buffer(const linestruct *src);
|
||||
void free_lines(linestruct *src);
|
||||
void renumber_from(linestruct *line);
|
||||
void partition_buffer(linestruct *top, size_t top_x,
|
||||
linestruct *bot, size_t bot_x);
|
||||
linestruct *bot, size_t bot_x);
|
||||
void unpartition_buffer(void);
|
||||
void extract(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x);
|
||||
void ingraft_buffer(linestruct *somebuffer);
|
||||
void copy_from_buffer(linestruct *somebuffer);
|
||||
void print_view_warning(void);
|
||||
bool in_restricted_mode(void);
|
||||
#ifndef ENABLE_HELP
|
||||
@@ -438,10 +444,10 @@ void confirm_margin(void);
|
||||
#endif
|
||||
void unbound_key(int code);
|
||||
bool okay_for_view(const keystruct *shortcut);
|
||||
void do_output(char *output, size_t output_len, bool allow_cntrls);
|
||||
void inject(char *output, size_t output_len, bool filtering);
|
||||
|
||||
/* Most functions in prompt.c. */
|
||||
void do_statusbar_output(int *the_input, size_t input_len, bool filtering);
|
||||
void inject_into_answer(int *the_input, size_t input_len, bool filtering);
|
||||
void do_statusbar_home(void);
|
||||
void do_statusbar_end(void);
|
||||
void do_statusbar_left(void);
|
||||
@@ -603,15 +609,11 @@ linestruct *line_from_number(ssize_t lineno);
|
||||
void record_macro(void);
|
||||
void run_macro(void);
|
||||
size_t get_key_buffer_len(void);
|
||||
void put_back(int keycode);
|
||||
void unget_kbinput(int kbinput, bool metakey);
|
||||
#ifdef ENABLE_NANORC
|
||||
void implant(const char *string);
|
||||
#endif
|
||||
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);
|
||||
int get_kbinput(WINDOW *win, bool showcursor);
|
||||
int get_byte_kbinput(int kbinput);
|
||||
int get_control_kbinput(int kbinput);
|
||||
int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
|
||||
@@ -677,10 +679,11 @@ void backwards_void(void);
|
||||
void flip_replace(void);
|
||||
void flip_goto(void);
|
||||
#ifdef ENABLE_BROWSER
|
||||
void to_files_void(void);
|
||||
void goto_dir_void(void);
|
||||
void to_files(void);
|
||||
void goto_dir(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_nothing(void);
|
||||
void do_toggle_void(void);
|
||||
void dos_format_void(void);
|
||||
void mac_format_void(void);
|
||||
|
||||
123
src/rcfile.c
123
src/rcfile.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* rcfile.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014 Mike Frysinger *
|
||||
* Copyright (C) 2019 Brand Huntsman *
|
||||
* Copyright (C) 2014-2019 Benno Schulenberg *
|
||||
@@ -422,9 +422,9 @@ keystruct *strtosc(const char *input)
|
||||
#ifdef ENABLE_BROWSER
|
||||
else if (!strcmp(input, "tofiles") ||
|
||||
!strcmp(input, "browser"))
|
||||
s->func = to_files_void;
|
||||
s->func = to_files;
|
||||
else if (!strcmp(input, "gotodir"))
|
||||
s->func = goto_dir_void;
|
||||
s->func = goto_dir;
|
||||
else if (!strcmp(input, "firstfile"))
|
||||
s->func = to_first_file;
|
||||
else if (!strcmp(input, "lastfile"))
|
||||
@@ -705,9 +705,8 @@ bool is_universal(void (*func)(void))
|
||||
void parse_binding(char *ptr, bool dobind)
|
||||
{
|
||||
char *keyptr = NULL, *keycopy = NULL, *funcptr = NULL, *menuptr = NULL;
|
||||
keystruct *s, *newsc = NULL;
|
||||
int menu, mask = 0;
|
||||
funcstruct *f;
|
||||
int keycode, menu, mask = 0;
|
||||
keystruct *newsc = NULL;
|
||||
|
||||
check_for_nonempty_syntax();
|
||||
|
||||
@@ -720,30 +719,21 @@ void parse_binding(char *ptr, bool dobind)
|
||||
ptr = parse_next_word(ptr);
|
||||
keycopy = copy_of(keyptr);
|
||||
|
||||
if (keycopy[1] == '\0') {
|
||||
jot_error(N_("Key name is too short"));
|
||||
/* Uppercase either the second or the first character of the key name. */
|
||||
if (keycopy[0] == '^')
|
||||
keycopy[1] = toupper((unsigned char)keycopy[1]);
|
||||
else
|
||||
keycopy[0] = toupper((unsigned char)keycopy[0]);
|
||||
|
||||
/* Verify that the key name is not too short, to allow the next call. */
|
||||
if (keycopy[1] == '\0' || (keycopy[0] == 'M' && keycopy[2] == '\0')) {
|
||||
jot_error(N_("Key name %s is invalid"), keycopy);
|
||||
goto free_things;
|
||||
}
|
||||
|
||||
/* Uppercase only the first two or three characters of the key name. */
|
||||
keycopy[0] = toupper((unsigned char)keycopy[0]);
|
||||
keycopy[1] = toupper((unsigned char)keycopy[1]);
|
||||
if (keycopy[0] == 'M' && keycopy[1] == '-') {
|
||||
if (keycopy[2] == '\0') {
|
||||
jot_error(N_("Key name is too short"));
|
||||
goto free_things;
|
||||
} else
|
||||
keycopy[2] = toupper((unsigned char)keycopy[2]);
|
||||
}
|
||||
keycode = keycode_from_string(keycopy);
|
||||
|
||||
/* Allow the codes for Insert and Delete to be rebound, but apart
|
||||
* from those two only Control, Meta and Function sequences. */
|
||||
if (!strcasecmp(keycopy, "Ins") || !strcasecmp(keycopy, "Del"))
|
||||
keycopy[1] = tolower((unsigned char)keycopy[1]);
|
||||
else if (keycopy[0] != '^' && keycopy[0] != 'M' && keycopy[0] != 'F') {
|
||||
jot_error(N_("Key name must begin with \"^\", \"M\", or \"F\""));
|
||||
goto free_things;
|
||||
} else if (keycode_from_string(keycopy) < 0) {
|
||||
if (keycode < 0) {
|
||||
jot_error(N_("Key name %s is invalid"), keycopy);
|
||||
goto free_things;
|
||||
}
|
||||
@@ -795,30 +785,32 @@ void parse_binding(char *ptr, bool dobind)
|
||||
}
|
||||
|
||||
/* Wipe the given shortcut from the given menu. */
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if ((s->menus & menu) && strcmp(s->keystr, keycopy) == 0)
|
||||
for (keystruct *s = sclist; s != NULL; s = s->next)
|
||||
if ((s->menus & menu) && s->keycode == keycode)
|
||||
s->menus &= ~menu;
|
||||
|
||||
/* When unbinding, we are done now. */
|
||||
if (!dobind)
|
||||
goto free_things;
|
||||
|
||||
/* Tally up the menus where the function exists. */
|
||||
for (f = allfuncs; f != NULL; f = f->next)
|
||||
if (f->func == newsc->func)
|
||||
mask = mask | f->menus;
|
||||
|
||||
/* Limit the given menu to those where the function exists;
|
||||
* first handle three special cases, then the general case. */
|
||||
if (is_universal(newsc->func))
|
||||
menu &= MMOST|MBROWSER;
|
||||
#ifndef NANO_TINY
|
||||
/* Handle the special case of the toggles. */
|
||||
if (newsc->func == do_toggle_void)
|
||||
mask = MMAIN;
|
||||
else if (newsc->func == do_toggle_void)
|
||||
menu &= MMAIN;
|
||||
#endif
|
||||
/* Handle the special case of a key defined as a string. */
|
||||
if (newsc->func == (functionptrtype)implant)
|
||||
mask = MMOST|MBROWSER|MHELP;
|
||||
else if (newsc->func == (functionptrtype)implant)
|
||||
menu &= MMOST|MBROWSER|MHELP;
|
||||
else {
|
||||
/* Tally up the menus where the function exists. */
|
||||
for (funcstruct *f = allfuncs; f != NULL; f = f->next)
|
||||
if (f->func == newsc->func)
|
||||
mask |= f->menus;
|
||||
|
||||
/* Now limit the given menu to those where the function exists. */
|
||||
menu = menu & (is_universal(newsc->func) ? (MMOST|MBROWSER) : mask);
|
||||
menu &= mask;
|
||||
}
|
||||
|
||||
if (!menu) {
|
||||
if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE))
|
||||
@@ -828,11 +820,11 @@ void parse_binding(char *ptr, bool dobind)
|
||||
}
|
||||
|
||||
newsc->menus = menu;
|
||||
assign_keyinfo(newsc, keycopy, 0);
|
||||
newsc->keystr = keycopy;
|
||||
newsc->keycode = keycode;
|
||||
|
||||
/* Disallow rebinding ^[ and frequent escape-sequence starter "Esc [". */
|
||||
if ((!newsc->meta && newsc->keycode == ESC_CODE) ||
|
||||
(newsc->meta && newsc->keycode == '[')) {
|
||||
if (newsc->keycode == ESC_CODE || newsc->keycode == '[') {
|
||||
jot_error(N_("Keystroke %s may not be rebound"), keycopy);
|
||||
free_things:
|
||||
free(keycopy);
|
||||
@@ -843,7 +835,7 @@ void parse_binding(char *ptr, bool dobind)
|
||||
#ifndef NANO_TINY
|
||||
/* If this is a toggle, find and copy its sequence number. */
|
||||
if (newsc->func == do_toggle_void) {
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
for (keystruct *s = sclist; s != NULL; s = s->next)
|
||||
if (s->func == do_toggle_void && s->toggle == newsc->toggle)
|
||||
newsc->ordinal = s->ordinal;
|
||||
} else
|
||||
@@ -970,7 +962,7 @@ void parse_includes(char *ptr)
|
||||
* and set bright to TRUE if that color is bright. */
|
||||
short color_to_short(const char *colorname, bool *bright)
|
||||
{
|
||||
if (strncasecmp(colorname, "bright", 6) == 0) {
|
||||
if (strncmp(colorname, "bright", 6) == 0) {
|
||||
*bright = TRUE;
|
||||
colorname += 6;
|
||||
} else
|
||||
@@ -1067,7 +1059,7 @@ void parse_colors(char *ptr, int rex_flags)
|
||||
bool expectend = FALSE;
|
||||
/* Whether to expect an end= line. */
|
||||
|
||||
if (strncasecmp(ptr, "start=", 6) == 0) {
|
||||
if (strncmp(ptr, "start=", 6) == 0) {
|
||||
ptr += 6;
|
||||
expectend = TRUE;
|
||||
}
|
||||
@@ -1113,7 +1105,7 @@ void parse_colors(char *ptr, int rex_flags)
|
||||
if (!expectend)
|
||||
continue;
|
||||
|
||||
if (ptr == NULL || strncasecmp(ptr, "end=", 4) != 0) {
|
||||
if (ptr == NULL || strncmp(ptr, "end=", 4) != 0) {
|
||||
jot_error(N_("\"start=\" requires a corresponding \"end=\""));
|
||||
return;
|
||||
}
|
||||
@@ -1642,27 +1634,34 @@ bool have_nanorc(const char *path, const char *name)
|
||||
return is_good_file(nanorc);
|
||||
}
|
||||
|
||||
/* First read the system-wide rcfile, then the user's rcfile. */
|
||||
/* Process the nanorc file that was specified on the command line (if any),
|
||||
* and otherwise the system-wide rcfile followed by the user's rcfile. */
|
||||
void do_rcfiles(void)
|
||||
{
|
||||
const char *xdgconfdir;
|
||||
if (custom_nanorc) {
|
||||
nanorc = get_full_path(custom_nanorc);
|
||||
if (access(nanorc, F_OK) != 0)
|
||||
die(_("Specified rcfile does not exist\n"));
|
||||
} else
|
||||
nanorc = mallocstrcpy(nanorc, SYSCONFDIR "/nanorc");
|
||||
|
||||
/* First process the system-wide nanorc, if it exists and is suitable. */
|
||||
nanorc = mallocstrcpy(nanorc, SYSCONFDIR "/nanorc");
|
||||
if (is_good_file(nanorc))
|
||||
parse_one_nanorc();
|
||||
|
||||
get_homedir();
|
||||
xdgconfdir = getenv("XDG_CONFIG_HOME");
|
||||
if (custom_nanorc == NULL) {
|
||||
const char *xdgconfdir = getenv("XDG_CONFIG_HOME");
|
||||
|
||||
/* Now try the to find a nanorc file in the user's home directory or in
|
||||
* the XDG configuration directories, and process the first one found. */
|
||||
if (have_nanorc(homedir, "/" HOME_RC_NAME) ||
|
||||
have_nanorc(xdgconfdir, "/nano/" RCFILE_NAME) ||
|
||||
have_nanorc(homedir, "/.config/nano/" RCFILE_NAME))
|
||||
parse_one_nanorc();
|
||||
else if (homedir == NULL && xdgconfdir == NULL)
|
||||
jot_error(N_("I can't find my home directory! Wah!"));
|
||||
get_homedir();
|
||||
|
||||
/* Now try to find a nanorc file in the user's home directory or in the
|
||||
* XDG configuration directories, and process the first one found. */
|
||||
if (have_nanorc(homedir, "/" HOME_RC_NAME) ||
|
||||
have_nanorc(xdgconfdir, "/nano/" RCFILE_NAME) ||
|
||||
have_nanorc(homedir, "/.config/nano/" RCFILE_NAME))
|
||||
parse_one_nanorc();
|
||||
else if (homedir == NULL && xdgconfdir == NULL)
|
||||
jot_error(N_("I can't find my home directory! Wah!"));
|
||||
}
|
||||
|
||||
check_vitals_mapped();
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* search.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2018 Benno Schulenberg *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2019 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
src/text.c
55
src/text.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* text.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2015 Mark Majeres *
|
||||
* Copyright (C) 2016 Mike Scalora *
|
||||
* Copyright (C) 2016 Sumedh Pendurkar *
|
||||
@@ -69,7 +69,7 @@ void do_tab(void)
|
||||
{
|
||||
#ifdef ENABLE_COLOR
|
||||
if (openfile->syntax && openfile->syntax->tab)
|
||||
do_output(openfile->syntax->tab, strlen(openfile->syntax->tab), TRUE);
|
||||
inject(openfile->syntax->tab, strlen(openfile->syntax->tab), FALSE);
|
||||
else
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
@@ -80,12 +80,12 @@ void do_tab(void)
|
||||
memset(spaces, ' ', length);
|
||||
spaces[length] = '\0';
|
||||
|
||||
do_output(spaces, length, TRUE);
|
||||
inject(spaces, length, FALSE);
|
||||
|
||||
free(spaces);
|
||||
} else
|
||||
#endif
|
||||
do_output((char *)"\t", 1, TRUE);
|
||||
inject((char *)"\t", 1, FALSE);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -627,7 +627,6 @@ void do_undo(void)
|
||||
openfile->mark_x = u->mark_begin_x;
|
||||
goto_line_posx(u->lineno, u->begin);
|
||||
cut_marked(NULL);
|
||||
free_lines(u->cutbuffer);
|
||||
u->cutbuffer = cutbuffer;
|
||||
cutbuffer = oldcutbuffer;
|
||||
break;
|
||||
@@ -2050,7 +2049,7 @@ void do_justify(bool full_justify)
|
||||
|
||||
/* Do the equivalent of a marked cut into an empty cutbuffer. */
|
||||
cutbuffer = NULL;
|
||||
extract(first_par_line, top_x, last_par_line, bot_x);
|
||||
extract_segment(first_par_line, top_x, last_par_line, bot_x);
|
||||
#ifndef NANO_TINY
|
||||
update_undo(CUT);
|
||||
|
||||
@@ -2359,8 +2358,6 @@ const char *do_int_speller(const char *tempfile_name)
|
||||
if (pipe(spell_fd) == -1 || pipe(sort_fd) == -1 || pipe(uniq_fd) == -1)
|
||||
return _("Could not create pipe");
|
||||
|
||||
statusbar(_("Creating misspelled word list, please wait..."));
|
||||
|
||||
/* Fork a process to run spell in. */
|
||||
if ((pid_spell = fork()) == 0) {
|
||||
/* Child: open the temporary file that holds the text to be checked. */
|
||||
@@ -2447,6 +2444,9 @@ const char *do_int_speller(const char *tempfile_name)
|
||||
return _("Could not get size of pipe buffer");
|
||||
}
|
||||
|
||||
/* Leave curses mode so that error messages go to the original screen. */
|
||||
endwin();
|
||||
|
||||
/* Block SIGWINCHes while reading misspelled words from the third pipe. */
|
||||
block_sigwinch(TRUE);
|
||||
|
||||
@@ -2467,6 +2467,10 @@ const char *do_int_speller(const char *tempfile_name)
|
||||
|
||||
block_sigwinch(FALSE);
|
||||
|
||||
/* Re-enter curses mode. */
|
||||
terminal_init();
|
||||
doupdate();
|
||||
|
||||
/* Do any replacements case-sensitively, forward, and without regexes. */
|
||||
SET(CASE_SENSITIVE);
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
@@ -3008,7 +3012,8 @@ void do_linter(void)
|
||||
last_wait = time(NULL);
|
||||
statusline(NOTICE, curlint->msg);
|
||||
}
|
||||
}
|
||||
} else
|
||||
beep();
|
||||
}
|
||||
|
||||
for (curlint = lints; curlint != NULL;) {
|
||||
@@ -3117,7 +3122,7 @@ void do_wordlinechar_count(void)
|
||||
openfile->current = was_current;
|
||||
openfile->current_x = was_x;
|
||||
|
||||
/* Display the total word, line, and character counts on the statusbar. */
|
||||
/* Display the total word, line, and character counts on the status bar. */
|
||||
statusline(HUSH, _("%sWords: %zu Lines: %zd Chars: %zu"), openfile->mark ?
|
||||
_("In Selection: ") : "", words, lines, chars);
|
||||
}
|
||||
@@ -3127,8 +3132,8 @@ void do_wordlinechar_count(void)
|
||||
void do_verbatim_input(void)
|
||||
{
|
||||
int *kbinput;
|
||||
size_t kbinput_len, i;
|
||||
char *output;
|
||||
size_t count;
|
||||
char *keycodes;
|
||||
|
||||
/* TRANSLATORS: This is displayed when the next keystroke will be
|
||||
* inserted verbatim. */
|
||||
@@ -3136,27 +3141,25 @@ void do_verbatim_input(void)
|
||||
place_the_cursor();
|
||||
|
||||
/* Read in all the verbatim characters. */
|
||||
kbinput = get_verbatim_kbinput(edit, &kbinput_len);
|
||||
kbinput = get_verbatim_kbinput(edit, &count);
|
||||
|
||||
/* Unsuppress cursor-position display or blank the statusbar. */
|
||||
/* Unsuppress cursor-position display or blank the status bar. */
|
||||
if (ISSET(CONSTANT_SHOW))
|
||||
suppress_cursorpos = FALSE;
|
||||
else
|
||||
wipe_statusbar();
|
||||
|
||||
/* Display all the verbatim characters at once, not filtering out
|
||||
* control characters. */
|
||||
output = charalloc(kbinput_len + 1);
|
||||
keycodes = charalloc(count + 1);
|
||||
|
||||
for (i = 0; i < kbinput_len; i++)
|
||||
output[i] = (char)kbinput[i];
|
||||
output[i] = '\0';
|
||||
for (size_t i = 0; i < count; i++)
|
||||
keycodes[i] = (char)kbinput[i];
|
||||
keycodes[count] = '\0';
|
||||
|
||||
/* Insert the keystroke verbatim, without filtering control characters. */
|
||||
inject(keycodes, count, FALSE);
|
||||
|
||||
free(keycodes);
|
||||
free(kbinput);
|
||||
|
||||
do_output(output, kbinput_len, TRUE);
|
||||
|
||||
free(output);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
@@ -3300,8 +3303,8 @@ void complete_a_word(void)
|
||||
UNSET(BREAK_LONG_LINES);
|
||||
#endif
|
||||
/* Inject the completion into the buffer. */
|
||||
do_output(&completion[shard_length],
|
||||
strlen(completion) - shard_length, FALSE);
|
||||
inject(&completion[shard_length],
|
||||
strlen(completion) - shard_length, TRUE);
|
||||
#ifdef ENABLE_WRAPPING
|
||||
/* If needed, reenable wrapping and wrap the current line. */
|
||||
if (was_set_wrapping) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* utils.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2017, 2019 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 *
|
||||
|
||||
1342
src/winio.c
1342
src/winio.c
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
syntax nanohelp
|
||||
|
||||
# Key combos:
|
||||
color cyan "\^[]/4-8A-Z\^_◀▶▲▼]" "[◀▶▲▼]" "\<M-." "\<F([1-9]|1[0-9]|2[0-4])"
|
||||
color cyan "\^[]/4-8@A-Z\^_`◀▶▲▼]" "[◀▶▲▼]" "\<(M|S[Hh]-[Mm])-." "\<F([1-9]|1[0-9]|2[0-4])"
|
||||
color cyan "\<((Sh-)?Tab|Enter|Ins|(Sh-\^?)?Del|Space|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
|
||||
|
||||
# Quoted indicators:
|
||||
|
||||
@@ -11,8 +11,8 @@ color brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure
|
||||
color yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|selected|status|stripe|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
color brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|stripecolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
color brightgreen "^[[:space:]]*set[[:space:]]+(fill[[:space:]]+-?[[:digit:]]+|(guidestripe|tabsize)[[:space:]]+[1-9][0-9]*)\>"
|
||||
color brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]/@\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+([[:alpha:]]+|".*")[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
color brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([[:alpha:]]|[]/@\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
color brightgreen "^[[:space:]]*bind[[:space:]]+((\^([A-Za-z]|[]/@\^_`]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+([a-z]+|".*")[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
color brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([A-Za-z]|[]/@\^_`]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
color brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|formatter|linter|tabgives)[[:space:]]+.*"
|
||||
color brightgreen "^[[:space:]]*(syntax[[:space:]]+[^[:blank:]]+|(formatter|linter)[[:space:]]+.+)"
|
||||
color green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|formatter|linter|tabgives|extendsyntax)\>"
|
||||
|
||||
Reference in New Issue
Block a user