Compare commits
171 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
075b7e75bc | ||
|
|
c00431134f | ||
|
|
51065ff24b | ||
|
|
4314feae11 | ||
|
|
410280b089 | ||
|
|
178dd9181f | ||
|
|
d30ca576b7 | ||
|
|
ed520c89bc | ||
|
|
cb44a2bd2c | ||
|
|
a0055f3640 | ||
|
|
b00c1d6110 | ||
|
|
594ef2225f | ||
|
|
9631e858f2 | ||
|
|
26d88ccbb1 | ||
|
|
413b9cb774 | ||
|
|
d3a8d81afb | ||
|
|
e16026eacd | ||
|
|
90f18af8bd | ||
|
|
011e8de480 | ||
|
|
4e8afb2877 | ||
|
|
c7ad5c8d86 | ||
|
|
0b1a766964 | ||
|
|
a7e11495bd | ||
|
|
b56db25a35 | ||
|
|
e3957ee5ee | ||
|
|
2a73b4a050 | ||
|
|
ef7c78910c | ||
|
|
772f1029e5 | ||
|
|
3251a216cd | ||
|
|
00b0316ab8 | ||
|
|
76d90617cc | ||
|
|
f516cddce7 | ||
|
|
60b826e5ee | ||
|
|
fc0fcdea10 | ||
|
|
1dd7b216a0 | ||
|
|
87bf46ffb6 | ||
|
|
a921bdadbf | ||
|
|
0271e4a187 | ||
|
|
076eb6f6af | ||
|
|
e484918ef2 | ||
|
|
fdf095c32f | ||
|
|
81402101d9 | ||
|
|
154742c5e3 | ||
|
|
ec569b4bd0 | ||
|
|
38743b0016 | ||
|
|
68c3aaf2df | ||
|
|
2a97cb9f41 | ||
|
|
af8ffa8c94 | ||
|
|
3ffefbfddc | ||
|
|
8637acb106 | ||
|
|
51a3f78d69 | ||
|
|
4d77e0adbb | ||
|
|
2b8a73348c | ||
|
|
576502a5c5 | ||
|
|
ec9a11c761 | ||
|
|
1c63bf0e38 | ||
|
|
4aa1678f3b | ||
|
|
c60d3bbb97 | ||
|
|
90d4b51837 | ||
|
|
302ea79d1c | ||
|
|
ebeed9c013 | ||
|
|
75dd9bee38 | ||
|
|
9151abcd45 | ||
|
|
3258bb0ff4 | ||
|
|
3f3698640b | ||
|
|
432388b23e | ||
|
|
bad618e537 | ||
|
|
7ae305fdc0 | ||
|
|
7d4f279c04 | ||
|
|
f230c46e5e | ||
|
|
bc5a225678 | ||
|
|
493b334ebb | ||
|
|
7d54207627 | ||
|
|
458933f09e | ||
|
|
2b49a19793 | ||
|
|
fc716156a4 | ||
|
|
2b9f06194f | ||
|
|
631defb8b2 | ||
|
|
a6dae403e6 | ||
|
|
b4dbbe3799 | ||
|
|
4281b6becb | ||
|
|
34b1824822 | ||
|
|
b025f67805 | ||
|
|
40f8ca0d07 | ||
|
|
aae752912e | ||
|
|
3c695664ec | ||
|
|
8a7634f070 | ||
|
|
fa88fcc8f2 | ||
|
|
c2d8641f01 | ||
|
|
3d5e51bcd0 | ||
|
|
95ae124891 | ||
|
|
1a8646393a | ||
|
|
054559dc93 | ||
|
|
fdeab9b4c9 | ||
|
|
f26c121ca9 | ||
|
|
17c16a4bf5 | ||
|
|
46566572d6 | ||
|
|
b4a5fac744 | ||
|
|
f816da413a | ||
|
|
3a0ac428ba | ||
|
|
97ab28a164 | ||
|
|
ccb739dd7d | ||
|
|
1082f2adec | ||
|
|
042b8394a0 | ||
|
|
f2d6e6fa5e | ||
|
|
5390f96900 | ||
|
|
50ed18be17 | ||
|
|
a6365707c0 | ||
|
|
6fad6a17da | ||
|
|
eb757e7c5b | ||
|
|
b554606047 | ||
|
|
e915fb1650 | ||
|
|
4e40ec057e | ||
|
|
bd0026be86 | ||
|
|
a1bef0e953 | ||
|
|
f5693d4151 | ||
|
|
e3807f00a2 | ||
|
|
022cc084a7 | ||
|
|
0f98466e2f | ||
|
|
40c067133a | ||
|
|
36270748dc | ||
|
|
1894c81412 | ||
|
|
e917ef0105 | ||
|
|
3347682fd0 | ||
|
|
7c5b104859 | ||
|
|
3b9a24a7ca | ||
|
|
7d3290fb91 | ||
|
|
df0ae2ace5 | ||
|
|
bc91af2e3c | ||
|
|
48b94d71c7 | ||
|
|
f14be47878 | ||
|
|
c51f5f4bff | ||
|
|
7f8851caa8 | ||
|
|
bfdc31fbb4 | ||
|
|
69d2045c9f | ||
|
|
c63f4c1f58 | ||
|
|
b8dc8d4a37 | ||
|
|
8749ccb469 | ||
|
|
b5c5cde0d4 | ||
|
|
d8c03cd4cd | ||
|
|
1536a76ced | ||
|
|
d2fb371fe2 | ||
|
|
34170611d3 | ||
|
|
23c36ba667 | ||
|
|
31d5cb1118 | ||
|
|
f551c07e7a | ||
|
|
2656f543f4 | ||
|
|
ba79602281 | ||
|
|
094758be15 | ||
|
|
06bbc70d4a | ||
|
|
d256d0cbc0 | ||
|
|
ab6635c3a6 | ||
|
|
416ad4c5fd | ||
|
|
0374708597 | ||
|
|
101987f5c6 | ||
|
|
ad451933c6 | ||
|
|
222e67300e | ||
|
|
d12191db5a | ||
|
|
785efc2087 | ||
|
|
557ad827f9 | ||
|
|
600f81cf98 | ||
|
|
56d98052d1 | ||
|
|
265d3245af | ||
|
|
53d4224be9 | ||
|
|
f813fd0f4d | ||
|
|
e90b40e651 | ||
|
|
07c1e72216 | ||
|
|
7338b45d36 | ||
|
|
c95e5362e6 | ||
|
|
2698a2ba68 | ||
|
|
ff0e01a69e |
182
ChangeLog
182
ChangeLog
@@ -1,3 +1,185 @@
|
||||
Changes between v4.6 and v4.7:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (39):
|
||||
build: add the uploading of PDF and cheatsheet to the release script
|
||||
build: avoid three compiler warnings when using gcc-9.2 or newer
|
||||
build: fix compilation for --enable-tiny --enable-wrapping
|
||||
build: fix compilation on macOS, where 'st_mtim' is unknown
|
||||
build: fix compilation when configured with --disable-justify
|
||||
bump version numbers and add a news item for the 4.7 release
|
||||
display: don't color the space that separates line numbers from text
|
||||
docs: add or improve the 'description' meta tag in the two HTML pages
|
||||
docs: add the 'lang' attribute in the right place to the two HTML pages
|
||||
docs: mention that all keywords in a nanorc file should be in lowercase
|
||||
docs: mention that a negative number after "+" counts from the end
|
||||
gnulib: update to its current upstream state
|
||||
input: make <Tab> indent only when mark and cursor are on different lines
|
||||
justify: distinguish between tabs and spaces when comparing indentation
|
||||
justify: treat consecutive indentations that look the same as the same
|
||||
linter: beep when trying to go beyond first or last message
|
||||
rcfile: accept also function names and menu names only in lowercase
|
||||
rcfile: accept only keywords in all lowercase, for speed of comparison
|
||||
rcfile: demand that function 'exit' is bound in the file browser
|
||||
syntax: nanohelp: colorize also ^/ as a possible keystroke
|
||||
syntax: sh: recognize shell rc files also in dedicated directories
|
||||
tweaks: avoid using strlen() where it is not needed
|
||||
tweaks: drop M-Space and ^Space from the browser's key list
|
||||
tweaks: improve two comments and the ordering of some operands
|
||||
tweaks: move three functions to the file where they are used
|
||||
tweaks: optimize the trimming of trailing whitespace
|
||||
tweaks: remove a stray space
|
||||
tweaks: rename a function, to get out of the way for another rename
|
||||
tweaks: rename a function, to get rid of a useless suffix
|
||||
tweaks: reshuffle a few lines, for brevity or speed or consistency
|
||||
tweaks: reshuffle a few lines, for symmetry with the preceding function
|
||||
tweaks: reshuffle a fragment of code, for efficiency
|
||||
tweaks: reshuffle and rename a few things, to elide duplication
|
||||
tweaks: reshuffle an item, to avoid a lone 'else'
|
||||
tweaks: reshuffle two declarations, for compactness
|
||||
tweaks: slightly streamline the search for a possible wrapping point
|
||||
tweaks: trim or adjust some whitespace in HTML, and add two keywords
|
||||
tweaks: unwrap a few lines, and move some strings to among their peers
|
||||
wrapping: never break in the quoting part nor in the indentation part
|
||||
|
||||
|
||||
Changes between v4.5 and v4.6:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (128):
|
||||
bindings: allow to rebind ^/, even though it is synonymous with ^_
|
||||
bindings: don't hard-bind ^H in the help viewer or the file browser
|
||||
bindings: the 'all' keyword should encompass the browser menu too
|
||||
bindings: the 'all' keyword should include the browser menu always
|
||||
build: fix compilation for --enable-tiny --enable-histories
|
||||
build: fix compilation when configured with --disable-color
|
||||
build: slightly speed up the compilation of the tiny version
|
||||
bump version numbers and add a news item for the 4.6 release
|
||||
chars: add a faster version of the character-parsing function
|
||||
commands: rename 'fixer' to 'formatter', to be less misleading
|
||||
cutting: do nothing when trying to chop a word leftward at start of file
|
||||
display: do refresh the edit window when exiting from the help viewer
|
||||
docs: add a note saying that rebinding ^M or ^I is not advisable
|
||||
docs: add the M-F and M-N keystrokes to the cheatsheet
|
||||
docs: adjust the compilation instructions to two-digit version numbers
|
||||
docs: correct the description of the 'spell' menu
|
||||
docs: document the 'fixer' command, a per-syntax content arranger
|
||||
docs: mention that color rules are applied in the order they are listed
|
||||
docs: mention that 'hunspell' is now the first default spelling program
|
||||
docs: mention that the 'nopauses' option is obsolete
|
||||
docs: remove some excessive detail from the sample nanorc file
|
||||
docs: remove the note about the formatter having been removed
|
||||
feedback: say it when spell check or manipulation did not change anything
|
||||
files: distinguish between read error and write error when prepending
|
||||
files: don't mention the name of the temp file when reading goes wrong
|
||||
files: when opening a file for copying, it should NOT be created
|
||||
formatter: accept the formatted result also upon a nonzero exit status
|
||||
formatter: don't let output from the program pollute the screen
|
||||
gnulib: update to its current upstream state
|
||||
history: don't wait when there is something wrong with the history files
|
||||
linter: report it as an error when running the linting program fails
|
||||
rcfile: allow binding also F17...F24
|
||||
rcfile: process extensions to file-matching commands straightaway
|
||||
restored feature: a per-syntax 'fixer' command that processes the buffer
|
||||
softwrap: when switching to another buffer, re-align the starting column
|
||||
speller: prefer 'hunspell' over 'spell', because it can handle UTF-8
|
||||
speller: when 'spell' is not found, try running 'hunspell -l' instead
|
||||
statusbar: show only the first error message, with dots to indicate more
|
||||
syntax: c: recognize some C++ header files by their Emacs modeline
|
||||
syntax: default: don't colorize stuff between two pairs of brackets
|
||||
syntax: html: add a formatter command, making use of 'tidy'
|
||||
syntax: html: colorize only full attributes, and colorize strings later
|
||||
syntax: javascript: colorize also special values 'null' and 'undefined'
|
||||
syntax: javascript: colorize the boolean values 'true' and 'false' too
|
||||
syntax: nanorc: colorize all arguments of 'fixer' and 'linter' as valid
|
||||
syntax: nanorc: colorize in bright red everything that is invalid
|
||||
syntax: nanorc: colorize only lowercase keywords as valid
|
||||
syntax: nanorc: colorize the 'fixer' command as valid
|
||||
syntax: ruby: colorize also lowercase global/instance variables
|
||||
syntaxes: put the 'linter' and 'formatter' commands on a separate line
|
||||
tweaks: add a helper function without the ubiquitous NULL argument
|
||||
tweaks: add a local variable, for clarity, to not preuse another one
|
||||
tweaks: add some "fall-through" comments, and reshuffle some breaks
|
||||
tweaks: add two translator hints
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: adjust the indentation after the previous change, and another
|
||||
tweaks: adjust two comments, to better fit the actual functions
|
||||
tweaks: avoid setting and resetting a variable when there is no need
|
||||
tweaks: avoid three unneeded calls of umask() in the normal case
|
||||
tweaks: be explicit about which program complained
|
||||
tweaks: check the return value of copy_file() also after its other uses
|
||||
tweaks: close the unused reading ends of two more output pipes
|
||||
tweaks: condense a fragment of code by making use of a helper function
|
||||
tweaks: condense or improve some comments
|
||||
tweaks: condense two comments, and rename two parameters
|
||||
tweaks: condense two comments, and rewrap a line
|
||||
tweaks: correct a comment, and retype a variable
|
||||
tweaks: die on an impossible condition -- to be removed later
|
||||
tweaks: don't do in the parent something that only the child needs
|
||||
tweaks: don't wrap calls of statusline() that slightly overshoot 80 cols
|
||||
tweaks: drop the unneeded closing of descriptors when exiting anyway
|
||||
tweaks: elide a duplicate opening of the existing file when prepending
|
||||
tweaks: elide a function call for the plain ASCII case
|
||||
tweaks: elide another two calls of umask(), and rename two variables
|
||||
tweaks: elide an unneeded and leaky function
|
||||
tweaks: elide an unneeded check when making a backup
|
||||
tweaks: elide a variable, and add a condition to elide an assignment
|
||||
tweaks: elide a variable that is the same as another
|
||||
tweaks: exclude two fragments of code from the tiny version
|
||||
tweaks: fuse two regexes into one
|
||||
tweaks: group the closing of descriptors together, for compactness
|
||||
tweaks: group the closing of two descriptors, and reword two comments
|
||||
tweaks: harmonize a message with another
|
||||
tweaks: improve some comments, and trim some repetitive ones
|
||||
tweaks: make a function do a check so its calls don't need to
|
||||
tweaks: mark two strings for translation
|
||||
tweaks: move a call of umask() closer to where it is relevant
|
||||
tweaks: move two functions to after the one that they make use of
|
||||
tweaks: normalize the indentation after the previous change
|
||||
tweaks: order two functions more sensibly
|
||||
tweaks: pass an empty string as an answer instead of a NULL pointer
|
||||
tweaks: pass an empty string for copying instead of a non-existent one
|
||||
tweaks: pass any special undo/redo messages to the add_undo() function
|
||||
tweaks: remove a pointless updating of the title bar
|
||||
tweaks: remove a redundant check for an existing emergency file
|
||||
tweaks: remove the superfluous closing of a file descriptor
|
||||
tweaks: remove two pointless re-inclusion guards
|
||||
tweaks: remove two superfluous conditions when prepending
|
||||
tweaks: rename a function and add a parameter, so it becomes more general
|
||||
tweaks: rename a function, and elide a parameter that is always NULL
|
||||
tweaks: rename a function and elide its first parameter
|
||||
tweaks: rename a local variable, to not shadow another
|
||||
tweaks: rename a variable, to be a bit more fitting
|
||||
tweaks: rename a variable, to be distinct and visible
|
||||
tweaks: rename three variables, and reshuffle some lines
|
||||
tweaks: rename three variables, to be consistent with other linestructs
|
||||
tweaks: rename three variables, to be more descriptive
|
||||
tweaks: rename three variables, to match others elsewhere
|
||||
tweaks: rename two parameters, for contrast and to match others
|
||||
tweaks: rename two parameters plus a variable, to match others
|
||||
tweaks: rename two variables, and add a third, for more contrast
|
||||
tweaks: reshuffle a few declarations, and reduce the scope of one
|
||||
tweaks: reshuffle a fragment of code into two alternatives
|
||||
tweaks: reshuffle an 'if' to avoid a negation, and improve a comment
|
||||
tweaks: reshuffle some declarations, and rename a variable
|
||||
tweaks: reword an undo/redo string that was overlooked during the rename
|
||||
tweaks: silence a warning when configured with --enable-tiny
|
||||
tweaks: simplify the opening of files when prepending
|
||||
tweaks: slightly reword some fragments in the manual's rebinding section
|
||||
tweaks: use a better variable name for the argument of an option
|
||||
tweaks: use a literal NULL instead of a variable that is NULL
|
||||
tweaks: use a simpler positive/negative check for after copy_file()
|
||||
tweaks: use a string-copy function that checks for out-of-memory
|
||||
tweaks: use the given string instead of the found match, for clarity
|
||||
undo: don't try to copy a string that doesn't exist
|
||||
undo: put the cursor back on the original row for a full-buffer operation
|
||||
utils: don't accept NULL for the string to be copied
|
||||
|
||||
Jeroen Roovers (1):
|
||||
syntax: gentoo: highlight the BDEPEND variable as well
|
||||
|
||||
|
||||
Changes between v4.4 and v4.5:
|
||||
------------------------------
|
||||
|
||||
|
||||
18
NEWS
18
NEWS
@@ -1,3 +1,21 @@
|
||||
2019.12.23 - GNU nano 4.7 "Havikskruid"
|
||||
• A <Tab> will indent a marked region only when mark and cursor are
|
||||
on different lines.
|
||||
• Two indentations (any mix of tabs and spaces) are considered the
|
||||
same when they look the same (that is: indent to the same level).
|
||||
• When using --breaklonglines or ^J, a line will never be broken in
|
||||
its leading whitespace or quoting.
|
||||
• The keywords in nanorc files must be in lowercase.
|
||||
|
||||
2019.11.29 - GNU nano 4.6 "And don't you eat that yellow snow"
|
||||
• The 'formatter' command has returned, bound by default to M-F.
|
||||
It allows running a syntax-specific command on the contents of
|
||||
the buffer.
|
||||
• ^T will try to run 'hunspell' before 'spell', because it checks
|
||||
spellling for the locale's language and understands UTF-8.
|
||||
• Multiple errors or warnings on startup will no longer slow nano
|
||||
down but will be indicated on the status bar with trailing dots.
|
||||
|
||||
2019.10.04 - GNU nano 4.5 "Košice"
|
||||
• The new 'tabgives' command allows you to specify per syntax what
|
||||
the <Tab> key should produce: some spaces, a hard TAB, ...
|
||||
|
||||
6
README
6
README
@@ -25,10 +25,10 @@ Overview
|
||||
|
||||
How to compile and install nano
|
||||
|
||||
Download the nano source code, then:
|
||||
Download the latest nano source tarball, then:
|
||||
|
||||
tar xvzf nano-x.y.z.tar.gz
|
||||
cd nano-x.y.z
|
||||
tar -xvf nano-x.y.tar.gz
|
||||
cd nano-x.y
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="ab02af9d47248a1d8b4ade4e8ab2c927d0543ea1"
|
||||
gnulib_hash="129087dbb4f8721d750d2ec58261c56b2bda2536"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
@@ -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.5], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [4.7], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.14])
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Cheatsheet for nano</title>
|
||||
<meta name="description" content="nano">
|
||||
<meta name="keywords" content="cheatsheet, nano, editor, shortcuts, keystrokes, functions">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="description" content="A concise overview of the command shortcuts of the GNU nano editor, grouped by category.">
|
||||
<meta name="keywords" content="cheatsheet, nano, editor, shortcuts, keystrokes, functions, operations, commands">
|
||||
<meta name="author" content="Benno Schulenberg">
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
<body>
|
||||
|
||||
<br>
|
||||
<h1 align="center">Overview of nano's shortcuts </h1>
|
||||
@@ -21,9 +22,9 @@
|
||||
<b>File handling</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+S </td><td>Save current file</td></tr>
|
||||
<tr><td>Ctrl+O </td><td> Offer to write file ("Save as")</td></tr>
|
||||
<tr><td>Ctrl+R </td><td> Insert a file into current one</td></tr>
|
||||
<tr><td>Ctrl+X </td><td> Close buffer, exit from nano</td></tr>
|
||||
<tr><td>Ctrl+O</td><td>Offer to write file ("Save as")</td></tr>
|
||||
<tr><td>Ctrl+R</td><td>Insert a file into current one</td></tr>
|
||||
<tr><td>Ctrl+X</td><td>Close buffer, exit from nano</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
@@ -66,6 +67,7 @@
|
||||
<tr><td>Ctrl+J</td><td>Justify paragraph or region</td></tr>
|
||||
<tr><td>Alt+J</td><td>Justify entire buffer</td></tr>
|
||||
<tr><td>Alt+B</td><td>Run a syntax check</td></tr>
|
||||
<tr><td>Alt+F</td><td>Run a formatter/fixer/arranger</td></tr>
|
||||
<tr><td>Alt+:</td><td>Start/stop recording of macro</td></tr>
|
||||
<tr><td>Alt+;</td><td>Replay macro</td></tr>
|
||||
</tbody></table>
|
||||
@@ -94,7 +96,7 @@
|
||||
|
||||
<b>Special movement</b>
|
||||
<table><tbody>
|
||||
<tr><td>Alt+G </td><td>Go to specified line</td></tr>
|
||||
<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>
|
||||
@@ -116,6 +118,7 @@
|
||||
<tr><td>Alt+A</td><td>Turn the mark on/off</td></tr>
|
||||
<tr><td>Tab</td><td>Indent marked region</td></tr>
|
||||
<tr><td>Shift+Tab </td><td>Unindent marked region</td></tr>
|
||||
<tr><td>Alt+N</td><td>Turn line numbers on/off</td></tr>
|
||||
<tr><td>Alt+P</td><td>Turn visible whitespace on/off</td></tr>
|
||||
<tr><td>Alt+V</td><td>Enter next keystroke verbatim</td></tr>
|
||||
<tr><td>Ctrl+L</td><td>Refresh the screen</td></tr>
|
||||
|
||||
23
doc/faq.html
23
doc/faq.html
@@ -1,9 +1,12 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>The GNU nano editor FAQ</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="description" content="The genesis story of the nano editor, plus the solution to some common problems.">
|
||||
</head>
|
||||
|
||||
<body text="#330000" bgcolor="#ffffff" link="#0000ef" vlink="#51188e" alink="#ff0000">
|
||||
|
||||
<h1>The GNU nano editor FAQ</h1>
|
||||
@@ -85,7 +88,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.5</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.7</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<h3><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h3>
|
||||
<blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/latest/nano.1.html">here</a>.</p></blockquote>
|
||||
<hr width="100%">
|
||||
@@ -112,7 +115,7 @@
|
||||
<li><a href="https://packages.debian.org/testing/editors/nano">testing</a></li>
|
||||
<li><a href="https://packages.debian.org/unstable/editors/nano">unstable</a></li>
|
||||
</ul>
|
||||
<p>You can also have a look at the <a href="ftp://ftp.debian.org/debian/pool/main/n/nano/">Package Pool</a> to see all the available binary and source packages.</p>
|
||||
<p>You can also have a look at the <a href="http://ftp.debian.org/debian/pool/main/n/nano/">Package Pool</a> to see all the available binary and source packages.</p>
|
||||
</blockquote>
|
||||
<h3><a name="2.4"></a>2.4. By GIT (for the brave).</h3>
|
||||
<blockquote><p>For the 'bleeding edge' current version of nano, you can use GIT to download the current source code. <b>Note:</b> believe it or not, by downloading code that has not yet stabilized into an official release, there could quite possibly be bugs, in fact the code may not even compile! Anyway, see <a href="http://git.savannah.gnu.org/cgit/nano.git/tree/README.GIT">the nano GIT document</a> for info on anonymous GIT access to the nano source.</p></blockquote>
|
||||
@@ -120,13 +123,13 @@
|
||||
|
||||
<h1><a name="3"></a>3. Installation and Configuration</h1>
|
||||
<h3><a name="3.1"></a>3.1. How do I install the RPM or DEB package?</h3>
|
||||
<blockquote><p>It's simple really! As root, type <b>rpm -Uvh nano-x.y.z-1.i386.rpm</b> if you have a RedHat-ish system or <b>dpkg -i nano_x.y.z-1.deb</b> if you have a Debian-ish system, where <b>x.y.z</b> is the release of nano. There are other programs to install packages, and if you wish to use those, knock yourself out.</p></blockquote>
|
||||
<blockquote><p>It's simple really! As root, type <b>rpm -Uvh nano-x.y-1*.rpm</b> if you have a RedHat-ish system or <b>dpkg -i nano_x.y-1*.deb</b> if you have a Debian-ish system, where <b>x.y</b> is the version number of nano. There are other programs to install packages, and if you wish to use those, knock yourself out.</p></blockquote>
|
||||
<h3><a name="3.2"></a>3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h3>
|
||||
<blockquote><p>Okay, take a deep breath, this really isn't hard. Unpack the nano source with a command like:</p>
|
||||
<p><b>tar -xvf nano-x.y.z.tar.gz</b></p>
|
||||
<p><b>tar -xvf nano-x.y.tar.gz</b></p>
|
||||
<p>Then you need to run <b>configure</b> with any options you might want (if any).</p>
|
||||
<p>The average case is this:</p>
|
||||
<p><b>cd nano-x.y.z/</b><br>
|
||||
<p><b>cd nano-x.y/</b><br>
|
||||
<b>./configure</b><br>
|
||||
<b>make</b><br>
|
||||
<b>make install</b> (as root, of course)</p></blockquote>
|
||||
@@ -203,8 +206,8 @@
|
||||
<b>[ ] enable-alternate-editor-implicitly</b></p>
|
||||
<p>Then exit (<b>E</b>) and select Yes (<b>Y</b>).</p>
|
||||
<p>If you're a mutt user, you should see an effect immediately the next time you log in. No further configuration is needed. However, if you want to let people know you use nano to compose your email messages, you can put a line like this in your <b>.muttrc</b>:</p>
|
||||
<p><b>my_hdr X-Composer: nano x.y.z</b></p>
|
||||
<p>Again, replace x.y.z with the version of nano you use.</p></blockquote>
|
||||
<p><b>my_hdr X-Composer: nano-x.y</b></p>
|
||||
<p>Again, replace x.y with the version of nano you use.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="5"></a>5. Internationalization</h1>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 4.5" "October 2019"
|
||||
.TH NANO 1 "version 4.7" "December 2019"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, inspired by Pico
|
||||
@@ -44,6 +44,7 @@ syntax coloring, line numbering, and soft-wrapping overlong lines.
|
||||
When giving a filename on the command line, the cursor can be put on a
|
||||
specific line by adding the line number with a plus sign (\fB+\fR) before
|
||||
the filename, and even in a specific column by adding it with a comma.
|
||||
(Negative numbers count from the end of the file or line.)
|
||||
The cursor can be put on the first or last occurrence of a specific string
|
||||
by specifying that string after \fB+/\fR or \fB+?\fR before the filename.
|
||||
The string can be made case sensitive and/or caused to be interpreted as a
|
||||
@@ -278,7 +279,8 @@ 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"""
|
||||
Use this alternative command to perform spell checking.
|
||||
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
|
||||
.BR \-t ", " \-\-tempfile
|
||||
Save a changed buffer without prompting (when exiting with \fB^X\fR).
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 4.5
|
||||
@set UPDATED October 2019
|
||||
@set VERSION 4.7
|
||||
@set UPDATED December 2019
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 4.5
|
||||
@subtitle version 4.7
|
||||
|
||||
@author Chris Allegretta
|
||||
@page
|
||||
@@ -57,13 +57,13 @@ You may contact the author by
|
||||
e-mail: @email{chrisa@@asty.org}@*
|
||||
@end titlepage
|
||||
|
||||
|
||||
@ifnottex
|
||||
|
||||
|
||||
@node Top
|
||||
@top
|
||||
|
||||
This manual documents the GNU @command{nano} editor, version 4.5.
|
||||
This manual documents the GNU @command{nano} editor, version 4.7.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@@ -128,6 +128,7 @@ section), and to edit several files in a row. Additionally, the cursor
|
||||
can be put on a specific line of a file by adding the line number
|
||||
with a plus sign before the filename, and even in a specific column by
|
||||
adding it with a comma.
|
||||
(Negative numbers count from the end of the file or line.)
|
||||
The cursor can also be put on the first or last occurrence of a specific string
|
||||
by specifying that string after @code{+/} or @code{+?} before the filename.
|
||||
The string can be made case sensitive and/or caused to be interpreted as a
|
||||
@@ -156,6 +157,7 @@ As a special case: when instead of a filename a dash is given, @command{nano}
|
||||
will read data from standard input. This means you can pipe the output of
|
||||
a command straight into a buffer, and then edit it.
|
||||
|
||||
|
||||
@node Command-line Options
|
||||
@chapter Command-line Options
|
||||
|
||||
@@ -402,7 +404,8 @@ 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
|
||||
not specified either, then @command{nano} uses its own interactive spell
|
||||
corrector, which requires the GNU @command{spell} program to be installed.
|
||||
corrector, which requires either @command{hunspell} or GNU @command{spell}
|
||||
to be installed.
|
||||
|
||||
@item -t
|
||||
@itemx --tempfile
|
||||
@@ -614,6 +617,7 @@ The recording and playback of keyboard macros works correctly only on a
|
||||
terminal emulator, not on a Linux console (VT), because the latter does
|
||||
not by default distinguish modified from unmodified arrow keys.
|
||||
|
||||
|
||||
@node Built-in Help
|
||||
@chapter Built-in Help
|
||||
|
||||
@@ -691,6 +695,7 @@ be used to configure @command{nano} on startup without using command-line
|
||||
options. Additionally, there are some commands to define syntax highlighting
|
||||
and to rebind keys --- @pxref{Syntax Highlighting} and @ref{Rebinding Keys}.
|
||||
@command{nano} will read one command per line.
|
||||
All commands and keywords should be written in lowercase.
|
||||
|
||||
Options in nanorc files take precedence over @command{nano}'s defaults, and
|
||||
command-line options override nanorc settings. Also, options that do not
|
||||
@@ -843,8 +848,7 @@ Don't automatically add a newline when a text does not end with one.
|
||||
(This can cause you to save non-POSIX text files.)
|
||||
|
||||
@item set nopauses
|
||||
Don't pause between warnings at startup. This means that only
|
||||
the last one will be visible (when there are multiple ones).
|
||||
Obsolete option. Ignored.
|
||||
|
||||
@item set nowrap
|
||||
Deprecated option since it has become the default setting.
|
||||
@@ -1046,6 +1050,12 @@ 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{}]
|
||||
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{}]
|
||||
Use the given @var{program} to do a syntax check on the current buffer.
|
||||
|
||||
@@ -1077,6 +1087,9 @@ stronger highlight.
|
||||
If your terminal supports transparency, not specifying a "bgcolor"
|
||||
tells @command{nano} to attempt to use a transparent background.
|
||||
|
||||
All coloring commands are applied in the order in which they are specified,
|
||||
which means that later commands can recolor stuff that was colored earlier.
|
||||
|
||||
@item icolor @var{fgcolor},@var{bgcolor} "@var{regex}" @dots{}
|
||||
Same as above, except that the matching is case insensitive.
|
||||
|
||||
@@ -1099,28 +1112,12 @@ to @code{icolor}.
|
||||
@item extendsyntax @var{name} @var{command} [@var{arg} @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}, or @code{linter} command to an already
|
||||
@code{magic}, @code{comment}, @code{linter}, or @code{formatter} 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).
|
||||
|
||||
@end table
|
||||
|
||||
Note: the @code{formatter} command has been removed. It was superseded by
|
||||
a more general mechanism: the filtering of buffer or marked text through
|
||||
an external command. Such filtering is done by typing @code{^R^X} and then
|
||||
preceding your formatter command with the pipe symbol (@code{|}). It has
|
||||
the added advantage that the operation can be undone.
|
||||
|
||||
If you use such a formatting command regularly, you could assign the relevant
|
||||
series of keystrokes to a single key in your nanorc:
|
||||
|
||||
@example
|
||||
bind M-F "^R^X|yourformatcommand^M" main
|
||||
@end example
|
||||
|
||||
(Note that the @key{^R}, @key{^X}, and @key{^M} are each a single, literal
|
||||
control character. You can enter them by preceding each with @key{M-V}.)
|
||||
|
||||
@node Rebinding Keys
|
||||
@section Rebinding Keys
|
||||
|
||||
@@ -1131,7 +1128,7 @@ nanorc file:
|
||||
|
||||
@item bind key function menu
|
||||
Rebinds @code{key} to @code{function} in the context of @code{menu}
|
||||
(or in all menus where the function exists by using @code{all}).
|
||||
(or in all menus where the function exists when @code{all} is used).
|
||||
|
||||
@item bind key "string" menu
|
||||
Makes @code{key} produce @code{string} in the context of @code{menu}
|
||||
@@ -1142,7 +1139,7 @@ with @kbd{M-V}.)
|
||||
|
||||
@item unbind key menu
|
||||
Unbinds @code{key} from @code{menu}
|
||||
(or from all menus where it exists by using @code{all}).
|
||||
(or from all menus where the key exists when @code{all} is used).
|
||||
|
||||
@end table
|
||||
|
||||
@@ -1151,22 +1148,29 @@ The format of @code{key} should be one of:
|
||||
|
||||
@itemize @w{}
|
||||
@item
|
||||
@code{^}@ followed by a Latin letter, by one of several ASCII characters
|
||||
(@@, ], \, ^, or _), or by the word "Space".
|
||||
@code{^@var{X}} ------ where @var{X} is a Latin letter, or one of several
|
||||
ASCII characters (@@, ], \, ^, _), or the word "Space".
|
||||
Example: @code{^C}.
|
||||
|
||||
@item
|
||||
@code{M-}@ followed by any ASCII character except [, or by the word "Space".
|
||||
@code{M-@var{X}} ------ where @var{X} is any ASCII character except [,
|
||||
or the word "Space".
|
||||
Example: @code{M-C}.
|
||||
|
||||
@item
|
||||
@code{F}@ followed by a numeric value from 1 to 16.
|
||||
@code{F@var{n}} ------ where @var{n} is a numeric value from 1 to 24.
|
||||
Example: @code{F10}.
|
||||
(Often, @code{F13} to @code{F24} can be typed as @code{F1} to @code{F12}
|
||||
with Shift.)
|
||||
|
||||
@item
|
||||
the word "Ins" or the word "Del".
|
||||
@code{Ins} or @code{Del}.
|
||||
@end itemize
|
||||
|
||||
Rebinding @code{^M} (Enter) or @code{^I} (Tab) is probably not a good idea.
|
||||
On some terminals it's not possible to rebind @code{^H} (unless @code{--raw}
|
||||
is used) because its keycode is identical to that of the Backspace key.
|
||||
|
||||
@sp 1
|
||||
Valid names for the @code{function} to be bound are:
|
||||
|
||||
@@ -1246,8 +1250,12 @@ Shows the current cursor position: the line, column, and character positions.
|
||||
Counts the number of words, lines and characters in the current buffer.
|
||||
|
||||
@item speller
|
||||
Invokes a spell-checking program, either the default one, or the one
|
||||
defined by @option{--speller} or @code{set speller}.
|
||||
Invokes a spell-checking program, either the default @command{hunspell}
|
||||
or GNU @command{spell}, or the one defined by @option{--speller} or
|
||||
@code{set speller}.
|
||||
|
||||
@item formatter
|
||||
Invokes a full-buffer-processing program (if the active syntax defines one).
|
||||
|
||||
@item linter
|
||||
Invokes a syntax-checking program (if the active syntax defines one).
|
||||
@@ -1531,7 +1539,7 @@ The menu for inserting output from an external command, reached from the insert
|
||||
The help-viewer menu.
|
||||
|
||||
@item spell
|
||||
The interactive spell checker Yes/no menu.
|
||||
The menu of the integrated spell checker where the user can edit a misspelled word.
|
||||
|
||||
@item linter
|
||||
The linter menu.
|
||||
|
||||
81
doc/nanorc.5
81
doc/nanorc.5
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 4.5" "October 2019"
|
||||
.TH NANORC 5 "version 4.7" "December 2019"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
@@ -44,6 +44,7 @@ commands, which can be used to configure nano on startup without using
|
||||
command-line options. Additionally, there are some commands to define
|
||||
syntax highlighting and to rebind keys -- see the two separate sections
|
||||
on those. \fBnano\fP reads one command per line.
|
||||
All commands and keywords should be written in lowercase.
|
||||
.sp
|
||||
Options in \fInanorc\fP files take precedence over nano's defaults, and
|
||||
command-line options override \fInanorc\fP settings. Also, options that
|
||||
@@ -183,8 +184,7 @@ Don't automatically add a newline when a text does not end with one.
|
||||
(This can cause you to save non-POSIX text files.)
|
||||
.TP
|
||||
.B set nopauses
|
||||
Don't pause between warnings at startup. This means that only
|
||||
the last one will be visible (when there are multiple ones).
|
||||
Obsolete option. Ignored.
|
||||
.TP
|
||||
.B set nowrap
|
||||
Deprecated option since it has become the default setting.
|
||||
@@ -262,8 +262,8 @@ When needed, use \fBunset jumpyscrolling\fR instead.
|
||||
Enable soft line wrapping for easier viewing of very long lines.
|
||||
.TP
|
||||
.B set speller """\fIprogram\fR [\fIarg\fR...]\fB"""
|
||||
Use the given \fIprogram\fR to do spell checking and correcting,
|
||||
instead of the built-in corrector that calls \fBspell\fR.
|
||||
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
|
||||
.B set statuscolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Specify the color combination to use for the status bar.
|
||||
@@ -382,6 +382,12 @@ 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...]
|
||||
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...]
|
||||
Use the given \fIprogram\fR to run a syntax check on the current buffer.
|
||||
.TP
|
||||
@@ -411,6 +417,9 @@ one of which must be specified. Valid color names are:
|
||||
You may use the prefix \fBbright\fR for the foreground color to get a
|
||||
stronger highlight. If your terminal supports transparency, not specifying
|
||||
a \fIbgcolor\fP tells \fBnano\fP to attempt to use a transparent background.
|
||||
.sp
|
||||
All coloring commands are applied in the order in which they are specified,
|
||||
which means that later commands can recolor stuff that was colored earlier.
|
||||
.TP
|
||||
.BI "icolor " fgcolor , bgcolor " """ regex """ " \fR...
|
||||
Same as above, except that the matching is case insensitive.
|
||||
@@ -435,36 +444,18 @@ to \fBicolor\fP.
|
||||
.BI extendsyntax " name command " \fR[ "arg " \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, or \fBlinter\fP
|
||||
\fBheader\fP, \fBmagic\fP, \fBcomment\fP, \fBlinter\fP, or \fBformatter\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).
|
||||
|
||||
.P
|
||||
Note: the \fBformatter\fR command has been removed. It was superseded by
|
||||
a more general mechanism: the filtering of buffer or marked text through
|
||||
an external command. Such filtering is done by typing \fB^R^X\fR and then
|
||||
preceding your formatter command with the pipe symbol (\fB|\fR). It has
|
||||
the added advantage that the operation can be undone.
|
||||
.sp
|
||||
If you use such a formatting command regularly, you could assign the relevant
|
||||
series of keystrokes to a single key in your nanorc:
|
||||
.sp
|
||||
.RS
|
||||
.B "bind M\-F \(dq^R^X|yourformatcommand^M\(dq main"
|
||||
.RE
|
||||
.sp
|
||||
(Note that the \fB^R\fR, \fB^X\fR, and \fB^M\fR are each a single, literal
|
||||
control character. You can enter them by preceding each with \fBM\-V\fR.)
|
||||
|
||||
.SH REBINDING KEYS
|
||||
Key bindings can be changed via the following three commands:
|
||||
.RS 3
|
||||
.TP
|
||||
.BI bind " key function menu"
|
||||
Rebinds the key \fIkey\fP to a new function named \fIfunction\fP in the
|
||||
context of menu \fImenu\fP (or in all menus where the function exists
|
||||
by using \fBall\fP).
|
||||
Rebinds the given \fIkey\fP to the given \fIfunction\fP in the given \fImenu\fP
|
||||
(or in all menus where the function exists when \fBall\fP is used).
|
||||
.TP
|
||||
.BI bind " key " """" string """" " menu"
|
||||
Makes the given \fIkey\fR produce the given \fIstring\fR in the given
|
||||
@@ -472,33 +463,38 @@ Makes the given \fIkey\fR produce the given \fIstring\fR in the given
|
||||
The \fIstring\fR can consist of text or commands or a mix of them.
|
||||
(To enter a command into the \fIstring\fR, precede its keystroke
|
||||
with \fBM\-V\fR.)
|
||||
|
||||
.TP
|
||||
.BI unbind " key menu"
|
||||
Unbinds the key \fIkey\fP from the menu named \fImenu\fP (or from all
|
||||
menus where it exists by using \fBall\fP).
|
||||
Unbinds the given \fIkey\fP from the given \fImenu\fP (or from all
|
||||
menus where the key exists when \fBall\fP is used).
|
||||
.RE
|
||||
|
||||
.TP
|
||||
The format of \fIkey\fP should be one of:
|
||||
.RS 3
|
||||
.TP 3
|
||||
.B ^
|
||||
followed by a Latin letter, by one of several ASCII characters
|
||||
(@, ], \\, ^, or _), or by the word "Space".
|
||||
.TP 5
|
||||
.BI ^ X
|
||||
where \fIX\fR is a Latin letter, or one of several ASCII characters
|
||||
(@, ], \\, ^, _), or the word "Space".
|
||||
Example: ^C.
|
||||
.TP
|
||||
.B M\-
|
||||
followed by any ASCII character except [, or by the word "Space".
|
||||
.BI M\- X
|
||||
where \fIX\fR is any ASCII character except [, or the word "Space".
|
||||
Example: M\-C.
|
||||
.TP
|
||||
.B F
|
||||
followed by a numeric value from 1 to 16.
|
||||
.BI F N
|
||||
where \fIN\fR is a numeric value from 1 to 24.
|
||||
Example: F10.
|
||||
(Often, \fBF13\fR to \fBF24\fR can be typed as \fBF1\fR to \fBF12\fR with Shift.)
|
||||
|
||||
.TP
|
||||
the word "Ins" or the word "Del".
|
||||
.BR Ins " or " Del .
|
||||
.RE
|
||||
|
||||
Rebinding \fB^M\fR (Enter) or \fB^I\fR (Tab) is probably not a good idea.
|
||||
On some terminals it's not possible to rebind \fB^H\fR (unless \fB\-\-raw\fR
|
||||
is used) because its keycode is identical to that of the Backspace key.
|
||||
|
||||
.TP
|
||||
Valid \fIfunction\fP names to be bound are:
|
||||
.RS 3
|
||||
@@ -577,8 +573,11 @@ Shows the current cursor position: the line, column, and character positions.
|
||||
Counts the number of words, lines and characters in the current buffer.
|
||||
.TP
|
||||
.B speller
|
||||
Invokes a spell-checking program, either the default one, or the one
|
||||
defined by \fB\-\-speller\fR or \fBset speller\fR.
|
||||
Invokes a spell-checking program, either the default \fBhunspell\fR or GNU
|
||||
\fBspell\fR, or the one defined by \fB\-\-speller\fR or \fBset speller\fR.
|
||||
.TP
|
||||
.B formatter
|
||||
Invokes a full-buffer-processing program (if the active syntax defines one).
|
||||
.TP
|
||||
.B linter
|
||||
Invokes a syntax-checking program (if the active syntax defines one).
|
||||
@@ -860,7 +859,7 @@ The menu for inserting output from an external command, reached from the insert
|
||||
The help-viewer menu.
|
||||
.TP
|
||||
.B spell
|
||||
The interactive spell checker Yes/no menu.
|
||||
The menu of the integrated spell checker where the user can edit a misspelled word.
|
||||
.TP
|
||||
.B linter
|
||||
The linter menu.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 4.5" "October 2019"
|
||||
.TH RNANO 1 "version 4.7" "December 2019"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
|
||||
@@ -97,10 +97,6 @@
|
||||
## Don't automatically add a newline when a file does not end with one.
|
||||
# set nonewlines
|
||||
|
||||
## Don't pause between warnings at startup. Which means that only the
|
||||
## last one will be readable (when there are multiple ones).
|
||||
# set nopauses
|
||||
|
||||
## Set operating directory. nano will not read or write files outside
|
||||
## this directory and its subdirectories. Also, the current directory
|
||||
## is changed to here, so any files are inserted from this dir. A blank
|
||||
@@ -218,44 +214,31 @@
|
||||
|
||||
## Setup of syntax coloring.
|
||||
##
|
||||
## Format:
|
||||
## syntax "name" ["filename regex" ...]
|
||||
##
|
||||
## syntax "short description" ["filename regex" ...]
|
||||
## color|icolor foreground,background "regex" ["regex"...]
|
||||
## [...]
|
||||
##
|
||||
## The "none" syntax is reserved; specifying it on the command line is
|
||||
## the same as not having a syntax at all. The "default" syntax is
|
||||
## special: it takes no filename regexes, and applies to files that
|
||||
## don't match any other syntax's filename regexes.
|
||||
##
|
||||
## color foreground,background "regex" ["regex"...]
|
||||
## or
|
||||
## icolor foreground,background "regex" ["regex"...]
|
||||
##
|
||||
## "color" will do case-sensitive matches, while "icolor" will do
|
||||
## 'color' will do case-sensitive matches, while 'icolor' will do
|
||||
## case-insensitive matches.
|
||||
##
|
||||
## Valid color names ares: white, black, normal, red, blue, green,
|
||||
## yellow, magenta, cyan. For foreground colors, you may use the
|
||||
## prefix "bright" to get a stronger highlight.
|
||||
## All color commands are applied in the order in which they are specified,
|
||||
## meaning that later commands can recolor stuff that was colored earlier.
|
||||
##
|
||||
## Valid color names for foreground and background are: white, black, normal,
|
||||
## red, blue, green, yellow, magenta, cyan. For foreground colors, you may
|
||||
## use the prefix "bright" to get a stronger highlight.
|
||||
##
|
||||
## All regexes (regular expressions) are of the extended type (ERE).
|
||||
##
|
||||
## To use multi-line regexes, use the start="regex" end="regex"
|
||||
## [start="regex" end="regex"...] format.
|
||||
## If the coloring rule should span multiple lines, use the following format:
|
||||
##
|
||||
## If your system supports transparency, not specifying a background
|
||||
## color will use a transparent color. If you don't want this, be sure
|
||||
## to set the background color to black or white.
|
||||
## color fg,bg start="regex" end="regex"
|
||||
##
|
||||
## If you wish, you may put your syntax definitions in separate files.
|
||||
## You can make use of such files as follows:
|
||||
##
|
||||
## include "/path/to/syntax_file.nanorc"
|
||||
##
|
||||
## Unless otherwise noted, the name of the syntax file (without the
|
||||
## ".nanorc" extension) should be the same as the "short description"
|
||||
## name inside that file. These names are kept fairly short to make
|
||||
## them easier to remember and faster to type using nano's -Y option.
|
||||
## include "/path/to/syntax_file.nanorc"
|
||||
|
||||
## To include all existing syntax definitions, you can do:
|
||||
# include "@PKGDATADIR@/*.nanorc"
|
||||
@@ -264,7 +247,7 @@
|
||||
## If <Tab> should always produce four spaces when editing a Python file,
|
||||
## independent of the settings of 'tabsize' and 'tabstospaces':
|
||||
# extendsyntax python tabgives " "
|
||||
#
|
||||
|
||||
## If <Tab> should always produce an actual TAB when editing a Makefile:
|
||||
# extendsyntax makefile tabgives " "
|
||||
|
||||
|
||||
1196
po/nano.pot
1196
po/nano.pot
File diff suppressed because it is too large
Load Diff
1182
po/pt_BR.po
1182
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1184
po/zh_CN.po
1184
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1186
po/zh_TW.po
1186
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION="4.5"
|
||||
VERSION="4.7"
|
||||
|
||||
./configure -C --enable-tiny && make && ./configure -C &&
|
||||
|
||||
@@ -22,6 +22,10 @@ gpg --verify nano-$VERSION.tar.xz.asc &&
|
||||
|
||||
git tag -u A0ACE884 -a v$VERSION -m "the nano $VERSION release" &&
|
||||
|
||||
make pdf && rm -rf doc/nano.t2p &&
|
||||
scp doc/nano.pdf bens@wh0rd.org:nano.pdf &&
|
||||
scp doc/cheatsheet.html bens@wh0rd.org:cheatsheet.html &&
|
||||
|
||||
for file in nano-$VERSION.tar.*z*; do scp $file bens@wh0rd.org:$file; done &&
|
||||
|
||||
gnupload --to ftp.gnu.org:nano nano-$VERSION.tar.*z &&
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
|
||||
static char **filelist = NULL;
|
||||
/* The list of files to display in the file browser. */
|
||||
static size_t filelist_len = 0;
|
||||
@@ -153,9 +153,9 @@ char *do_browser(char *path)
|
||||
/* Simulate a window resize to force a directory reread. */
|
||||
kbinput = KEY_WINCH;
|
||||
#endif
|
||||
} else if (func == do_help_void) {
|
||||
} else if (func == do_help) {
|
||||
#ifdef ENABLE_HELP
|
||||
do_help_void();
|
||||
do_help();
|
||||
#ifndef NANO_TINY
|
||||
/* The window dimensions might have changed, so act as if. */
|
||||
kbinput = KEY_WINCH;
|
||||
@@ -221,7 +221,7 @@ char *do_browser(char *path)
|
||||
selected = filelist_len - 1;
|
||||
} else if (func == goto_dir_void) {
|
||||
/* Ask for the directory to go to. */
|
||||
if (do_prompt(TRUE, FALSE, MGOTODIR, NULL, NULL,
|
||||
if (do_prompt(TRUE, FALSE, MGOTODIR, "", NULL,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
browser_refresh, _("Go To Directory")) < 0) {
|
||||
statusbar(_("Cancelled"));
|
||||
@@ -285,7 +285,7 @@ char *do_browser(char *path)
|
||||
|
||||
/* If it isn't a directory, a file was selected -- we're done. */
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
retval = mallocstrcpy(NULL, filelist[selected]);
|
||||
retval = copy_of(filelist[selected]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ char *do_browser(char *path)
|
||||
/* If the window resized, refresh the file list. */
|
||||
if (kbinput == KEY_WINCH) {
|
||||
/* Remember the selected file, to be able to reselect it. */
|
||||
present_name = mallocstrcpy(NULL, filelist[selected]);
|
||||
present_name = copy_of(filelist[selected]);
|
||||
/* Reread the contents of the current directory. */
|
||||
goto read_directory_contents;
|
||||
}
|
||||
@@ -453,7 +453,6 @@ functionptrtype parse_browser_input(int *kbinput)
|
||||
{
|
||||
if (!meta_key) {
|
||||
switch (*kbinput) {
|
||||
case BS_CODE:
|
||||
case '-':
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
@@ -470,7 +469,7 @@ functionptrtype parse_browser_input(int *kbinput)
|
||||
case 'g':
|
||||
return goto_dir_void;
|
||||
case '?':
|
||||
return do_help_void;
|
||||
return do_help;
|
||||
case 'S':
|
||||
case 's':
|
||||
return do_enter;
|
||||
@@ -547,17 +546,17 @@ void browser_refresh(void)
|
||||
* "(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))
|
||||
info = mallocstrcpy(NULL, "--");
|
||||
info = copy_of("--");
|
||||
else
|
||||
/* TRANSLATORS: Try to keep this at most 7 characters. */
|
||||
info = mallocstrcpy(NULL, _("(dir)"));
|
||||
info = copy_of(_("(dir)"));
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
if (strcmp(thename, "..") == 0) {
|
||||
/* TRANSLATORS: Try to keep this at most 12 characters. */
|
||||
info = mallocstrcpy(NULL, _("(parent dir)"));
|
||||
info = copy_of(_("(parent dir)"));
|
||||
infomaxlen = 12;
|
||||
} else
|
||||
info = mallocstrcpy(NULL, _("(dir)"));
|
||||
info = copy_of(_("(dir)"));
|
||||
} else {
|
||||
off_t result = st.st_size;
|
||||
char modifier;
|
||||
@@ -665,10 +664,10 @@ int filesearch_init(bool forwards)
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
thedefault = mallocstrcpy(NULL, "");
|
||||
thedefault = copy_of("");
|
||||
|
||||
/* Now ask what to search for. */
|
||||
response = do_prompt(FALSE, FALSE, MWHEREISFILE, NULL, &search_history,
|
||||
response = do_prompt(FALSE, FALSE, MWHEREISFILE, "", &search_history,
|
||||
browser_refresh, "%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: A modifier of the Search prompt. */
|
||||
!forwards ? _(" [Backwards]") : "", thedefault);
|
||||
@@ -793,7 +792,7 @@ void to_last_file(void)
|
||||
* The returned string is dynamically allocated, and should be freed. */
|
||||
char *strip_last_component(const char *path)
|
||||
{
|
||||
char *copy = mallocstrcpy(NULL, path);
|
||||
char *copy = copy_of(path);
|
||||
char *last_slash = strrchr(copy, '/');
|
||||
|
||||
if (last_slash != NULL)
|
||||
|
||||
87
src/chars.c
87
src/chars.c
@@ -160,7 +160,7 @@ bool is_word_mbchar(const char *c, bool allow_punct)
|
||||
|
||||
if (word_chars != NULL && *word_chars != '\0') {
|
||||
char symbol[MAXCHARLEN + 1];
|
||||
int symlen = parse_mbchar(c, symbol, NULL);
|
||||
int symlen = collect_char(c, symbol);
|
||||
|
||||
symbol[symlen] = '\0';
|
||||
return (strstr(word_chars, symbol) != NULL);
|
||||
@@ -244,7 +244,7 @@ char *make_mbchar(long code, int *length)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
mb_char = mallocstrncpy(NULL, (char *)&code, 1);
|
||||
mb_char = measured_copy((char *)&code, 1);
|
||||
*length = 1;
|
||||
}
|
||||
|
||||
@@ -286,50 +286,67 @@ size_t mbstrlen(const char *pointer)
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Parse a multibyte character from buf. Return the number of bytes
|
||||
* used. If chr isn't NULL, store the multibyte character in it. If
|
||||
* col isn't NULL, add the character's width (in columns) to it. */
|
||||
int parse_mbchar(const char *buf, char *chr, size_t *col)
|
||||
/* Return the length (in bytes) of the character at the start of the
|
||||
* given string, and return a copy of this character in *thechar. */
|
||||
int collect_char(const char *string, char *thechar)
|
||||
{
|
||||
int length;
|
||||
int charlen;
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
/* If this is a UTF-8 starter byte, get the number of bytes of the character. */
|
||||
if ((signed char)*buf < 0) {
|
||||
length = mblen(buf, MAXCHARLEN);
|
||||
if ((signed char)*string < 0) {
|
||||
charlen = mblen(string, MAXCHARLEN);
|
||||
|
||||
/* When the multibyte sequence is invalid, only take the first byte. */
|
||||
if (length <= 0)
|
||||
length = 1;
|
||||
if (charlen <= 0)
|
||||
charlen = 1;
|
||||
} else
|
||||
#endif
|
||||
length = 1;
|
||||
charlen = 1;
|
||||
|
||||
/* When requested, store the multibyte character in chr. */
|
||||
if (chr != NULL)
|
||||
for (int i = 0; i < length; i++)
|
||||
chr[i] = buf[i];
|
||||
for (int i = 0; i < charlen; i++)
|
||||
thechar[i] = string[i];
|
||||
|
||||
/* When requested, add the width of the character to col. */
|
||||
if (col != NULL) {
|
||||
/* If we have a tab, compute its width in columns based on the
|
||||
* current value of col. */
|
||||
if (*buf == '\t')
|
||||
*col += tabsize - *col % tabsize;
|
||||
/* If we have a control character, it's two columns wide: one
|
||||
* column for the "^", and one for the visible character. */
|
||||
else if (is_cntrl_mbchar(buf))
|
||||
*col += 2;
|
||||
/* If we have a normal character, get its width normally. */
|
||||
else if (length == 1)
|
||||
*col += 1;
|
||||
return charlen;
|
||||
}
|
||||
|
||||
/* Return the length (in bytes) of the character at the start of
|
||||
* the given string, and add this character's width to *column. */
|
||||
int advance_over(const char *string, size_t *column)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
else
|
||||
*col += mbwidth(buf);
|
||||
#endif
|
||||
}
|
||||
if ((signed char)*string < 0) {
|
||||
int charlen = mblen(string, MAXCHARLEN);
|
||||
|
||||
return length;
|
||||
if (charlen > 0) {
|
||||
if (is_cntrl_mbchar(string))
|
||||
*column += 2;
|
||||
else
|
||||
*column += mbwidth(string);
|
||||
} else {
|
||||
charlen = 1;
|
||||
*column += 1;
|
||||
}
|
||||
|
||||
return charlen;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((unsigned char)*string < 0x20) {
|
||||
if (*string == '\t')
|
||||
*column += tabsize - *column % tabsize;
|
||||
else
|
||||
*column += 2;
|
||||
} else if (*string == 0x7F)
|
||||
*column += 2;
|
||||
#ifndef ENABLE_UTF8
|
||||
else if (0x7F < (unsigned char)*string && (unsigned char)*string < 0xA0)
|
||||
*column += 2;
|
||||
#endif
|
||||
else
|
||||
*column += 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the index in buf of the beginning of the multibyte character
|
||||
@@ -593,7 +610,7 @@ bool has_blank_char(const char *string)
|
||||
char symbol[MAXCHARLEN];
|
||||
|
||||
while (*string != '\0') {
|
||||
string += parse_mbchar(string, symbol, NULL);
|
||||
string += collect_char(string, symbol);
|
||||
|
||||
if (is_blank_mbchar(symbol))
|
||||
return TRUE;
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_MAGIC_H
|
||||
#include <magic.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
/* For early versions of ncurses-6.0, use an additional A_PROTECT attribute
|
||||
* for all colors, in order to work around an ncurses miscoloring bug. */
|
||||
#if defined(NCURSES_VERSION_MAJOR) && (NCURSES_VERSION_MAJOR == 6) && \
|
||||
|
||||
21
src/cut.c
21
src/cut.c
@@ -42,7 +42,7 @@ void do_deletion(undo_type action)
|
||||
* line, create a new undo item, otherwise update the existing item. */
|
||||
if (action != openfile->last_action ||
|
||||
openfile->current->lineno != openfile->current_undo->lineno)
|
||||
add_undo(action);
|
||||
add_undo(action, NULL);
|
||||
else
|
||||
update_undo(action);
|
||||
|
||||
@@ -68,13 +68,13 @@ void do_deletion(undo_type action)
|
||||
!ISSET(NO_NEWLINES)) {
|
||||
#ifndef NANO_TINY
|
||||
if (action == BACK)
|
||||
add_undo(BACK);
|
||||
add_undo(BACK, NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(action);
|
||||
add_undo(action, NULL);
|
||||
#endif
|
||||
/* Add the contents of the next line to those of the current one. */
|
||||
openfile->current->data = charealloc(openfile->current->data,
|
||||
@@ -182,7 +182,7 @@ void chop_word(bool forward)
|
||||
openfile->current_x = is_current_x;
|
||||
|
||||
/* Now kill the marked region and a word is gone. */
|
||||
add_undo(CUT);
|
||||
add_undo(CUT, NULL);
|
||||
do_snip(FALSE, TRUE, FALSE, FALSE);
|
||||
update_undo(CUT);
|
||||
|
||||
@@ -194,7 +194,10 @@ void chop_word(bool forward)
|
||||
/* Delete a word leftward. */
|
||||
void chop_previous_word(void)
|
||||
{
|
||||
chop_word(BACKWARD);
|
||||
if (openfile->current->prev == NULL && openfile->current_x == 0)
|
||||
statusbar(_("Nothing was cut"));
|
||||
else
|
||||
chop_word(BACKWARD);
|
||||
}
|
||||
|
||||
/* Delete a word rightward. */
|
||||
@@ -382,7 +385,7 @@ void cut_text(void)
|
||||
* the current cut is not contiguous with the previous cutting. */
|
||||
if (openfile->last_action != CUT || !keep_cutbuffer) {
|
||||
keep_cutbuffer = FALSE;
|
||||
add_undo(CUT);
|
||||
add_undo(CUT, NULL);
|
||||
}
|
||||
|
||||
do_snip(FALSE, openfile->mark != NULL, FALSE, FALSE);
|
||||
@@ -433,7 +436,7 @@ void cut_till_eof(void)
|
||||
return;
|
||||
}
|
||||
|
||||
add_undo(CUT_TO_EOF);
|
||||
add_undo(CUT_TO_EOF, NULL);
|
||||
do_snip(FALSE, FALSE, TRUE, FALSE);
|
||||
update_undo(CUT_TO_EOF);
|
||||
wipe_statusbar();
|
||||
@@ -451,7 +454,7 @@ void zap_text(void)
|
||||
/* Add a new undo item only when the current item is not a ZAP or when
|
||||
* the current zap is not contiguous with the previous zapping. */
|
||||
if (openfile->last_action != ZAP || !keep_cutbuffer)
|
||||
add_undo(ZAP);
|
||||
add_undo(ZAP, NULL);
|
||||
|
||||
/* Use the cutbuffer from the ZAP undo item, so the cut can be undone. */
|
||||
cutbuffer = openfile->current_undo->cutbuffer;
|
||||
@@ -479,7 +482,7 @@ void paste_text(void)
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(PASTE);
|
||||
add_undo(PASTE, NULL);
|
||||
|
||||
if (ISSET(SOFTWRAP))
|
||||
was_leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
|
||||
443
src/files.c
443
src/files.c
@@ -35,7 +35,7 @@
|
||||
/* Verify that the containing directory of the given filename exists. */
|
||||
bool has_valid_path(const char *filename)
|
||||
{
|
||||
char *namecopy = mallocstrcpy(NULL, filename);
|
||||
char *namecopy = copy_of(filename);
|
||||
char *parentdir = dirname(namecopy);
|
||||
struct stat parentinfo;
|
||||
bool validity = FALSE;
|
||||
@@ -86,10 +86,10 @@ void make_new_buffer(void)
|
||||
/* Make the new buffer the current one, and start initializing it. */
|
||||
openfile = newnode;
|
||||
|
||||
openfile->filename = mallocstrcpy(NULL, "");
|
||||
openfile->filename = copy_of("");
|
||||
|
||||
openfile->filetop = make_new_node(NULL);
|
||||
openfile->filetop->data = mallocstrcpy(NULL, "");
|
||||
openfile->filetop->data = copy_of("");
|
||||
openfile->filebot = openfile->filetop;
|
||||
|
||||
openfile->current = openfile->filetop;
|
||||
@@ -244,7 +244,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
lockdata[27] = mypid / (256 * 256 * 256);
|
||||
snprintf(&lockdata[2], 11, "nano %s", VERSION);
|
||||
strncpy(&lockdata[28], mypwuid->pw_name, 16);
|
||||
strncpy(&lockdata[68], myhostname, 31);
|
||||
strncpy(&lockdata[68], myhostname, 32);
|
||||
if (origfilename != NULL)
|
||||
strncpy(&lockdata[108], origfilename, 768);
|
||||
if (modified == TRUE)
|
||||
@@ -293,8 +293,8 @@ int delete_lockfile(const char *lockfilename)
|
||||
* creating the lockfile but we should continue to load the file. */
|
||||
int do_lockfile(const char *filename)
|
||||
{
|
||||
char *namecopy = mallocstrcpy(NULL, filename);
|
||||
char *secondcopy = mallocstrcpy(NULL, filename);
|
||||
char *namecopy = copy_of(filename);
|
||||
char *secondcopy = copy_of(filename);
|
||||
size_t locknamesize = strlen(filename) + strlen(locking_prefix)
|
||||
+ strlen(locking_suffix) + 3;
|
||||
char *lockfilename = charalloc(locknamesize);
|
||||
@@ -349,7 +349,7 @@ int do_lockfile(const char *filename)
|
||||
room = COLS - breadth(question) + 7 - breadth(lockuser) -
|
||||
breadth(lockprog) - breadth(pidstring);
|
||||
if (room < 4)
|
||||
postedname = mallocstrcpy(NULL, "_");
|
||||
postedname = copy_of("_");
|
||||
else if (room < breadth(filename)) {
|
||||
char *fragment = display_string(filename,
|
||||
breadth(filename) - room + 3, room, FALSE, FALSE);
|
||||
@@ -420,8 +420,7 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
if (outside_of_confinement(filename, FALSE)) {
|
||||
statusline(ALERT, _("Can't read file from outside of %s"),
|
||||
operating_dir);
|
||||
statusline(ALERT, _("Can't read file from outside of %s"), operating_dir);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
@@ -513,7 +512,8 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
#ifdef ENABLE_SPELLER
|
||||
/* Open the specified file, and if that succeeds, remove the text of the marked
|
||||
* region or of the entire buffer and read the file contents into its place. */
|
||||
bool replace_buffer(const char *filename, undo_type action, bool marked)
|
||||
bool replace_buffer(const char *filename, undo_type action, bool marked,
|
||||
const char *operation)
|
||||
{
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
int descriptor;
|
||||
@@ -525,8 +525,7 @@ bool replace_buffer(const char *filename, undo_type action, bool marked)
|
||||
return FALSE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(COUPLE_BEGIN);
|
||||
openfile->undotop->strdata = mallocstrcpy(NULL, _("spelling correction"));
|
||||
add_undo(COUPLE_BEGIN, operation);
|
||||
#endif
|
||||
|
||||
/* When nothing is marked, start at the top of the buffer. */
|
||||
@@ -538,7 +537,7 @@ bool replace_buffer(const char *filename, undo_type action, bool marked)
|
||||
/* Throw away the marked region or the whole buffer. */
|
||||
cutbuffer = NULL;
|
||||
#ifndef NANO_TINY
|
||||
add_undo(action);
|
||||
add_undo(action, NULL);
|
||||
#endif
|
||||
do_snip(FALSE, marked, !marked, FALSE);
|
||||
#ifndef NANO_TINY
|
||||
@@ -551,8 +550,7 @@ bool replace_buffer(const char *filename, undo_type action, bool marked)
|
||||
read_file(f, descriptor, filename, TRUE);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(COUPLE_END);
|
||||
openfile->undotop->strdata = mallocstrcpy(NULL, _("spelling correction"));
|
||||
add_undo(COUPLE_END, operation);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
@@ -607,10 +605,12 @@ void redecorate_after_switch(void)
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When not in softwrap mode, make sure firstcolumn is zero. It might
|
||||
* be nonzero if we had softwrap mode on while in this buffer, and then
|
||||
* turned softwrap mode off while in a different buffer. */
|
||||
if (!ISSET(SOFTWRAP))
|
||||
/* While in a different buffer, the screen may have been resized
|
||||
* or softwrap mode maybe have been toggled, so make sure that the
|
||||
* starting column for the first row gets an appropriate value. */
|
||||
if (ISSET(SOFTWRAP))
|
||||
ensure_firstcolumn_is_aligned();
|
||||
else
|
||||
openfile->firstcolumn = 0;
|
||||
#endif
|
||||
|
||||
@@ -677,7 +677,7 @@ char *encode_data(char *buf, size_t buf_len)
|
||||
unsunder(buf, buf_len);
|
||||
buf[buf_len] = '\0';
|
||||
|
||||
return mallocstrcpy(NULL, buf);
|
||||
return copy_of(buf);
|
||||
}
|
||||
|
||||
/* Read the given open file f into the current buffer. filename should be
|
||||
@@ -719,7 +719,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (undoable)
|
||||
add_undo(INSERT);
|
||||
add_undo(INSERT, NULL);
|
||||
|
||||
if (ISSET(SOFTWRAP))
|
||||
was_leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
@@ -833,17 +833,16 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
/* If there was a real error during the reading, let the user know. */
|
||||
if (ferror(f) && errornumber != EINTR && errornumber != 0)
|
||||
statusline(ALERT, strerror(errornumber));
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (fd > 0 && !undoable) {
|
||||
close(fd);
|
||||
if (fd > 0 && !undoable)
|
||||
writable = (ISSET(VIEW_MODE) || access(filename, W_OK) == 0);
|
||||
}
|
||||
|
||||
/* If the file ended with newline, or it was entirely empty, make the
|
||||
* last line blank. Otherwise, put the last read data in. */
|
||||
if (len == 0)
|
||||
bottomline->data = mallocstrcpy(NULL, "");
|
||||
bottomline->data = copy_of("");
|
||||
else {
|
||||
bool mac_line_needs_newline = FALSE;
|
||||
|
||||
@@ -869,7 +868,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
if (mac_line_needs_newline) {
|
||||
bottomline->next = make_new_node(bottomline);
|
||||
bottomline = bottomline->next;
|
||||
bottomline->data = mallocstrcpy(NULL, "");
|
||||
bottomline->data = copy_of("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1026,7 +1025,7 @@ void do_insertfile(void)
|
||||
{
|
||||
int response;
|
||||
const char *msg;
|
||||
char *given = mallocstrcpy(NULL, "");
|
||||
char *given = copy_of("");
|
||||
/* The last answer the user typed at the statusbar prompt. */
|
||||
#ifndef NANO_TINY
|
||||
format_type was_fmt = openfile->fmt;
|
||||
@@ -1212,9 +1211,7 @@ void do_insertfile(void)
|
||||
/* If the current mode of operation allows it, go insert a file. */
|
||||
void do_insertfile_void(void)
|
||||
{
|
||||
if (ISSET(RESTRICTED))
|
||||
show_restricted_warning();
|
||||
else
|
||||
if (!in_restricted_mode())
|
||||
do_insertfile();
|
||||
}
|
||||
|
||||
@@ -1249,7 +1246,7 @@ char *get_full_path(const char *origpath)
|
||||
strcat(here, "/");
|
||||
}
|
||||
} else {
|
||||
here = mallocstrcpy(NULL, "");
|
||||
here = copy_of("");
|
||||
free(allocation);
|
||||
}
|
||||
|
||||
@@ -1279,7 +1276,7 @@ char *get_full_path(const char *origpath)
|
||||
} else {
|
||||
/* If target contains a filename, separate the two. */
|
||||
if (!path_only) {
|
||||
just_filename = mallocstrcpy(NULL, last_slash + 1);
|
||||
just_filename = copy_of(last_slash + 1);
|
||||
*(last_slash + 1) = '\0';
|
||||
}
|
||||
|
||||
@@ -1326,9 +1323,8 @@ char *get_full_path(const char *origpath)
|
||||
return target;
|
||||
}
|
||||
|
||||
/* Return the full version of path, as returned by get_full_path(). On
|
||||
* error, or if path doesn't reference a directory, or if the directory
|
||||
* isn't writable, return NULL. */
|
||||
/* Check whether the given path refers to a directory that is writable.
|
||||
* Return the absolute form of the path on success, and NULL on failure. */
|
||||
char *check_writable_directory(const char *path)
|
||||
{
|
||||
char *full_path = get_full_path(path);
|
||||
@@ -1336,9 +1332,7 @@ char *check_writable_directory(const char *path)
|
||||
if (full_path == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If we can't write to path or path isn't a directory, return NULL. */
|
||||
if (access(full_path, W_OK) != 0 ||
|
||||
full_path[strlen(full_path) - 1] != '/') {
|
||||
if (full_path[strlen(full_path) - 1] != '/' || access(full_path, W_OK) != 0) {
|
||||
free(full_path);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1346,44 +1340,42 @@ char *check_writable_directory(const char *path)
|
||||
return full_path;
|
||||
}
|
||||
|
||||
/* This function calls mkstemp(($TMPDIR|P_tmpdir|/tmp/)"nano.XXXXXX").
|
||||
* On success, it returns the malloc()ed filename and corresponding
|
||||
* FILE stream, opened in "r+b" mode. On error, it returns NULL for
|
||||
* the filename and leaves the FILE stream unchanged. */
|
||||
char *safe_tempfile(FILE **f)
|
||||
/* Create, safely, a temporary file in the standard temp directory.
|
||||
* On success, return the malloc()ed filename, plus the corresponding
|
||||
* file stream opened in read-write mode. On error, return NULL. */
|
||||
char *safe_tempfile(FILE **stream)
|
||||
{
|
||||
const char *tmpdir_env = getenv("TMPDIR");
|
||||
char *full_tempdir = NULL, *tempfile_name = NULL;
|
||||
mode_t original_umask = 0;
|
||||
const char *env_dir = getenv("TMPDIR");
|
||||
char *tempdir = NULL, *tempfile_name = NULL;
|
||||
mode_t was_mask;
|
||||
int fd;
|
||||
|
||||
/* Get the absolute path for the first directory among $TMPDIR
|
||||
* and P_tmpdir that is writable, otherwise use /tmp/. */
|
||||
if (tmpdir_env != NULL)
|
||||
full_tempdir = check_writable_directory(tmpdir_env);
|
||||
if (env_dir != NULL)
|
||||
tempdir = check_writable_directory(env_dir);
|
||||
|
||||
if (full_tempdir == NULL)
|
||||
full_tempdir = check_writable_directory(P_tmpdir);
|
||||
if (tempdir == NULL)
|
||||
tempdir = check_writable_directory(P_tmpdir);
|
||||
|
||||
if (full_tempdir == NULL)
|
||||
full_tempdir = mallocstrcpy(NULL, "/tmp/");
|
||||
if (tempdir == NULL)
|
||||
tempdir = copy_of("/tmp/");
|
||||
|
||||
tempfile_name = charealloc(full_tempdir, strlen(full_tempdir) + 12);
|
||||
tempfile_name = charealloc(tempdir, strlen(tempdir) + 12);
|
||||
strcat(tempfile_name, "nano.XXXXXX");
|
||||
|
||||
original_umask = umask(0);
|
||||
umask(S_IRWXG | S_IRWXO);
|
||||
was_mask = umask(S_IRWXG | S_IRWXO);
|
||||
|
||||
fd = mkstemp(tempfile_name);
|
||||
|
||||
if (fd != -1)
|
||||
*f = fdopen(fd, "r+b");
|
||||
else {
|
||||
umask(was_mask);
|
||||
|
||||
if (fd == -1) {
|
||||
free(tempfile_name);
|
||||
tempfile_name = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
umask(original_umask);
|
||||
*stream = fdopen(fd, "r+b");
|
||||
|
||||
return tempfile_name;
|
||||
}
|
||||
@@ -1470,10 +1462,10 @@ void init_backup_dir(void)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Read from inn, write to out. We assume inn is opened for reading,
|
||||
* and out for writing. We return 0 on success, -1 on read error, or -2
|
||||
* on write error. inn is always closed by this function, out is closed
|
||||
* only if close_out is true. */
|
||||
/* Read all data from inn, and write it to out. File inn must be open for
|
||||
* reading, and out for writing. Return 0 on success, a negative number on
|
||||
* read error, and a positive number on write error. File inn is always
|
||||
* closed by this function, out is closed only if close_out is true. */
|
||||
int copy_file(FILE *inn, FILE *out, bool close_out)
|
||||
{
|
||||
int retval = 0;
|
||||
@@ -1488,64 +1480,51 @@ int copy_file(FILE *inn, FILE *out, bool close_out)
|
||||
break;
|
||||
}
|
||||
if (fwrite(buf, sizeof(char), charsread, out) < charsread) {
|
||||
retval = -2;
|
||||
retval = 2;
|
||||
break;
|
||||
}
|
||||
} while (charsread > 0);
|
||||
|
||||
if (fclose(inn) == EOF)
|
||||
retval = -1;
|
||||
retval = -3;
|
||||
if (flush_out_fnc(out) == EOF)
|
||||
retval = -2;
|
||||
retval = 4;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Write a file out to disk. If f_open isn't NULL, we assume that it is
|
||||
* a stream associated with the file, and we don't try to open it
|
||||
* ourselves. If tmp is TRUE, we set the umask to disallow anyone else
|
||||
* from accessing the file, we don't set the filename to its name, and
|
||||
* we don't print out how many lines we wrote on the statusbar.
|
||||
*
|
||||
* tmp means we are writing a temporary file in a secure fashion. We
|
||||
* use it when spell checking or dumping the file on an error. If
|
||||
* method is APPEND, it means we are appending instead of overwriting.
|
||||
* If method is PREPEND, it means we are prepending instead of
|
||||
* overwriting. If fullbuffer is TRUE, we set the current filename and
|
||||
* stat info. But fullbuffer is irrelevant when appending or prepending,
|
||||
* or when writing a temporary file.
|
||||
*
|
||||
* Return TRUE on success or FALSE on error. */
|
||||
bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
/* Write the current buffer to disk. If thefile isn't NULL, we write to a
|
||||
* temporary file that is already open. If tmp is TRUE (when spell checking
|
||||
* or emergency dumping, for example), we set the umask to disallow anyone else
|
||||
* from accessing the file, and don't print out how many lines we wrote on the
|
||||
* status bar. If method is APPEND or PREPEND, it means we will be appending
|
||||
* or prepending instead of overwriting the given file. If fullbuffer is TRUE
|
||||
* and when writing normally, we set the current filename and stat info.
|
||||
* Return TRUE on success, and FALSE otherwise. */
|
||||
bool write_file(const char *name, FILE *thefile, bool tmp,
|
||||
kind_of_writing_type method, bool fullbuffer)
|
||||
{
|
||||
bool retval = FALSE;
|
||||
/* Instead of returning in this function, you should always
|
||||
* set retval and then goto cleanup_and_exit. */
|
||||
size_t lineswritten = 0;
|
||||
const linestruct *fileptr = openfile->filetop;
|
||||
int fd;
|
||||
/* The file descriptor we use. */
|
||||
mode_t original_umask = 0;
|
||||
/* Our umask, from when nano started. */
|
||||
#ifndef NANO_TINY
|
||||
bool isactualfile = FALSE;
|
||||
/* TRUE when the file is non-temporary and exists, FALSE otherwise. */
|
||||
#endif
|
||||
/* Becomes TRUE when the file is non-temporary and exists. */
|
||||
struct stat st;
|
||||
/* The status fields filled in by stat(). */
|
||||
#endif
|
||||
char *realname;
|
||||
/* The filename after tilde expansion. */
|
||||
FILE *f = f_open;
|
||||
/* The actual file, realname, we are writing to. */
|
||||
char *tempname = NULL;
|
||||
/* The name of the temporary file we write to on prepend. */
|
||||
/* The name of the temporary file we use when prepending. */
|
||||
linestruct *line = openfile->filetop;
|
||||
/* An iterator for moving through the lines of the buffer. */
|
||||
size_t lineswritten = 0;
|
||||
/* The number of lines written, for feedback on the status bar. */
|
||||
bool retval = FALSE;
|
||||
/* The return value, to become TRUE when writing has succeeded. */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (*name == '\0')
|
||||
return -1;
|
||||
|
||||
if (!tmp)
|
||||
titlebar(NULL);
|
||||
die("Tried to write a nameless file -- please report a bug\n");
|
||||
#endif
|
||||
|
||||
realname = real_dir_from_tilde(name);
|
||||
|
||||
@@ -1557,11 +1536,6 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the temp file exists and isn't already open, give up. */
|
||||
if (tmp && (lstat(realname, &st) != -1) && f_open == NULL)
|
||||
goto cleanup_and_exit;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Check whether the file (at the end of the symlink) exists. */
|
||||
if (!tmp)
|
||||
@@ -1582,25 +1556,21 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
openfile->current_stat->st_mtime == st.st_mtime)) {
|
||||
static struct timespec filetime[2];
|
||||
char *backupname;
|
||||
int backup_cflags, backup_fd;
|
||||
FILE *backup_file = NULL;
|
||||
int backup_cflags, backup_fd, verdict;
|
||||
FILE *original = NULL, *backup_file = NULL;
|
||||
|
||||
/* Save the original file's access and modification times. */
|
||||
filetime[0].tv_sec = openfile->current_stat->st_atime;
|
||||
filetime[1].tv_sec = openfile->current_stat->st_mtime;
|
||||
|
||||
if (f_open == NULL) {
|
||||
/* Open the original file to copy to the backup. */
|
||||
f = fopen(realname, "rb");
|
||||
/* Open the file of which a backup must be made. */
|
||||
original = fopen(realname, "rb");
|
||||
|
||||
if (f == NULL) {
|
||||
statusline(ALERT, _("Error reading %s: %s"), realname,
|
||||
strerror(errno));
|
||||
/* If we can't read from the original file, go on, since
|
||||
* only saving the current buffer is better than saving
|
||||
* nothing. */
|
||||
goto skip_backup;
|
||||
}
|
||||
if (original == NULL) {
|
||||
statusline(ALERT, _("Error reading %s: %s"), realname, strerror(errno));
|
||||
/* If we can't read from the original file, go on, since saving
|
||||
* only the current buffer is better than saving nothing. */
|
||||
goto skip_backup;
|
||||
}
|
||||
|
||||
/* If backup_dir is set, we set backupname to
|
||||
@@ -1615,14 +1585,11 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
* filename portion of the given path. Otherwise, replace
|
||||
* slashes with exclamation marks in the full path. */
|
||||
if (backuptemp == NULL)
|
||||
backuptemp = mallocstrcpy(NULL, tail(realname));
|
||||
backuptemp = copy_of(tail(realname));
|
||||
else {
|
||||
size_t i = 0;
|
||||
|
||||
for (; backuptemp[i] != '\0'; i++) {
|
||||
for (int i = 0; backuptemp[i] != '\0'; i++)
|
||||
if (backuptemp[i] == '/')
|
||||
backuptemp[i] = '!';
|
||||
}
|
||||
}
|
||||
|
||||
backupname = charalloc(strlen(backup_dir) + strlen(backuptemp) + 1);
|
||||
@@ -1704,11 +1671,19 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
/* Copy the file. */
|
||||
if (copy_file(f, backup_file, FALSE) != 0) {
|
||||
/* Copy the existing file to the backup. */
|
||||
verdict = copy_file(original, backup_file, FALSE);
|
||||
|
||||
if (verdict < 0) {
|
||||
fclose(backup_file);
|
||||
statusline(ALERT, _("Error reading %s: %s"), realname,
|
||||
strerror(errno));
|
||||
statusline(ALERT, _("Error reading %s: %s"), realname, strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
} else if (verdict > 0) {
|
||||
fclose(backup_file);
|
||||
if (prompt_failed_backupwrite(backupname))
|
||||
goto skip_backup;
|
||||
statusline(HUSH, _("Error writing backup file %s: %s"),
|
||||
backupname, strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
@@ -1727,77 +1702,55 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
}
|
||||
|
||||
skip_backup:
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
if (f_open == NULL) {
|
||||
original_umask = umask(0);
|
||||
|
||||
/* If we create a temp file, we don't let anyone else access it. */
|
||||
if (tmp)
|
||||
umask(S_IRWXG | S_IRWXO);
|
||||
else
|
||||
umask(original_umask);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If we're prepending, copy the file to a temp file. */
|
||||
/* When prepending, first copy the existing file to a temporary file. */
|
||||
if (method == PREPEND) {
|
||||
int fd_source;
|
||||
FILE *f_source = NULL;
|
||||
FILE *source = fopen(realname, "rb");
|
||||
FILE *target = NULL;
|
||||
int verdict;
|
||||
|
||||
if (f == NULL) {
|
||||
f = fopen(realname, "rb");
|
||||
|
||||
if (f == NULL) {
|
||||
statusline(ALERT, _("Error reading %s: %s"), realname,
|
||||
strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
}
|
||||
|
||||
tempname = safe_tempfile(&f);
|
||||
|
||||
if (tempname == NULL) {
|
||||
statusline(ALERT, _("Error writing temp file: %s"),
|
||||
strerror(errno));
|
||||
if (source == NULL) {
|
||||
statusline(ALERT, _("Error reading %s: %s"), realname, strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
if (f_open == NULL) {
|
||||
fd_source = open(realname, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
tempname = safe_tempfile(&target);
|
||||
|
||||
if (fd_source != -1) {
|
||||
f_source = fdopen(fd_source, "rb");
|
||||
if (f_source == NULL) {
|
||||
statusline(ALERT, _("Error reading %s: %s"), realname,
|
||||
strerror(errno));
|
||||
close(fd_source);
|
||||
fclose(f);
|
||||
unlink(tempname);
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
}
|
||||
if (tempname == NULL) {
|
||||
statusline(ALERT, _("Error writing temp file: %s"), strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
if (f_source == NULL || copy_file(f_source, f, TRUE) != 0) {
|
||||
statusline(ALERT, _("Error writing temp file: %s"),
|
||||
strerror(errno));
|
||||
verdict = copy_file(source, target, TRUE);
|
||||
|
||||
if (verdict < 0) {
|
||||
statusline(ALERT, _("Error reading %s: %s"), realname, strerror(errno));
|
||||
unlink(tempname);
|
||||
goto cleanup_and_exit;
|
||||
} else if (verdict > 0) {
|
||||
statusline(ALERT, _("Error writing temp file: %s"), strerror(errno));
|
||||
unlink(tempname);
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (S_ISFIFO(st.st_mode))
|
||||
if (!tmp && S_ISFIFO(st.st_mode))
|
||||
statusbar(_("Writing to FIFO..."));
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
if (f_open == NULL) {
|
||||
/* When it's not a temporary file, this is where we open or create it. */
|
||||
if (thefile == NULL) {
|
||||
mode_t was_mask = 0;
|
||||
int fd;
|
||||
|
||||
/* When creating an emergency file, don't let others access it. */
|
||||
if (tmp)
|
||||
was_mask = umask(S_IRWXG | S_IRWXO);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
block_sigwinch(TRUE);
|
||||
install_handler_for_Ctrl_C();
|
||||
#endif
|
||||
/* Now open the file in place. Use O_EXCL if tmp is TRUE. This
|
||||
* is copied from joe, because wiggy says so *shrug*. */
|
||||
/* Now open the file. Use O_EXCL for an emergency file. */
|
||||
fd = open(realname, O_WRONLY | O_CREAT | ((method == APPEND) ?
|
||||
O_APPEND : (tmp ? O_EXCL : O_TRUNC)), S_IRUSR |
|
||||
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
@@ -1806,26 +1759,27 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
restore_handler_for_Ctrl_C();
|
||||
block_sigwinch(FALSE);
|
||||
#endif
|
||||
/* Set the umask back to the user's original value. */
|
||||
umask(original_umask);
|
||||
/* When this is an emergency file, restore the original umask. */
|
||||
if (tmp)
|
||||
umask(was_mask);
|
||||
|
||||
/* If we couldn't open the file, give up. */
|
||||
if (fd == -1) {
|
||||
if (errno == EINTR || errno == 0)
|
||||
statusline(ALERT, _("Interrupted"));
|
||||
else
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
|
||||
#ifndef NANO_TINY
|
||||
if (tempname != NULL)
|
||||
unlink(tempname);
|
||||
#endif
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
f = fdopen(fd, (method == APPEND) ? "ab" : "wb");
|
||||
thefile = fdopen(fd, (method == APPEND) ? "ab" : "wb");
|
||||
|
||||
if (f == NULL) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
if (thefile == NULL) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
|
||||
close(fd);
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
@@ -1834,21 +1788,20 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
if (!tmp)
|
||||
statusbar(_("Writing..."));
|
||||
|
||||
while (fileptr != NULL) {
|
||||
size_t data_len = strlen(fileptr->data), size;
|
||||
while (line != NULL) {
|
||||
size_t data_len = strlen(line->data), size;
|
||||
|
||||
/* Decode LFs as the NULs that they are, before writing to disk. */
|
||||
sunder(fileptr->data);
|
||||
sunder(line->data);
|
||||
|
||||
size = fwrite(fileptr->data, sizeof(char), data_len, f);
|
||||
size = fwrite(line->data, sizeof(char), data_len, thefile);
|
||||
|
||||
/* Re-encode any embedded NULs as LFs. */
|
||||
unsunder(fileptr->data, data_len);
|
||||
unsunder(line->data, data_len);
|
||||
|
||||
if (size < data_len) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
fclose(f);
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
|
||||
fclose(thefile);
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
@@ -1856,67 +1809,59 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
* character after it. If the last line of the file is blank,
|
||||
* this means that zero bytes are written, in which case we
|
||||
* don't count the last line in the total lines written. */
|
||||
if (fileptr == openfile->filebot) {
|
||||
if (fileptr->data[0] == '\0')
|
||||
if (line == openfile->filebot) {
|
||||
if (line->data[0] == '\0')
|
||||
lineswritten--;
|
||||
} else {
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->fmt == DOS_FILE || openfile->fmt == MAC_FILE) {
|
||||
if (putc('\r', f) == EOF) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
fclose(f);
|
||||
if (putc('\r', thefile) == EOF) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
|
||||
fclose(thefile);
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (openfile->fmt != MAC_FILE)
|
||||
#endif
|
||||
if (putc('\n', f) == EOF) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
fclose(f);
|
||||
if (putc('\n', thefile) == EOF) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
|
||||
fclose(thefile);
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
}
|
||||
|
||||
fileptr = fileptr->next;
|
||||
line = line->next;
|
||||
lineswritten++;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If we're prepending, open the temp file, and append it to f. */
|
||||
/* When prepending, append the temporary file to what we wrote above. */
|
||||
if (method == PREPEND) {
|
||||
int fd_source;
|
||||
FILE *f_source = NULL;
|
||||
FILE *source = fopen(tempname, "rb");
|
||||
int verdict;
|
||||
|
||||
fd_source = open(tempname, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
|
||||
if (fd_source != -1) {
|
||||
f_source = fdopen(fd_source, "rb");
|
||||
if (f_source == NULL)
|
||||
close(fd_source);
|
||||
}
|
||||
|
||||
if (f_source == NULL) {
|
||||
statusline(ALERT, _("Error reading %s: %s"), tempname,
|
||||
strerror(errno));
|
||||
fclose(f);
|
||||
if (source == NULL) {
|
||||
statusline(ALERT, _("Error reading temp file: %s"), strerror(errno));
|
||||
fclose(thefile);
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
if (copy_file(f_source, f, TRUE) != 0) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
verdict = copy_file(source, thefile, TRUE);
|
||||
|
||||
if (verdict < 0) {
|
||||
statusline(ALERT, _("Error reading temp file: %s"), strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
} else if (verdict > 0) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
unlink(tempname);
|
||||
} else
|
||||
#endif
|
||||
if (fclose(f) != 0) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
if (fclose(thefile) != 0) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname, strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
@@ -1939,12 +1884,12 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
|
||||
/* If the syntax changed, discard and recompute the multidata. */
|
||||
if (strcmp(oldname, newname) != 0) {
|
||||
linestruct *line = openfile->filetop;
|
||||
linestruct *lin = openfile->filetop;
|
||||
|
||||
while (line != NULL) {
|
||||
free(line->multidata);
|
||||
line->multidata = NULL;
|
||||
line = line->next;
|
||||
while (lin != NULL) {
|
||||
free(lin->multidata);
|
||||
lin->multidata = NULL;
|
||||
lin = lin->next;
|
||||
}
|
||||
|
||||
precalc_multicolorinfo();
|
||||
@@ -1970,8 +1915,8 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
retval = TRUE;
|
||||
|
||||
cleanup_and_exit:
|
||||
free(realname);
|
||||
free(tempname);
|
||||
free(realname);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -1979,7 +1924,7 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
#ifndef NANO_TINY
|
||||
/* Write a marked selection from a file out to disk. Return TRUE on
|
||||
* success or FALSE on error. */
|
||||
bool write_marked_file(const char *name, FILE *f_open, bool tmp,
|
||||
bool write_marked_file(const char *name, FILE *stream, bool tmp,
|
||||
kind_of_writing_type method)
|
||||
{
|
||||
bool retval;
|
||||
@@ -1999,7 +1944,7 @@ bool write_marked_file(const char *name, FILE *f_open, bool tmp,
|
||||
added_magicline = TRUE;
|
||||
}
|
||||
|
||||
retval = write_file(name, f_open, tmp, method, FALSE);
|
||||
retval = write_file(name, stream, tmp, method, FALSE);
|
||||
|
||||
if (added_magicline)
|
||||
remove_magicline();
|
||||
@@ -2033,11 +1978,11 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
/* Display newlines in filenames as ^J. */
|
||||
as_an_at = FALSE;
|
||||
|
||||
given = mallocstrcpy(NULL,
|
||||
#ifndef NANO_TINY
|
||||
(openfile->mark && !exiting) ? "" :
|
||||
given = copy_of((openfile->mark && !exiting) ? "" : openfile->filename);
|
||||
#else
|
||||
given = copy_of(openfile->filename);
|
||||
#endif
|
||||
openfile->filename);
|
||||
|
||||
while (TRUE) {
|
||||
const char *msg;
|
||||
@@ -2129,7 +2074,7 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
continue;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
if (func == do_help_void) {
|
||||
if (func == do_help) {
|
||||
continue;
|
||||
}
|
||||
#ifdef ENABLE_EXTRA
|
||||
@@ -2287,7 +2232,7 @@ char *real_dir_from_tilde(const char *path)
|
||||
size_t i = 1;
|
||||
|
||||
if (*path != '~')
|
||||
return mallocstrcpy(NULL, path);
|
||||
return copy_of(path);
|
||||
|
||||
/* Figure out how much of the string we need to compare. */
|
||||
while (path[i] != '/' && path[i] != '\0')
|
||||
@@ -2295,12 +2240,12 @@ char *real_dir_from_tilde(const char *path)
|
||||
|
||||
if (i == 1) {
|
||||
get_homedir();
|
||||
tilded = mallocstrcpy(NULL, homedir);
|
||||
tilded = copy_of(homedir);
|
||||
} else {
|
||||
#ifdef HAVE_PWD_H
|
||||
const struct passwd *userdata;
|
||||
|
||||
tilded = mallocstrncpy(NULL, path, i + 1);
|
||||
tilded = measured_copy(path, i + 1);
|
||||
tilded[i] = '\0';
|
||||
|
||||
do {
|
||||
@@ -2311,7 +2256,7 @@ char *real_dir_from_tilde(const char *path)
|
||||
if (userdata != NULL)
|
||||
tilded = mallocstrcpy(tilded, userdata->pw_dir);
|
||||
#else
|
||||
tilded = strdup("");
|
||||
tilded = copy_of("");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2423,7 +2368,7 @@ char **username_tab_completion(const char *buf, size_t *num_matches,
|
||||
char **cwd_tab_completion(const char *buf, bool allow_files,
|
||||
size_t *num_matches, size_t buf_len)
|
||||
{
|
||||
char *dirname = mallocstrcpy(NULL, buf);
|
||||
char *dirname = copy_of(buf);
|
||||
char *slash, *filename;
|
||||
size_t filenamelen;
|
||||
char **matches = NULL;
|
||||
@@ -2438,7 +2383,7 @@ char **cwd_tab_completion(const char *buf, bool allow_files,
|
||||
if (slash != NULL) {
|
||||
char *wasdirname = dirname;
|
||||
|
||||
filename = mallocstrcpy(NULL, ++slash);
|
||||
filename = copy_of(++slash);
|
||||
/* Cut off the filename part after the slash. */
|
||||
*slash = '\0';
|
||||
dirname = real_dir_from_tilde(dirname);
|
||||
@@ -2451,7 +2396,7 @@ char **cwd_tab_completion(const char *buf, bool allow_files,
|
||||
free(wasdirname);
|
||||
} else {
|
||||
filename = dirname;
|
||||
dirname = mallocstrcpy(NULL, present_path);
|
||||
dirname = copy_of(present_path);
|
||||
}
|
||||
|
||||
dir = opendir(dirname);
|
||||
@@ -2496,7 +2441,7 @@ char **cwd_tab_completion(const char *buf, bool allow_files,
|
||||
|
||||
matches = (char **)nrealloc(matches, (*num_matches + 1) *
|
||||
sizeof(char *));
|
||||
matches[*num_matches] = mallocstrcpy(NULL, nextdir->d_name);
|
||||
matches[*num_matches] = copy_of(nextdir->d_name);
|
||||
++(*num_matches);
|
||||
}
|
||||
}
|
||||
@@ -2546,10 +2491,10 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
|
||||
/* Get the number of characters that all matches have in common. */
|
||||
while (TRUE) {
|
||||
len1 = parse_mbchar(matches[0] + common_len, char1, NULL);
|
||||
len1 = collect_char(matches[0] + common_len, char1);
|
||||
|
||||
for (match = 1; match < num_matches; match++) {
|
||||
len2 = parse_mbchar(matches[match] + common_len, char2, NULL);
|
||||
len2 = collect_char(matches[match] + common_len, char2);
|
||||
|
||||
if (len1 != len2 || strncmp(char1, char2, len2) != 0)
|
||||
break;
|
||||
|
||||
401
src/global.c
401
src/global.c
@@ -248,21 +248,9 @@ char *homedir = NULL;
|
||||
char *statedir = NULL;
|
||||
/* The directory for nano's history files. */
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
#define NUMBER_OF_MENUS 16
|
||||
char *menunames[NUMBER_OF_MENUS] = { "main", "search", "replace", "replacewith",
|
||||
"yesno", "gotoline", "writeout", "insert",
|
||||
"extcmd", "help", "spell", "linter",
|
||||
"browser", "whereisfile", "gotodir",
|
||||
"all" };
|
||||
int menusymbols[NUMBER_OF_MENUS] = { MMAIN, MWHEREIS, MREPLACE, MREPLACEWITH,
|
||||
MYESNO, MGOTOLINE, MWRITEFILE, MINSERTFILE,
|
||||
MEXTCMD, MHELP, MSPELL, MLINTER,
|
||||
MBROWSER, MWHEREISFILE, MGOTODIR,
|
||||
MMOST|MHELP|MYESNO };
|
||||
|
||||
char *rcfile_with_errors = NULL;
|
||||
/* The first nanorc file, if any, that produced warnings. */
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
char *startup_problem = NULL;
|
||||
/* An error message (if any) about nanorc files or history files. */
|
||||
#endif
|
||||
|
||||
bool spotlighted = FALSE;
|
||||
@@ -484,31 +472,36 @@ functionptrtype func_from_key(int *kbinput)
|
||||
int keycode_from_string(const char *keystring)
|
||||
{
|
||||
if (keystring[0] == '^') {
|
||||
if (strcasecmp(keystring, "^Space") == 0)
|
||||
return 0;
|
||||
if (keystring[2] == '\0') {
|
||||
if (keystring[1] == '/')
|
||||
return 31;
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
|
||||
if (strcasecmp(keystring, "^H") == 0)
|
||||
return KEY_BACKSPACE;
|
||||
if (keystring[1] == 'H')
|
||||
return KEY_BACKSPACE;
|
||||
#endif
|
||||
if (keystring[1] <= '_' && strlen(keystring) == 2)
|
||||
return keystring[1] - 64;
|
||||
if (keystring[1] <= '_')
|
||||
return keystring[1] - 64;
|
||||
else
|
||||
return -1;
|
||||
} else if (strcasecmp(keystring, "^Space") == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
} else if (keystring[0] == 'M') {
|
||||
if (keystring[1] == '-' && keystring[3] == '\0')
|
||||
return tolower((unsigned char)keystring[2]);
|
||||
if (strcasecmp(keystring, "M-Space") == 0)
|
||||
return (int)' ';
|
||||
if (keystring[1] == '-' && strlen(keystring) == 3)
|
||||
return tolower((unsigned char)keystring[2]);
|
||||
else
|
||||
return -1;
|
||||
} else if (keystring[0] == 'F') {
|
||||
int fn = atoi(&keystring[1]);
|
||||
if (fn < 1 || fn > 16)
|
||||
if (fn < 1 || fn > 24)
|
||||
return -1;
|
||||
return KEY_F0 + fn;
|
||||
} else if (!strcasecmp(keystring, "Ins"))
|
||||
} else if (strcasecmp(keystring, "Ins") == 0)
|
||||
return KEY_IC;
|
||||
else if (!strcasecmp(keystring, "Del"))
|
||||
else if (strcasecmp(keystring, "Del") == 0)
|
||||
return KEY_DC;
|
||||
else
|
||||
return -1;
|
||||
@@ -519,11 +512,7 @@ void assign_keyinfo(keystruct *s, const char *keystring, const int keycode)
|
||||
{
|
||||
s->keystr = keystring;
|
||||
s->meta = (keystring[0] == 'M' && keycode == 0);
|
||||
|
||||
if (keycode)
|
||||
s->keycode = keycode;
|
||||
else
|
||||
s->keycode = keycode_from_string(keystring);
|
||||
s->keycode = (keycode ? keycode : keycode_from_string(keystring));
|
||||
}
|
||||
|
||||
/* These two tags are used elsewhere too, so they are global. */
|
||||
@@ -539,8 +528,7 @@ void shortcut_init(void)
|
||||
* they are best kept shorter than 56 characters, but may be longer. */
|
||||
const char *cancel_gist = N_("Cancel the current function");
|
||||
const char *help_gist = N_("Display this help text");
|
||||
const char *exit_gist =
|
||||
N_("Close the current buffer / Exit from nano");
|
||||
const char *exit_gist = N_("Close the current buffer / Exit from nano");
|
||||
const char *writeout_gist =
|
||||
N_("Write the current buffer (or the marked region) to disk");
|
||||
const char *readfile_gist =
|
||||
@@ -549,19 +537,6 @@ void shortcut_init(void)
|
||||
N_("Search forward for a string or a regular expression");
|
||||
const char *wherewas_gist =
|
||||
N_("Search backward for a string or a regular expression");
|
||||
#ifdef ENABLE_BROWSER
|
||||
const char *browserwhereis_gist = N_("Search forward for a string");
|
||||
const char *browserwherewas_gist = N_("Search backward for a string");
|
||||
const char *browserrefresh_gist = N_("Refresh the file list");
|
||||
#ifndef NANO_TINY
|
||||
const char *browserlefthand_gist = N_("Go to lefthand column");
|
||||
const char *browserrighthand_gist = N_("Go to righthand column");
|
||||
const char *browsertoprow_gist = N_("Go to first row in this column");
|
||||
const char *browserbottomrow_gist = N_("Go to last row in this column");
|
||||
#endif
|
||||
#endif
|
||||
const char *prevpage_gist = N_("Go one screenful up");
|
||||
const char *nextpage_gist = N_("Go one screenful down");
|
||||
const char *cut_gist =
|
||||
N_("Cut current line (or marked region) and store it in cutbuffer");
|
||||
const char *uncut_gist =
|
||||
@@ -598,6 +573,8 @@ void shortcut_init(void)
|
||||
const char *paraend_gist =
|
||||
N_("Go just beyond end of paragraph; then of next paragraph");
|
||||
#endif
|
||||
const char *prevpage_gist = N_("Go one screenful up");
|
||||
const char *nextpage_gist = N_("Go one screenful down");
|
||||
const char *firstline_gist = N_("Go to the first line of the file");
|
||||
const char *lastline_gist = N_("Go to the last line of the file");
|
||||
#ifndef NANO_TINY
|
||||
@@ -653,12 +630,9 @@ void shortcut_init(void)
|
||||
const char *recordmacro_gist = N_("Start/stop recording a macro");
|
||||
const char *runmacro_gist = N_("Run the last recorded macro");
|
||||
#endif
|
||||
const char *case_gist =
|
||||
N_("Toggle the case sensitivity of the search");
|
||||
const char *reverse_gist =
|
||||
N_("Reverse the direction of the search");
|
||||
const char *regexp_gist =
|
||||
N_("Toggle the use of regular expressions");
|
||||
const char *case_gist = N_("Toggle the case sensitivity of the search");
|
||||
const char *reverse_gist = N_("Reverse the direction of the search");
|
||||
const char *regexp_gist = N_("Toggle the use of regular expressions");
|
||||
#ifdef ENABLE_HISTORIES
|
||||
const char *older_gist =
|
||||
N_("Recall the previous search/replace string");
|
||||
@@ -687,12 +661,25 @@ void shortcut_init(void)
|
||||
const char *lastfile_gist = N_("Go to the last file in the list");
|
||||
const char *backfile_gist = N_("Go to the previous file in the list");
|
||||
const char *forwardfile_gist = N_("Go to the next file in the list");
|
||||
#ifndef NANO_TINY
|
||||
const char *browserlefthand_gist = N_("Go to lefthand column");
|
||||
const char *browserrighthand_gist = N_("Go to righthand column");
|
||||
const char *browsertoprow_gist = N_("Go to first row in this column");
|
||||
const char *browserbottomrow_gist = N_("Go to last row in this column");
|
||||
#endif
|
||||
const char *browserwhereis_gist = N_("Search forward for a string");
|
||||
const char *browserwherewas_gist = N_("Search backward for a string");
|
||||
const char *browserrefresh_gist = N_("Refresh the file list");
|
||||
const char *gotodir_gist = N_("Go to directory");
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
const char *lint_gist = N_("Invoke the linter, if available");
|
||||
const char *prevlint_gist = N_("Go to previous linter msg");
|
||||
const char *nextlint_gist = N_("Go to next linter msg");
|
||||
#ifdef ENABLE_SPELLER
|
||||
const char *formatter_gist =
|
||||
N_("Invoke a program to format/arrange/manipulate the buffer");
|
||||
#endif
|
||||
#endif
|
||||
#endif /* ENABLE_HELP */
|
||||
|
||||
@@ -704,7 +691,7 @@ void shortcut_init(void)
|
||||
|
||||
/* Start populating the different menus with functions. */
|
||||
|
||||
add_to_funcs(do_help_void, (MMOST | MBROWSER) & ~MFINDINHELP,
|
||||
add_to_funcs(do_help, (MMOST | MBROWSER) & ~MFINDINHELP,
|
||||
/* TRANSLATORS: Try to keep the next eleven strings at most 10 characters. */
|
||||
N_("Get Help"), WITHORSANS(help_gist), TOGETHER, VIEW);
|
||||
|
||||
@@ -1001,9 +988,14 @@ void shortcut_init(void)
|
||||
N_("Zap Text"), WITHORSANS(zap_gist), BLANKAFTER, NOVIEW);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (!ISSET(RESTRICTED))
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
add_to_funcs(do_linter, MMAIN,
|
||||
N_("To Linter"), WITHORSANS(lint_gist), BLANKAFTER, NOVIEW);
|
||||
N_("To Linter"), WITHORSANS(lint_gist), TOGETHER, NOVIEW);
|
||||
#ifdef ENABLE_SPELLER
|
||||
add_to_funcs(do_formatter, MMAIN,
|
||||
N_("Formatter"), WITHORSANS(formatter_gist), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
add_to_funcs(do_savefile, MMAIN,
|
||||
@@ -1102,7 +1094,7 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMOST, "Del", 0, 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_void, 0);
|
||||
add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, "^G", 0, do_help, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", 0, do_exit, 0);
|
||||
if (!ISSET(PRESERVE))
|
||||
add_to_sclist(MMAIN, "^S", 0, do_savefile, 0);
|
||||
@@ -1124,6 +1116,9 @@ void shortcut_init(void)
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
add_to_sclist(MMAIN, "M-B", 0, do_linter, 0);
|
||||
#ifdef ENABLE_SPELLER
|
||||
add_to_sclist(MMAIN, "M-F", 0, do_formatter, 0);
|
||||
#endif
|
||||
#endif
|
||||
add_to_sclist(MMAIN, "^C", 0, do_cursorpos_void, 0);
|
||||
add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn_void, 0);
|
||||
@@ -1200,8 +1195,8 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN, "M-F", 0, do_next_word_void, 0);
|
||||
add_to_sclist(MMAIN, "M-N", 0, do_next_word_void, 0);
|
||||
#endif
|
||||
add_to_sclist(MMOST|MBROWSER, "M-Space", 0, do_prev_word_void, 0);
|
||||
add_to_sclist(MMOST|MBROWSER, "^Space", 0, do_next_word_void, 0);
|
||||
add_to_sclist(MMOST, "M-Space", 0, do_prev_word_void, 0);
|
||||
add_to_sclist(MMOST, "^Space", 0, do_next_word_void, 0);
|
||||
add_to_sclist(MMOST, "^A", 0, do_home, 0);
|
||||
add_to_sclist(MMOST, "Home", KEY_HOME, do_home, 0);
|
||||
add_to_sclist(MMOST, "^E", 0, do_end, 0);
|
||||
@@ -1385,7 +1380,7 @@ void shortcut_init(void)
|
||||
#ifdef ENABLE_COLOR
|
||||
add_to_sclist(MLINTER, "^X", 0, do_cancel, 0);
|
||||
#endif
|
||||
add_to_sclist(MMOST & ~MFINDINHELP, "F1", 0, do_help_void, 0);
|
||||
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);
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
@@ -1441,291 +1436,3 @@ const char *flagtostr(int flag)
|
||||
}
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
/* Interpret a function string given in the rc file, and return a
|
||||
* shortcut record with the corresponding function filled in. */
|
||||
keystruct *strtosc(const char *input)
|
||||
{
|
||||
keystruct *s = nmalloc(sizeof(keystruct));
|
||||
|
||||
#ifndef NANO_TINY
|
||||
s->toggle = 0;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
if (!strcasecmp(input, "help"))
|
||||
s->func = do_help_void;
|
||||
else
|
||||
#endif
|
||||
if (!strcasecmp(input, "cancel"))
|
||||
s->func = do_cancel;
|
||||
else if (!strcasecmp(input, "exit"))
|
||||
s->func = do_exit;
|
||||
else if (!strcasecmp(input, "discardbuffer"))
|
||||
s->func = discard_buffer;
|
||||
else if (!strcasecmp(input, "writeout"))
|
||||
s->func = do_writeout_void;
|
||||
else if (!strcasecmp(input, "savefile"))
|
||||
s->func = do_savefile;
|
||||
else if (!strcasecmp(input, "insert"))
|
||||
s->func = do_insertfile_void;
|
||||
else if (!strcasecmp(input, "whereis"))
|
||||
s->func = do_search_forward;
|
||||
else if (!strcasecmp(input, "wherewas"))
|
||||
s->func = do_search_backward;
|
||||
else if (!strcasecmp(input, "findprevious"))
|
||||
s->func = do_findprevious;
|
||||
else if (!strcasecmp(input, "findnext"))
|
||||
s->func = do_findnext;
|
||||
else if (!strcasecmp(input, "replace"))
|
||||
s->func = do_replace;
|
||||
else if (!strcasecmp(input, "cut"))
|
||||
s->func = cut_text;
|
||||
else if (!strcasecmp(input, "paste"))
|
||||
s->func = paste_text;
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "cutrestoffile"))
|
||||
s->func = cut_till_eof;
|
||||
else if (!strcasecmp(input, "copy"))
|
||||
s->func = copy_text;
|
||||
else if (!strcasecmp(input, "zap"))
|
||||
s->func = zap_text;
|
||||
else if (!strcasecmp(input, "mark"))
|
||||
s->func = do_mark;
|
||||
#endif
|
||||
#ifdef ENABLE_SPELLER
|
||||
else if (!strcasecmp(input, "tospell") ||
|
||||
!strcasecmp(input, "speller"))
|
||||
s->func = do_spell;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (!strcasecmp(input, "linter"))
|
||||
s->func = do_linter;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "curpos"))
|
||||
s->func = do_cursorpos_void;
|
||||
else if (!strcasecmp(input, "gotoline"))
|
||||
s->func = do_gotolinecolumn_void;
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
else if (!strcasecmp(input, "justify"))
|
||||
s->func = do_justify_void;
|
||||
else if (!strcasecmp(input, "fulljustify"))
|
||||
s->func = do_full_justify;
|
||||
else if (!strcasecmp(input, "beginpara"))
|
||||
s->func = do_para_begin_void;
|
||||
else if (!strcasecmp(input, "endpara"))
|
||||
s->func = do_para_end_void;
|
||||
#endif
|
||||
#ifdef ENABLE_COMMENT
|
||||
else if (!strcasecmp(input, "comment"))
|
||||
s->func = do_comment;
|
||||
#endif
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
else if (!strcasecmp(input, "complete"))
|
||||
s->func = complete_a_word;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "indent"))
|
||||
s->func = do_indent;
|
||||
else if (!strcasecmp(input, "unindent"))
|
||||
s->func = do_unindent;
|
||||
else if (!strcasecmp(input, "chopwordleft") ||
|
||||
!strcasecmp(input, "cutwordleft")) /* Deprecated; remove in 2021. */
|
||||
s->func = chop_previous_word;
|
||||
else if (!strcasecmp(input, "chopwordright") ||
|
||||
!strcasecmp(input, "cutwordright")) /* Deprecated; remove in 2021. */
|
||||
s->func = chop_next_word;
|
||||
else if (!strcasecmp(input, "findbracket"))
|
||||
s->func = do_find_bracket;
|
||||
else if (!strcasecmp(input, "wordcount"))
|
||||
s->func = do_wordlinechar_count;
|
||||
else if (!strcasecmp(input, "recordmacro"))
|
||||
s->func = record_macro;
|
||||
else if (!strcasecmp(input, "runmacro"))
|
||||
s->func = run_macro;
|
||||
else if (!strcasecmp(input, "undo"))
|
||||
s->func = do_undo;
|
||||
else if (!strcasecmp(input, "redo"))
|
||||
s->func = do_redo;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "left") ||
|
||||
!strcasecmp(input, "back"))
|
||||
s->func = do_left;
|
||||
else if (!strcasecmp(input, "right") ||
|
||||
!strcasecmp(input, "forward"))
|
||||
s->func = do_right;
|
||||
else if (!strcasecmp(input, "up") ||
|
||||
!strcasecmp(input, "prevline"))
|
||||
s->func = do_up;
|
||||
else if (!strcasecmp(input, "down") ||
|
||||
!strcasecmp(input, "nextline"))
|
||||
s->func = do_down;
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
else if (!strcasecmp(input, "scrollup"))
|
||||
s->func = do_scroll_up;
|
||||
else if (!strcasecmp(input, "scrolldown"))
|
||||
s->func = do_scroll_down;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "prevword"))
|
||||
s->func = do_prev_word_void;
|
||||
else if (!strcasecmp(input, "nextword"))
|
||||
s->func = do_next_word_void;
|
||||
else if (!strcasecmp(input, "home"))
|
||||
s->func = do_home;
|
||||
else if (!strcasecmp(input, "end"))
|
||||
s->func = do_end;
|
||||
else if (!strcasecmp(input, "prevblock"))
|
||||
s->func = do_prev_block;
|
||||
else if (!strcasecmp(input, "nextblock"))
|
||||
s->func = do_next_block;
|
||||
else if (!strcasecmp(input, "pageup") ||
|
||||
!strcasecmp(input, "prevpage"))
|
||||
s->func = do_page_up;
|
||||
else if (!strcasecmp(input, "pagedown") ||
|
||||
!strcasecmp(input, "nextpage"))
|
||||
s->func = do_page_down;
|
||||
else if (!strcasecmp(input, "firstline"))
|
||||
s->func = to_first_line;
|
||||
else if (!strcasecmp(input, "lastline"))
|
||||
s->func = to_last_line;
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
else if (!strcasecmp(input, "prevbuf"))
|
||||
s->func = switch_to_prev_buffer;
|
||||
else if (!strcasecmp(input, "nextbuf"))
|
||||
s->func = switch_to_next_buffer;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "verbatim"))
|
||||
s->func = do_verbatim_input;
|
||||
else if (!strcasecmp(input, "tab"))
|
||||
s->func = do_tab;
|
||||
else if (!strcasecmp(input, "enter"))
|
||||
s->func = do_enter;
|
||||
else if (!strcasecmp(input, "delete"))
|
||||
s->func = do_delete;
|
||||
else if (!strcasecmp(input, "backspace"))
|
||||
s->func = do_backspace;
|
||||
else if (!strcasecmp(input, "refresh"))
|
||||
s->func = total_refresh;
|
||||
else if (!strcasecmp(input, "suspend"))
|
||||
s->func = do_suspend_void;
|
||||
else if (!strcasecmp(input, "casesens"))
|
||||
s->func = case_sens_void;
|
||||
else if (!strcasecmp(input, "regexp"))
|
||||
s->func = regexp_void;
|
||||
else if (!strcasecmp(input, "backwards"))
|
||||
s->func = backwards_void;
|
||||
else if (!strcasecmp(input, "flipreplace"))
|
||||
s->func = flip_replace;
|
||||
else if (!strcasecmp(input, "flipgoto"))
|
||||
s->func = flip_goto;
|
||||
#ifdef ENABLE_HISTORIES
|
||||
else if (!strcasecmp(input, "older"))
|
||||
s->func = get_history_older_void;
|
||||
else if (!strcasecmp(input, "newer"))
|
||||
s->func = get_history_newer_void;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "dosformat"))
|
||||
s->func = dos_format_void;
|
||||
else if (!strcasecmp(input, "macformat"))
|
||||
s->func = mac_format_void;
|
||||
else if (!strcasecmp(input, "append"))
|
||||
s->func = append_void;
|
||||
else if (!strcasecmp(input, "prepend"))
|
||||
s->func = prepend_void;
|
||||
else if (!strcasecmp(input, "backup"))
|
||||
s->func = backup_file_void;
|
||||
else if (!strcasecmp(input, "flipexecute"))
|
||||
s->func = flip_execute;
|
||||
else if (!strcasecmp(input, "flippipe"))
|
||||
s->func = flip_pipe;
|
||||
else if (!strcasecmp(input, "flipconvert"))
|
||||
s->func = flip_convert;
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
else if (!strcasecmp(input, "flipnewbuffer"))
|
||||
s->func = flip_newbuffer;
|
||||
#endif
|
||||
#ifdef ENABLE_BROWSER
|
||||
else if (!strcasecmp(input, "tofiles") ||
|
||||
!strcasecmp(input, "browser"))
|
||||
s->func = to_files_void;
|
||||
else if (!strcasecmp(input, "gotodir"))
|
||||
s->func = goto_dir_void;
|
||||
else if (!strcasecmp(input, "firstfile"))
|
||||
s->func = to_first_file;
|
||||
else if (!strcasecmp(input, "lastfile"))
|
||||
s->func = to_last_file;
|
||||
#endif
|
||||
else {
|
||||
#ifndef NANO_TINY
|
||||
s->func = do_toggle_void;
|
||||
if (!strcasecmp(input, "nohelp"))
|
||||
s->toggle = NO_HELP;
|
||||
else if (!strcasecmp(input, "constantshow"))
|
||||
s->toggle = CONSTANT_SHOW;
|
||||
else if (!strcasecmp(input, "softwrap"))
|
||||
s->toggle = SOFTWRAP;
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
else if (!strcasecmp(input, "linenumbers"))
|
||||
s->toggle = LINE_NUMBERS;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "whitespacedisplay"))
|
||||
s->toggle = WHITESPACE_DISPLAY;
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (!strcasecmp(input, "nosyntax"))
|
||||
s->toggle = NO_COLOR_SYNTAX;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "smarthome"))
|
||||
s->toggle = SMART_HOME;
|
||||
else if (!strcasecmp(input, "autoindent"))
|
||||
s->toggle = AUTOINDENT;
|
||||
else if (!strcasecmp(input, "cutfromcursor"))
|
||||
s->toggle = CUT_FROM_CURSOR;
|
||||
#ifdef ENABLE_WRAPPING
|
||||
else if (!strcasecmp(input, "nowrap"))
|
||||
s->toggle = BREAK_LONG_LINES;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "tabstospaces"))
|
||||
s->toggle = TABS_TO_SPACES;
|
||||
#ifdef ENABLE_MOUSE
|
||||
else if (!strcasecmp(input, "mouse"))
|
||||
s->toggle = USE_MOUSE;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "suspendenable"))
|
||||
s->toggle = SUSPEND;
|
||||
else
|
||||
#endif /* !NANO_TINY */
|
||||
{
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the symbol that corresponds to the given menu name. */
|
||||
int name_to_menu(const char *name)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
while (++index < NUMBER_OF_MENUS)
|
||||
if (strcasecmp(name, menunames[index]) == 0)
|
||||
return menusymbols[index];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the name that corresponds to the given menu symbol. */
|
||||
char *menu_to_name(int menu)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
while (++index < NUMBER_OF_MENUS)
|
||||
if (menusymbols[index] == menu)
|
||||
return menunames[index];
|
||||
|
||||
return "boooo";
|
||||
}
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
30
src/help.c
30
src/help.c
@@ -22,11 +22,11 @@
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
|
||||
static char *help_text = NULL;
|
||||
/* The text displayed in the help window. */
|
||||
|
||||
@@ -64,7 +64,7 @@ void wrap_help_text_into_buffer(void)
|
||||
do {
|
||||
openfile->current->next = make_new_node(openfile->current);
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current->data = mallocstrcpy(NULL, "");
|
||||
openfile->current->data = copy_of("");
|
||||
} while (*(++ptr) == '\n');
|
||||
}
|
||||
|
||||
@@ -88,8 +88,8 @@ void wrap_help_text_into_buffer(void)
|
||||
openfile->edittop = openfile->current;
|
||||
}
|
||||
|
||||
/* Our main help-viewer function. */
|
||||
void do_help(void)
|
||||
/* Assemble a help text, display it, and allow scrolling through it. */
|
||||
void show_help(void)
|
||||
{
|
||||
int kbinput = ERR;
|
||||
functionptrtype func;
|
||||
@@ -103,7 +103,7 @@ void do_help(void)
|
||||
#ifdef ENABLE_COLOR
|
||||
char *was_syntax = syntaxstr;
|
||||
#endif
|
||||
char *saved_answer = (answer != NULL) ? strdup(answer) : NULL;
|
||||
char *saved_answer = (answer != NULL) ? copy_of(answer) : NULL;
|
||||
/* The current answer when the user invokes help at the prompt. */
|
||||
unsigned stash[sizeof(flags) / sizeof(flags[0])];
|
||||
/* A storage place for the current flag settings. */
|
||||
@@ -140,8 +140,9 @@ void do_help(void)
|
||||
#endif
|
||||
curs_set(0);
|
||||
|
||||
/* Compose the help text from all the pieces. */
|
||||
/* Compose the help text from all the relevant pieces. */
|
||||
help_init();
|
||||
|
||||
inhelp = TRUE;
|
||||
location = 0;
|
||||
didfind = 0;
|
||||
@@ -150,8 +151,7 @@ void do_help(void)
|
||||
|
||||
/* Extract the title from the head of the help text. */
|
||||
length = break_line(help_text, MAX_BUF_SIZE, TRUE);
|
||||
title = charalloc(length * sizeof(char) + 1);
|
||||
strncpy(title, help_text, length);
|
||||
title = measured_copy(help_text, length + 1);
|
||||
title[length] = '\0';
|
||||
|
||||
titlebar(title);
|
||||
@@ -247,7 +247,6 @@ void do_help(void)
|
||||
inhelp = FALSE;
|
||||
|
||||
curs_set(0);
|
||||
refresh_needed = TRUE;
|
||||
|
||||
if (ISSET(NO_HELP)) {
|
||||
currmenu = oldmenu;
|
||||
@@ -262,7 +261,10 @@ void do_help(void)
|
||||
browser_refresh();
|
||||
else
|
||||
#endif
|
||||
{
|
||||
titlebar(NULL);
|
||||
edit_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate space for the help text for the current menu, and concatenate
|
||||
@@ -547,7 +549,6 @@ functionptrtype parse_help_input(int *kbinput)
|
||||
{
|
||||
if (!meta_key) {
|
||||
switch (*kbinput) {
|
||||
case BS_CODE:
|
||||
case '-':
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
@@ -600,14 +601,13 @@ size_t help_line_len(const char *ptr)
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_HELP */
|
||||
|
||||
/* Start the help viewer. */
|
||||
void do_help_void(void)
|
||||
/* Start the help viewer, or indicate that there is no help. */
|
||||
void do_help(void)
|
||||
{
|
||||
#ifdef ENABLE_HELP
|
||||
do_help();
|
||||
show_help();
|
||||
#else
|
||||
if (currmenu == MMAIN)
|
||||
say_there_is_no_help();
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
|
||||
#ifndef SEARCH_HISTORY
|
||||
#define SEARCH_HISTORY "search_history"
|
||||
#endif
|
||||
@@ -48,17 +48,17 @@ static poshiststruct *position_history = NULL;
|
||||
void history_init(void)
|
||||
{
|
||||
search_history = make_new_node(NULL);
|
||||
search_history->data = mallocstrcpy(NULL, "");
|
||||
search_history->data = copy_of("");
|
||||
searchtop = search_history;
|
||||
searchbot = search_history;
|
||||
|
||||
replace_history = make_new_node(NULL);
|
||||
replace_history->data = mallocstrcpy(NULL, "");
|
||||
replace_history->data = copy_of("");
|
||||
replacetop = replace_history;
|
||||
replacebot = replace_history;
|
||||
|
||||
execute_history = make_new_node(NULL);
|
||||
execute_history->data = mallocstrcpy(NULL, "");
|
||||
execute_history->data = copy_of("");
|
||||
executetop = execute_history;
|
||||
executebot = execute_history;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ void update_history(linestruct **item, const char *text)
|
||||
(*hbot)->data = mallocstrcpy((*hbot)->data, text);
|
||||
splice_node(*hbot, make_new_node(*hbot));
|
||||
*hbot = (*hbot)->next;
|
||||
(*hbot)->data = mallocstrcpy(NULL, "");
|
||||
(*hbot)->data = copy_of("");
|
||||
|
||||
/* Indicate that the history needs to be saved on exit. */
|
||||
history_changed = TRUE;
|
||||
@@ -229,19 +229,6 @@ char *get_history_completion(linestruct **h, char *s, size_t len)
|
||||
}
|
||||
#endif /* ENABLE_TABCOMP */
|
||||
|
||||
void history_error(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, _(msg), ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr, _("\nPress Enter to continue\n"));
|
||||
while (getchar() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
/* Check whether we have or could make a directory for history files. */
|
||||
bool have_statedir(void)
|
||||
{
|
||||
@@ -280,14 +267,14 @@ bool have_statedir(void)
|
||||
free(statepath);
|
||||
}
|
||||
if (mkdir(statedir, S_IRWXU) == -1) {
|
||||
history_error(N_("Unable to create directory %s: %s\n"
|
||||
jot_error(N_("Unable to create directory %s: %s\n"
|
||||
"It is required for saving/loading "
|
||||
"search history or cursor positions.\n"),
|
||||
statedir, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
} else if (!S_ISDIR(dirstat.st_mode)) {
|
||||
history_error(N_("Path %s is not a directory and needs to be.\n"
|
||||
jot_error(N_("Path %s is not a directory and needs to be.\n"
|
||||
"Nano will be unable to load or save "
|
||||
"search history or cursor positions.\n"),
|
||||
statedir);
|
||||
@@ -308,7 +295,7 @@ void load_history(void)
|
||||
if (errno != ENOENT) {
|
||||
/* When reading failed, don't save history when we quit. */
|
||||
UNSET(HISTORYLOG);
|
||||
history_error(N_("Error reading %s: %s"), histname,
|
||||
jot_error(N_("Error reading %s: %s"), histname,
|
||||
strerror(errno));
|
||||
}
|
||||
} else {
|
||||
@@ -404,7 +391,7 @@ void load_poshistory(void)
|
||||
if (errno != ENOENT) {
|
||||
/* When reading failed, don't save history when we quit. */
|
||||
UNSET(POSITIONLOG);
|
||||
history_error(N_("Error reading %s: %s"), poshistname, strerror(errno));
|
||||
jot_error(N_("Error reading %s: %s"), poshistname, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
char *line = NULL, *lineptr, *xptr;
|
||||
@@ -414,7 +401,7 @@ void load_poshistory(void)
|
||||
|
||||
/* Read and parse each line, and store the extracted data. */
|
||||
while ((read = getline(&line, &buf_len, hisfile)) > 5) {
|
||||
/* Decode nulls as embedded newlines. */
|
||||
/* Decode NULs as embedded newlines. */
|
||||
unsunder(line, read);
|
||||
|
||||
/* Find where the x index and line number are in the line. */
|
||||
@@ -431,7 +418,7 @@ void load_poshistory(void)
|
||||
|
||||
/* Create a new position record. */
|
||||
newrecord = (poshiststruct *)nmalloc(sizeof(poshiststruct));
|
||||
newrecord->filename = mallocstrcpy(NULL, line);
|
||||
newrecord->filename = copy_of(line);
|
||||
newrecord->lineno = atoi(lineptr);
|
||||
newrecord->xno = atoi(xptr);
|
||||
newrecord->next = NULL;
|
||||
@@ -484,7 +471,7 @@ void save_poshistory(void)
|
||||
posptr->filename, posptr->lineno, posptr->xno);
|
||||
length = strlen(path_and_place);
|
||||
|
||||
/* Encode newlines in filenames as nulls. */
|
||||
/* Encode newlines in filenames as NULs. */
|
||||
sunder(path_and_place);
|
||||
/* Restore the terminating newline. */
|
||||
path_and_place[length - 1] = '\n';
|
||||
@@ -563,7 +550,7 @@ void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
|
||||
* not at the end, move the matching one to the end. */
|
||||
if (theone == NULL) {
|
||||
theone = (poshiststruct *)nmalloc(sizeof(poshiststruct));
|
||||
theone->filename = mallocstrcpy(NULL, fullpath);
|
||||
theone->filename = copy_of(fullpath);
|
||||
if (position_history == NULL)
|
||||
position_history = theone;
|
||||
else
|
||||
|
||||
80
src/nano.c
80
src/nano.c
@@ -100,7 +100,7 @@ linestruct *copy_node(const linestruct *src)
|
||||
{
|
||||
linestruct *dst = nmalloc(sizeof(linestruct));
|
||||
|
||||
dst->data = mallocstrcpy(NULL, src->data);
|
||||
dst->data = copy_of(src->data);
|
||||
dst->next = src->next;
|
||||
dst->prev = src->prev;
|
||||
dst->lineno = src->lineno;
|
||||
@@ -127,33 +127,33 @@ void splice_node(linestruct *afterthis, linestruct *newnode)
|
||||
}
|
||||
|
||||
/* Disconnect a node from a linked list of linestructs and delete it. */
|
||||
void unlink_node(linestruct *fileptr)
|
||||
void unlink_node(linestruct *line)
|
||||
{
|
||||
if (fileptr->prev != NULL)
|
||||
fileptr->prev->next = fileptr->next;
|
||||
if (fileptr->next != NULL)
|
||||
fileptr->next->prev = fileptr->prev;
|
||||
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 == fileptr)
|
||||
openfile->filebot = fileptr->prev;
|
||||
if (openfile && openfile->filebot == line)
|
||||
openfile->filebot = line->prev;
|
||||
|
||||
delete_node(fileptr);
|
||||
delete_node(line);
|
||||
}
|
||||
|
||||
/* Free the data structures in the given node. */
|
||||
void delete_node(linestruct *fileptr)
|
||||
void delete_node(linestruct *line)
|
||||
{
|
||||
#ifdef ENABLE_WRAPPING
|
||||
/* If the spill-over line for hard-wrapping is deleted... */
|
||||
if (fileptr == openfile->spillage_line)
|
||||
if (line == openfile->spillage_line)
|
||||
openfile->spillage_line = NULL;
|
||||
#endif
|
||||
free(fileptr->data);
|
||||
free(line->data);
|
||||
#ifdef ENABLE_COLOR
|
||||
free(fileptr->multidata);
|
||||
free(line->multidata);
|
||||
#endif
|
||||
free(fileptr);
|
||||
free(line);
|
||||
}
|
||||
|
||||
/* Duplicate an entire linked list of linestructs. */
|
||||
@@ -226,14 +226,14 @@ void partition_buffer(linestruct *top, size_t top_x,
|
||||
* top of the partition from it, and save the text before top_x. */
|
||||
foreline = top->prev;
|
||||
top->prev = NULL;
|
||||
antedata = mallocstrncpy(NULL, top->data, top_x + 1);
|
||||
antedata = measured_copy(top->data, top_x + 1);
|
||||
antedata[top_x] = '\0';
|
||||
|
||||
/* Remember which line is below the bottom of the partition, detach the
|
||||
* bottom of the partition from it, and save the text after bot_x. */
|
||||
hindline = bot->next;
|
||||
bot->next = NULL;
|
||||
postdata = mallocstrcpy(NULL, bot->data + bot_x);
|
||||
postdata = copy_of(bot->data + bot_x);
|
||||
|
||||
/* At the end of the partition, remove all text after bot_x. */
|
||||
bot->data[bot_x] = '\0';
|
||||
@@ -255,7 +255,7 @@ void unpartition_buffer(void)
|
||||
strlen(antedata) + strlen(openfile->filetop->data) + 1);
|
||||
memmove(openfile->filetop->data + strlen(antedata),
|
||||
openfile->filetop->data, strlen(openfile->filetop->data) + 1);
|
||||
strncpy(openfile->filetop->data, antedata, strlen(antedata));
|
||||
memcpy(openfile->filetop->data, antedata, strlen(antedata));
|
||||
free(antedata);
|
||||
antedata = NULL;
|
||||
|
||||
@@ -342,7 +342,7 @@ void extract(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x)
|
||||
|
||||
/* Since the text has now been saved, remove it from the file buffer. */
|
||||
openfile->filetop = make_new_node(NULL);
|
||||
openfile->filetop->data = mallocstrcpy(NULL, "");
|
||||
openfile->filetop->data = copy_of("");
|
||||
openfile->filebot = openfile->filetop;
|
||||
|
||||
/* Restore the current line and cursor position. If the mark begins
|
||||
@@ -463,11 +463,15 @@ void print_view_warning(void)
|
||||
statusbar(_("Key is invalid in view mode"));
|
||||
}
|
||||
|
||||
/* Indicate that something is disabled in restricted mode. */
|
||||
void show_restricted_warning(void)
|
||||
/* When in restricted mode, show a warning and return TRUE. */
|
||||
bool in_restricted_mode(void)
|
||||
{
|
||||
statusbar(_("This function is disabled in restricted mode"));
|
||||
beep();
|
||||
if (ISSET(RESTRICTED)) {
|
||||
statusbar(_("This function is disabled in restricted mode"));
|
||||
beep();
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_HELP
|
||||
@@ -500,7 +504,7 @@ void finish(void)
|
||||
/* Restore the old terminal settings. */
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
display_rcfile_errors();
|
||||
#endif
|
||||
|
||||
@@ -1340,10 +1344,8 @@ void do_toggle(int flag)
|
||||
{
|
||||
bool enabled;
|
||||
|
||||
if (flag == SUSPEND && ISSET(RESTRICTED)) {
|
||||
show_restricted_warning();
|
||||
if (flag == SUSPEND && in_restricted_mode())
|
||||
return;
|
||||
}
|
||||
|
||||
TOGGLE(flag);
|
||||
focusing = FALSE;
|
||||
@@ -1811,7 +1813,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
output[i] = '\n';
|
||||
|
||||
/* Get the next multibyte character. */
|
||||
charlen = parse_mbchar(output + i, onechar, NULL);
|
||||
charlen = collect_char(output + i, onechar);
|
||||
|
||||
i += charlen;
|
||||
|
||||
@@ -1837,7 +1839,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
if (openfile->last_action != ADD ||
|
||||
openfile->current_undo->mark_begin_lineno != openfile->current->lineno ||
|
||||
openfile->current_undo->mark_begin_x != openfile->current_x)
|
||||
add_undo(ADD);
|
||||
add_undo(ADD, NULL);
|
||||
|
||||
/* Note that current_x has not yet been incremented. */
|
||||
if (openfile->current == openfile->mark &&
|
||||
@@ -2442,11 +2444,11 @@ int main(int argc, char **argv)
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
/* Set the default value for things that weren't specified. */
|
||||
if (punct == NULL)
|
||||
punct = mallocstrcpy(NULL, "!.?");
|
||||
punct = copy_of("!.?");
|
||||
if (brackets == NULL)
|
||||
brackets = mallocstrcpy(NULL, "\"')>]}");
|
||||
brackets = copy_of("\"')>]}");
|
||||
if (quotestr == NULL)
|
||||
quotestr = mallocstrcpy(NULL, "^([ \t]*([!#%:;>|}]|/{2}))+");
|
||||
quotestr = copy_of("^([ \t]*([!#%:;>|}]|/{2}))+");
|
||||
|
||||
/* Compile the quoting regex, and exit when it's invalid. */
|
||||
quoterc = regcomp("ereg, quotestr, NANO_REG_EXTENDED);
|
||||
@@ -2470,14 +2472,14 @@ int main(int argc, char **argv)
|
||||
const char *spellenv = getenv("SPELL");
|
||||
|
||||
if (spellenv != NULL)
|
||||
alt_speller = mallocstrcpy(NULL, spellenv);
|
||||
alt_speller = copy_of(spellenv);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If matchbrackets wasn't specified, set its default value. */
|
||||
if (matchbrackets == NULL)
|
||||
matchbrackets = mallocstrcpy(NULL, "(<[{)>]}");
|
||||
matchbrackets = copy_of("(<[{)>]}");
|
||||
|
||||
/* If the whitespace option wasn't specified, set its default value. */
|
||||
if (whitespace == NULL) {
|
||||
@@ -2485,13 +2487,13 @@ int main(int argc, char **argv)
|
||||
if (using_utf8()) {
|
||||
/* A tab is shown as a Right-Pointing Double Angle Quotation Mark
|
||||
* (U+00BB), and a space as a Middle Dot (U+00B7). */
|
||||
whitespace = mallocstrcpy(NULL, "\xC2\xBB\xC2\xB7");
|
||||
whitespace = copy_of("\xC2\xBB\xC2\xB7");
|
||||
whitelen[0] = 2;
|
||||
whitelen[1] = 2;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
whitespace = mallocstrcpy(NULL, ">.");
|
||||
whitespace = copy_of(">.");
|
||||
whitelen[0] = 1;
|
||||
whitelen[1] = 1;
|
||||
}
|
||||
@@ -2499,7 +2501,7 @@ int main(int argc, char **argv)
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Initialize the search string. */
|
||||
last_search = mallocstrcpy(NULL, "");
|
||||
last_search = copy_of("");
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
|
||||
/* If tabsize wasn't specified, set its default value. */
|
||||
@@ -2607,7 +2609,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if (argv[optind][n] == '/' || argv[optind][n] == '?') {
|
||||
if (argv[optind][n + 1]) {
|
||||
searchstring = mallocstrcpy(NULL, &argv[optind][n + 1]);
|
||||
searchstring = copy_of(&argv[optind][n + 1]);
|
||||
if (argv[optind][n] == '?')
|
||||
SET(BACKWARDS_SEARCH);
|
||||
} else if (n == 1)
|
||||
@@ -2683,8 +2685,8 @@ int main(int argc, char **argv)
|
||||
prepare_for_display();
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
if (rcfile_with_errors != NULL)
|
||||
statusline(ALERT, _("Mistakes in '%s'"), rcfile_with_errors);
|
||||
if (startup_problem != NULL)
|
||||
statusline(ALERT, startup_problem);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef NANO_H
|
||||
#define NANO_H 1
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@@ -234,6 +231,8 @@ typedef struct syntaxtype {
|
||||
/* The list of libmagic results that this syntax applies to. */
|
||||
char *linter;
|
||||
/* The command with which to lint this type of file. */
|
||||
char *formatter;
|
||||
/* The command with which to format/modify/arrange this type of file. */
|
||||
char *tab;
|
||||
/* What the Tab key should produce; NULL for default behavior. */
|
||||
#ifdef ENABLE_COMMENT
|
||||
@@ -650,5 +649,3 @@ enum
|
||||
|
||||
/* The largest size_t number that doesn't have the high bit set. */
|
||||
#define HIGHEST_POSITIVE ((~(size_t)0) >> 1)
|
||||
|
||||
#endif /* !NANO_H */
|
||||
|
||||
14
src/prompt.c
14
src/prompt.c
@@ -203,7 +203,7 @@ void do_statusbar_output(int *the_input, size_t input_len,
|
||||
output[j] = '\n';
|
||||
|
||||
/* Interpret the next multibyte character. */
|
||||
charlen = parse_mbchar(output + j, onechar, NULL);
|
||||
charlen = collect_char(output + j, onechar);
|
||||
|
||||
j += charlen;
|
||||
|
||||
@@ -543,9 +543,9 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
}
|
||||
} else
|
||||
#endif /* ENABLE_HISTORIES */
|
||||
if (func == do_help_void) {
|
||||
if (func == do_help) {
|
||||
/* This key has a shortcut-list entry when it's used to go to
|
||||
* the help browser or display a message indicating that help
|
||||
* 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. */
|
||||
@@ -581,10 +581,10 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
*
|
||||
* The allow_tabs parameter indicates whether tab completion is allowed,
|
||||
* and allow_files indicates whether all files (and not just directories)
|
||||
* can be tab completed. The curranswer parameter is the default answer
|
||||
* can be tab completed. The 'provided' parameter is the default answer
|
||||
* for when simply Enter is typed. */
|
||||
int do_prompt(bool allow_tabs, bool allow_files,
|
||||
int menu, const char *curranswer, linestruct **history_list,
|
||||
int menu, const char *provided, linestruct **history_list,
|
||||
void (*refresh_func)(void), const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@@ -597,8 +597,8 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
||||
|
||||
bottombars(menu);
|
||||
|
||||
if (answer != curranswer || answer == NULL)
|
||||
answer = mallocstrcpy(answer, curranswer);
|
||||
if (answer != provided)
|
||||
answer = mallocstrcpy(answer, provided);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
redo_theprompt:
|
||||
|
||||
44
src/proto.h
44
src/proto.h
@@ -18,9 +18,6 @@
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef PROTO_H
|
||||
#define PROTO_H 1
|
||||
|
||||
#include "nano.h"
|
||||
|
||||
/* All external variables. See global.c for their descriptions. */
|
||||
@@ -176,8 +173,8 @@ extern int interface_color_pair[NUMBER_OF_ELEMENTS];
|
||||
|
||||
extern char *homedir;
|
||||
extern char *statedir;
|
||||
#ifdef ENABLE_NANORC
|
||||
extern char *rcfile_with_errors;
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
extern char *startup_problem;
|
||||
#endif
|
||||
|
||||
extern bool spotlighted;
|
||||
@@ -219,7 +216,8 @@ int mbwidth(const char *c);
|
||||
char *make_mbchar(long chr, int *chr_mb_len);
|
||||
int char_length(const char *pointer);
|
||||
size_t mbstrlen(const char *s);
|
||||
int parse_mbchar(const char *buf, char *chr, size_t *col);
|
||||
int collect_char(const char *buf, char *chr);
|
||||
int advance_over(const char *string, size_t *column);
|
||||
size_t step_left(const char *buf, size_t pos);
|
||||
size_t step_right(const char *buf, size_t pos);
|
||||
int mbstrcasecmp(const char *s1, const char *s2);
|
||||
@@ -276,7 +274,8 @@ void make_new_buffer(void);
|
||||
void set_modified(void);
|
||||
bool open_buffer(const char *filename, bool new_buffer);
|
||||
#ifdef ENABLE_SPELLER
|
||||
bool replace_buffer(const char *filename, undo_type action, bool marked);
|
||||
bool replace_buffer(const char *filename, undo_type action, bool marked,
|
||||
const char *operation);
|
||||
#endif
|
||||
void prepare_for_display(void);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
@@ -329,21 +328,15 @@ 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);
|
||||
#ifdef ENABLE_NANORC
|
||||
keystruct *strtosc(const char *input);
|
||||
int name_to_menu(const char *name);
|
||||
char *menu_to_name(int menu);
|
||||
#endif
|
||||
|
||||
/* All functions in help.c. */
|
||||
#ifdef ENABLE_HELP
|
||||
void wrap_help_text_into_buffer(void);
|
||||
void do_help(void);
|
||||
void help_init(void);
|
||||
functionptrtype parse_help_input(int *kbinput);
|
||||
size_t help_line_len(const char *ptr);
|
||||
#endif
|
||||
void do_help_void(void);
|
||||
void do_help(void);
|
||||
|
||||
/* Most functions in history.c. */
|
||||
#ifdef ENABLE_HISTORIES
|
||||
@@ -408,7 +401,7 @@ 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);
|
||||
void show_restricted_warning(void);
|
||||
bool in_restricted_mode(void);
|
||||
#ifndef ENABLE_HELP
|
||||
void say_there_is_no_help(void);
|
||||
#endif
|
||||
@@ -471,8 +464,11 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
||||
int do_yesno_prompt(bool all, const char *msg);
|
||||
|
||||
/* Most functions in rcfile.c. */
|
||||
#ifdef ENABLE_NANORC
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
void display_rcfile_errors(void);
|
||||
void jot_error(const char *msg, ...);
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
#ifdef ENABLE_COLOR
|
||||
void parse_one_include(char *file, syntaxtype *syntax);
|
||||
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage);
|
||||
@@ -525,7 +521,7 @@ void do_enter(void);
|
||||
RETSIGTYPE cancel_command(int signal);
|
||||
bool execute_command(const char *command);
|
||||
void discard_until(const undostruct *thisitem, openfilestruct *thefile, bool keep);
|
||||
void add_undo(undo_type action);
|
||||
void add_undo(undo_type action, const char *message);
|
||||
void update_multiline_undo(ssize_t lineno, char *indentation);
|
||||
void update_undo(undo_type action);
|
||||
#endif /* !NANO_TINY */
|
||||
@@ -535,7 +531,7 @@ bool do_wrap(void);
|
||||
#if defined(ENABLE_HELP) || defined(ENABLED_WRAPORJUSTIFY)
|
||||
ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl);
|
||||
#endif
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
|
||||
#if !defined(NANO_TINY) || defined(ENABLED_WRAPORJUSTIFY)
|
||||
size_t indent_length(const char *line);
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
@@ -551,6 +547,7 @@ void do_spell(void);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
void do_linter(void);
|
||||
void do_formatter(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_wordlinechar_count(void);
|
||||
@@ -567,8 +564,8 @@ int digits(ssize_t n);
|
||||
#endif
|
||||
bool parse_num(const char *str, ssize_t *val);
|
||||
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column);
|
||||
void unsunder(char *str, size_t true_len);
|
||||
void sunder(char *str);
|
||||
void unsunder(char *string, size_t length);
|
||||
void sunder(char *string);
|
||||
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
|
||||
void free_chararray(char **array, size_t len);
|
||||
#endif
|
||||
@@ -579,8 +576,9 @@ const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *start);
|
||||
void *nmalloc(size_t howmuch);
|
||||
void *nrealloc(void *ptr, size_t howmuch);
|
||||
char *mallocstrncpy(char *dest, const char *src, size_t n);
|
||||
char *measured_copy(const char *src, size_t n);
|
||||
char *mallocstrcpy(char *dest, const char *src);
|
||||
char *copy_of(const char *string);
|
||||
char *free_and_assign(char *dest, char *src);
|
||||
size_t get_page_start(size_t column);
|
||||
size_t xplustabs(void);
|
||||
@@ -629,9 +627,9 @@ void check_statusblank(void);
|
||||
char *display_string(const char *buf, size_t column, size_t span,
|
||||
bool isdata, bool isprompt);
|
||||
void titlebar(const char *path);
|
||||
void statusline(message_type importance, const char *msg, ...);
|
||||
void statusbar(const char *msg);
|
||||
void warn_and_shortly_pause(const char *msg);
|
||||
void statusline(message_type importance, const char *msg, ...);
|
||||
void bottombars(int menu);
|
||||
void post_one_key(const char *keystroke, const char *tag, int width);
|
||||
void place_the_cursor(void);
|
||||
@@ -698,5 +696,3 @@ void flip_newbuffer(void);
|
||||
#endif
|
||||
void discard_buffer(void);
|
||||
void do_cancel(void);
|
||||
|
||||
#endif /* !PROTO_H */
|
||||
|
||||
616
src/rcfile.c
616
src/rcfile.c
@@ -23,14 +23,14 @@
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <glob.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
|
||||
#ifndef RCFILE_NAME
|
||||
#define HOME_RC_NAME ".nanorc"
|
||||
#define RCFILE_NAME "nanorc"
|
||||
@@ -67,7 +67,7 @@ static const rcoption rcopts[] = {
|
||||
#endif
|
||||
{"nohelp", NO_HELP},
|
||||
{"nonewlines", NO_NEWLINES},
|
||||
{"nopauses", NO_PAUSES},
|
||||
{"nopauses", NO_PAUSES}, /* Obsolete; remove in 2021. */
|
||||
#ifdef ENABLE_WRAPPING
|
||||
{"nowrap", NO_WRAP}, /* Deprecated; remove in 2021. */
|
||||
#endif
|
||||
@@ -147,6 +147,20 @@ static colortype *lastcolor = NULL;
|
||||
/* The end of the color list for the current syntax. */
|
||||
#endif
|
||||
|
||||
#define NUMBER_OF_MENUS 16
|
||||
char *menunames[NUMBER_OF_MENUS] = { "main", "search", "replace", "replacewith",
|
||||
"yesno", "gotoline", "writeout", "insert",
|
||||
"extcmd", "help", "spell", "linter",
|
||||
"browser", "whereisfile", "gotodir",
|
||||
"all" };
|
||||
int menusymbols[NUMBER_OF_MENUS] = { MMAIN, MWHEREIS, MREPLACE, MREPLACEWITH,
|
||||
MYESNO, MGOTOLINE, MWRITEFILE, MINSERTFILE,
|
||||
MEXTCMD, MHELP, MSPELL, MLINTER,
|
||||
MBROWSER, MWHEREISFILE, MGOTODIR,
|
||||
MMOST|MBROWSER|MHELP|MYESNO };
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
static linestruct *errors_head = NULL;
|
||||
static linestruct *errors_tail = NULL;
|
||||
/* Beginning and end of a list of errors in rcfiles, if any. */
|
||||
@@ -174,13 +188,20 @@ void jot_error(const char *msg, ...)
|
||||
errors_tail->next = error;
|
||||
errors_tail = error;
|
||||
|
||||
if (rcfile_with_errors == NULL)
|
||||
rcfile_with_errors = strdup(nanorc);
|
||||
|
||||
if (startup_problem == NULL) {
|
||||
#ifdef ENABLE_NANORC
|
||||
if (nanorc != NULL) {
|
||||
snprintf(textbuf, MAXSIZE, _("Mistakes in '%s'"), nanorc);
|
||||
startup_problem = copy_of(textbuf);
|
||||
} else
|
||||
#endif
|
||||
startup_problem = copy_of(_("Problems with history file"));
|
||||
}
|
||||
#ifdef ENABLE_NANORC
|
||||
if (lineno > 0)
|
||||
length = snprintf(textbuf, MAXSIZE, _("Error in %s on line %zu: "),
|
||||
nanorc, lineno);
|
||||
|
||||
#endif
|
||||
va_start(ap, msg);
|
||||
length += vsnprintf(textbuf + length, MAXSIZE - length, _(msg), ap);
|
||||
va_end(ap);
|
||||
@@ -188,6 +209,297 @@ void jot_error(const char *msg, ...)
|
||||
error->data = nmalloc(length + 1);
|
||||
sprintf(error->data, "%s", textbuf);
|
||||
}
|
||||
#endif /* ENABLE_NANORC || ENABLE_HISTORIES */
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
/* Interpret a function string given in the rc file, and return a
|
||||
* shortcut record with the corresponding function filled in. */
|
||||
keystruct *strtosc(const char *input)
|
||||
{
|
||||
keystruct *s = nmalloc(sizeof(keystruct));
|
||||
|
||||
#ifndef NANO_TINY
|
||||
s->toggle = 0;
|
||||
#endif
|
||||
|
||||
if (!strcmp(input, "cancel"))
|
||||
s->func = do_cancel;
|
||||
#ifdef ENABLE_HELP
|
||||
else if (!strcmp(input, "help"))
|
||||
s->func = do_help;
|
||||
#endif
|
||||
else if (!strcmp(input, "exit"))
|
||||
s->func = do_exit;
|
||||
else if (!strcmp(input, "discardbuffer"))
|
||||
s->func = discard_buffer;
|
||||
else if (!strcmp(input, "writeout"))
|
||||
s->func = do_writeout_void;
|
||||
else if (!strcmp(input, "savefile"))
|
||||
s->func = do_savefile;
|
||||
else if (!strcmp(input, "insert"))
|
||||
s->func = do_insertfile_void;
|
||||
else if (!strcmp(input, "whereis"))
|
||||
s->func = do_search_forward;
|
||||
else if (!strcmp(input, "wherewas"))
|
||||
s->func = do_search_backward;
|
||||
else if (!strcmp(input, "findprevious"))
|
||||
s->func = do_findprevious;
|
||||
else if (!strcmp(input, "findnext"))
|
||||
s->func = do_findnext;
|
||||
else if (!strcmp(input, "replace"))
|
||||
s->func = do_replace;
|
||||
else if (!strcmp(input, "cut"))
|
||||
s->func = cut_text;
|
||||
else if (!strcmp(input, "paste"))
|
||||
s->func = paste_text;
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcmp(input, "cutrestoffile"))
|
||||
s->func = cut_till_eof;
|
||||
else if (!strcmp(input, "copy"))
|
||||
s->func = copy_text;
|
||||
else if (!strcmp(input, "zap"))
|
||||
s->func = zap_text;
|
||||
else if (!strcmp(input, "mark"))
|
||||
s->func = do_mark;
|
||||
#endif
|
||||
#ifdef ENABLE_SPELLER
|
||||
else if (!strcmp(input, "tospell") ||
|
||||
!strcmp(input, "speller"))
|
||||
s->func = do_spell;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (!strcmp(input, "linter"))
|
||||
s->func = do_linter;
|
||||
#ifdef ENABLE_SPELLER
|
||||
else if (!strcmp(input, "formatter"))
|
||||
s->func = do_formatter;
|
||||
#endif
|
||||
#endif
|
||||
else if (!strcmp(input, "curpos"))
|
||||
s->func = do_cursorpos_void;
|
||||
else if (!strcmp(input, "gotoline"))
|
||||
s->func = do_gotolinecolumn_void;
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
else if (!strcmp(input, "justify"))
|
||||
s->func = do_justify_void;
|
||||
else if (!strcmp(input, "fulljustify"))
|
||||
s->func = do_full_justify;
|
||||
else if (!strcmp(input, "beginpara"))
|
||||
s->func = do_para_begin_void;
|
||||
else if (!strcmp(input, "endpara"))
|
||||
s->func = do_para_end_void;
|
||||
#endif
|
||||
#ifdef ENABLE_COMMENT
|
||||
else if (!strcmp(input, "comment"))
|
||||
s->func = do_comment;
|
||||
#endif
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
else if (!strcmp(input, "complete"))
|
||||
s->func = complete_a_word;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcmp(input, "indent"))
|
||||
s->func = do_indent;
|
||||
else if (!strcmp(input, "unindent"))
|
||||
s->func = do_unindent;
|
||||
else if (!strcmp(input, "chopwordleft") ||
|
||||
!strcmp(input, "cutwordleft")) /* Deprecated; remove in 2021. */
|
||||
s->func = chop_previous_word;
|
||||
else if (!strcmp(input, "chopwordright") ||
|
||||
!strcmp(input, "cutwordright")) /* Deprecated; remove in 2021. */
|
||||
s->func = chop_next_word;
|
||||
else if (!strcmp(input, "findbracket"))
|
||||
s->func = do_find_bracket;
|
||||
else if (!strcmp(input, "wordcount"))
|
||||
s->func = do_wordlinechar_count;
|
||||
else if (!strcmp(input, "recordmacro"))
|
||||
s->func = record_macro;
|
||||
else if (!strcmp(input, "runmacro"))
|
||||
s->func = run_macro;
|
||||
else if (!strcmp(input, "undo"))
|
||||
s->func = do_undo;
|
||||
else if (!strcmp(input, "redo"))
|
||||
s->func = do_redo;
|
||||
#endif
|
||||
else if (!strcmp(input, "left") ||
|
||||
!strcmp(input, "back"))
|
||||
s->func = do_left;
|
||||
else if (!strcmp(input, "right") ||
|
||||
!strcmp(input, "forward"))
|
||||
s->func = do_right;
|
||||
else if (!strcmp(input, "up") ||
|
||||
!strcmp(input, "prevline"))
|
||||
s->func = do_up;
|
||||
else if (!strcmp(input, "down") ||
|
||||
!strcmp(input, "nextline"))
|
||||
s->func = do_down;
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
else if (!strcmp(input, "scrollup"))
|
||||
s->func = do_scroll_up;
|
||||
else if (!strcmp(input, "scrolldown"))
|
||||
s->func = do_scroll_down;
|
||||
#endif
|
||||
else if (!strcmp(input, "prevword"))
|
||||
s->func = do_prev_word_void;
|
||||
else if (!strcmp(input, "nextword"))
|
||||
s->func = do_next_word_void;
|
||||
else if (!strcmp(input, "home"))
|
||||
s->func = do_home;
|
||||
else if (!strcmp(input, "end"))
|
||||
s->func = do_end;
|
||||
else if (!strcmp(input, "prevblock"))
|
||||
s->func = do_prev_block;
|
||||
else if (!strcmp(input, "nextblock"))
|
||||
s->func = do_next_block;
|
||||
else if (!strcmp(input, "pageup") ||
|
||||
!strcmp(input, "prevpage"))
|
||||
s->func = do_page_up;
|
||||
else if (!strcmp(input, "pagedown") ||
|
||||
!strcmp(input, "nextpage"))
|
||||
s->func = do_page_down;
|
||||
else if (!strcmp(input, "firstline"))
|
||||
s->func = to_first_line;
|
||||
else if (!strcmp(input, "lastline"))
|
||||
s->func = to_last_line;
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
else if (!strcmp(input, "prevbuf"))
|
||||
s->func = switch_to_prev_buffer;
|
||||
else if (!strcmp(input, "nextbuf"))
|
||||
s->func = switch_to_next_buffer;
|
||||
#endif
|
||||
else if (!strcmp(input, "verbatim"))
|
||||
s->func = do_verbatim_input;
|
||||
else if (!strcmp(input, "tab"))
|
||||
s->func = do_tab;
|
||||
else if (!strcmp(input, "enter"))
|
||||
s->func = do_enter;
|
||||
else if (!strcmp(input, "delete"))
|
||||
s->func = do_delete;
|
||||
else if (!strcmp(input, "backspace"))
|
||||
s->func = do_backspace;
|
||||
else if (!strcmp(input, "refresh"))
|
||||
s->func = total_refresh;
|
||||
else if (!strcmp(input, "suspend"))
|
||||
s->func = do_suspend_void;
|
||||
else if (!strcmp(input, "casesens"))
|
||||
s->func = case_sens_void;
|
||||
else if (!strcmp(input, "regexp"))
|
||||
s->func = regexp_void;
|
||||
else if (!strcmp(input, "backwards"))
|
||||
s->func = backwards_void;
|
||||
else if (!strcmp(input, "flipreplace"))
|
||||
s->func = flip_replace;
|
||||
else if (!strcmp(input, "flipgoto"))
|
||||
s->func = flip_goto;
|
||||
#ifdef ENABLE_HISTORIES
|
||||
else if (!strcmp(input, "older"))
|
||||
s->func = get_history_older_void;
|
||||
else if (!strcmp(input, "newer"))
|
||||
s->func = get_history_newer_void;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcmp(input, "dosformat"))
|
||||
s->func = dos_format_void;
|
||||
else if (!strcmp(input, "macformat"))
|
||||
s->func = mac_format_void;
|
||||
else if (!strcmp(input, "append"))
|
||||
s->func = append_void;
|
||||
else if (!strcmp(input, "prepend"))
|
||||
s->func = prepend_void;
|
||||
else if (!strcmp(input, "backup"))
|
||||
s->func = backup_file_void;
|
||||
else if (!strcmp(input, "flipexecute"))
|
||||
s->func = flip_execute;
|
||||
else if (!strcmp(input, "flippipe"))
|
||||
s->func = flip_pipe;
|
||||
else if (!strcmp(input, "flipconvert"))
|
||||
s->func = flip_convert;
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
else if (!strcmp(input, "flipnewbuffer"))
|
||||
s->func = flip_newbuffer;
|
||||
#endif
|
||||
#ifdef ENABLE_BROWSER
|
||||
else if (!strcmp(input, "tofiles") ||
|
||||
!strcmp(input, "browser"))
|
||||
s->func = to_files_void;
|
||||
else if (!strcmp(input, "gotodir"))
|
||||
s->func = goto_dir_void;
|
||||
else if (!strcmp(input, "firstfile"))
|
||||
s->func = to_first_file;
|
||||
else if (!strcmp(input, "lastfile"))
|
||||
s->func = to_last_file;
|
||||
#endif
|
||||
else {
|
||||
#ifndef NANO_TINY
|
||||
s->func = do_toggle_void;
|
||||
if (!strcmp(input, "nohelp"))
|
||||
s->toggle = NO_HELP;
|
||||
else if (!strcmp(input, "constantshow"))
|
||||
s->toggle = CONSTANT_SHOW;
|
||||
else if (!strcmp(input, "softwrap"))
|
||||
s->toggle = SOFTWRAP;
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
else if (!strcmp(input, "linenumbers"))
|
||||
s->toggle = LINE_NUMBERS;
|
||||
#endif
|
||||
else if (!strcmp(input, "whitespacedisplay"))
|
||||
s->toggle = WHITESPACE_DISPLAY;
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (!strcmp(input, "nosyntax"))
|
||||
s->toggle = NO_COLOR_SYNTAX;
|
||||
#endif
|
||||
else if (!strcmp(input, "smarthome"))
|
||||
s->toggle = SMART_HOME;
|
||||
else if (!strcmp(input, "autoindent"))
|
||||
s->toggle = AUTOINDENT;
|
||||
else if (!strcmp(input, "cutfromcursor"))
|
||||
s->toggle = CUT_FROM_CURSOR;
|
||||
#ifdef ENABLE_WRAPPING
|
||||
else if (!strcmp(input, "nowrap"))
|
||||
s->toggle = BREAK_LONG_LINES;
|
||||
#endif
|
||||
else if (!strcmp(input, "tabstospaces"))
|
||||
s->toggle = TABS_TO_SPACES;
|
||||
#ifdef ENABLE_MOUSE
|
||||
else if (!strcmp(input, "mouse"))
|
||||
s->toggle = USE_MOUSE;
|
||||
#endif
|
||||
else if (!strcmp(input, "suspendenable"))
|
||||
s->toggle = SUSPEND;
|
||||
else
|
||||
#endif /* !NANO_TINY */
|
||||
{
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the symbol that corresponds to the given menu name. */
|
||||
int name_to_menu(const char *name)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
while (++index < NUMBER_OF_MENUS)
|
||||
if (strcmp(name, menunames[index]) == 0)
|
||||
return menusymbols[index];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the name that corresponds to the given menu symbol. */
|
||||
char *menu_to_name(int menu)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
while (++index < NUMBER_OF_MENUS)
|
||||
if (menusymbols[index] == menu)
|
||||
return menunames[index];
|
||||
|
||||
return "boooo";
|
||||
}
|
||||
|
||||
/* Parse the next word from the string, null-terminate it, and return
|
||||
* a pointer to the first character after the null terminator. The
|
||||
@@ -325,17 +637,18 @@ void begin_new_syntax(char *ptr)
|
||||
|
||||
/* Initialize a new syntax struct. */
|
||||
live_syntax = (syntaxtype *)nmalloc(sizeof(syntaxtype));
|
||||
live_syntax->name = mallocstrcpy(NULL, nameptr);
|
||||
live_syntax->filename = strdup(nanorc);
|
||||
live_syntax->name = copy_of(nameptr);
|
||||
live_syntax->filename = copy_of(nanorc);
|
||||
live_syntax->lineno = lineno;
|
||||
live_syntax->augmentations = NULL;
|
||||
live_syntax->extensions = NULL;
|
||||
live_syntax->headers = NULL;
|
||||
live_syntax->magics = NULL;
|
||||
live_syntax->linter = NULL;
|
||||
live_syntax->formatter = NULL;
|
||||
live_syntax->tab = NULL;
|
||||
#ifdef ENABLE_COMMENT
|
||||
live_syntax->comment = mallocstrcpy(NULL, GENERAL_COMMENT_CHARACTER);
|
||||
live_syntax->comment = copy_of(GENERAL_COMMENT_CHARACTER);
|
||||
#endif
|
||||
live_syntax->color = NULL;
|
||||
live_syntax->nmultis = 0;
|
||||
@@ -405,9 +718,9 @@ void parse_binding(char *ptr, bool dobind)
|
||||
|
||||
keyptr = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
keycopy = mallocstrcpy(NULL, keyptr);
|
||||
keycopy = copy_of(keyptr);
|
||||
|
||||
if (strlen(keycopy) < 2) {
|
||||
if (keycopy[1] == '\0') {
|
||||
jot_error(N_("Key name is too short"));
|
||||
goto free_things;
|
||||
}
|
||||
@@ -416,12 +729,11 @@ void parse_binding(char *ptr, bool dobind)
|
||||
keycopy[0] = toupper((unsigned char)keycopy[0]);
|
||||
keycopy[1] = toupper((unsigned char)keycopy[1]);
|
||||
if (keycopy[0] == 'M' && keycopy[1] == '-') {
|
||||
if (strlen(keycopy) > 2)
|
||||
keycopy[2] = toupper((unsigned char)keycopy[2]);
|
||||
else {
|
||||
if (keycopy[2] == '\0') {
|
||||
jot_error(N_("Key name is too short"));
|
||||
goto free_things;
|
||||
}
|
||||
} else
|
||||
keycopy[2] = toupper((unsigned char)keycopy[2]);
|
||||
}
|
||||
|
||||
/* Allow the codes for Insert and Delete to be rebound, but apart
|
||||
@@ -463,7 +775,7 @@ void parse_binding(char *ptr, bool dobind)
|
||||
if (*funcptr == '"') {
|
||||
newsc = nmalloc(sizeof(keystruct));
|
||||
newsc->func = (functionptrtype)implant;
|
||||
newsc->expansion = mallocstrcpy(NULL, funcptr + 1);
|
||||
newsc->expansion = copy_of(funcptr + 1);
|
||||
#ifndef NANO_TINY
|
||||
newsc->toggle = 0;
|
||||
#endif
|
||||
@@ -501,13 +813,12 @@ void parse_binding(char *ptr, bool dobind)
|
||||
if (newsc->func == do_toggle_void)
|
||||
mask = MMAIN;
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
/* Handle the special case of a key defined as a string. */
|
||||
if (newsc->func == (functionptrtype)implant)
|
||||
mask = MMOST | MHELP;
|
||||
#endif
|
||||
mask = MMOST|MBROWSER|MHELP;
|
||||
|
||||
/* Now limit the given menu to those where the function exists. */
|
||||
menu = menu & (is_universal(newsc->func) ? MMOST : mask);
|
||||
menu = menu & (is_universal(newsc->func) ? (MMOST|MBROWSER) : mask);
|
||||
|
||||
if (!menu) {
|
||||
if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE))
|
||||
@@ -665,23 +976,23 @@ short color_to_short(const char *colorname, bool *bright)
|
||||
} else
|
||||
*bright = FALSE;
|
||||
|
||||
if (strcasecmp(colorname, "green") == 0)
|
||||
if (strcmp(colorname, "green") == 0)
|
||||
return COLOR_GREEN;
|
||||
else if (strcasecmp(colorname, "red") == 0)
|
||||
else if (strcmp(colorname, "red") == 0)
|
||||
return COLOR_RED;
|
||||
else if (strcasecmp(colorname, "blue") == 0)
|
||||
else if (strcmp(colorname, "blue") == 0)
|
||||
return COLOR_BLUE;
|
||||
else if (strcasecmp(colorname, "white") == 0)
|
||||
else if (strcmp(colorname, "white") == 0)
|
||||
return COLOR_WHITE;
|
||||
else if (strcasecmp(colorname, "yellow") == 0)
|
||||
else if (strcmp(colorname, "yellow") == 0)
|
||||
return COLOR_YELLOW;
|
||||
else if (strcasecmp(colorname, "cyan") == 0)
|
||||
else if (strcmp(colorname, "cyan") == 0)
|
||||
return COLOR_CYAN;
|
||||
else if (strcasecmp(colorname, "magenta") == 0)
|
||||
else if (strcmp(colorname, "magenta") == 0)
|
||||
return COLOR_MAGENTA;
|
||||
else if (strcasecmp(colorname, "black") == 0)
|
||||
else if (strcmp(colorname, "black") == 0)
|
||||
return COLOR_BLACK;
|
||||
else if (strcasecmp(colorname, "normal") == 0)
|
||||
else if (strcmp(colorname, "normal") == 0)
|
||||
return USE_THE_DEFAULT;
|
||||
|
||||
jot_error(N_("Color \"%s\" not understood"), colorname);
|
||||
@@ -900,7 +1211,7 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
|
||||
|
||||
/* Copy the regex into a struct, and hook this in at the end. */
|
||||
newthing = (regexlisttype *)nmalloc(sizeof(regexlisttype));
|
||||
newthing->full_regex = mallocstrcpy(NULL, regexstring);
|
||||
newthing->full_regex = copy_of(regexstring);
|
||||
newthing->next = NULL;
|
||||
|
||||
if (lastthing == NULL)
|
||||
@@ -941,20 +1252,22 @@ void pick_up_name(const char *kind, char *ptr, char **storage)
|
||||
/* Handle the four syntax-only commands. */
|
||||
bool parse_syntax_commands(char *keyword, char *ptr)
|
||||
{
|
||||
if (strcasecmp(keyword, "color") == 0)
|
||||
if (strcmp(keyword, "color") == 0)
|
||||
parse_colors(ptr, NANO_REG_EXTENDED);
|
||||
else if (strcasecmp(keyword, "icolor") == 0)
|
||||
else if (strcmp(keyword, "icolor") == 0)
|
||||
parse_colors(ptr, NANO_REG_EXTENDED | REG_ICASE);
|
||||
else if (strcasecmp(keyword, "comment") == 0) {
|
||||
else if (strcmp(keyword, "comment") == 0) {
|
||||
#ifdef ENABLE_COMMENT
|
||||
pick_up_name("comment", ptr, &live_syntax->comment);
|
||||
#endif
|
||||
} else if (strcasecmp(keyword, "tabgives") == 0) {
|
||||
} else if (strcmp(keyword, "tabgives") == 0) {
|
||||
#ifdef ENABLE_COLOR
|
||||
pick_up_name("tabgives", ptr, &live_syntax->tab);
|
||||
#endif
|
||||
} else if (strcasecmp(keyword, "linter") == 0)
|
||||
} else if (strcmp(keyword, "linter") == 0)
|
||||
pick_up_name("linter", ptr, &live_syntax->linter);
|
||||
else if (strcmp(keyword, "formatter") == 0)
|
||||
pick_up_name("formatter", ptr, &live_syntax->formatter);
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
@@ -966,14 +1279,12 @@ bool parse_syntax_commands(char *keyword, char *ptr)
|
||||
* function that we consider 'vital' (such as "Exit"). */
|
||||
static void check_vitals_mapped(void)
|
||||
{
|
||||
funcstruct *f;
|
||||
int v;
|
||||
#define VITALS 3
|
||||
void (*vitals[VITALS])(void) = { do_exit, do_exit, do_cancel };
|
||||
int inmenus[VITALS] = { MMAIN, MHELP, MYESNO };
|
||||
#define VITALS 4
|
||||
void (*vitals[VITALS])(void) = { do_exit, do_exit, do_exit, do_cancel };
|
||||
int inmenus[VITALS] = { MMAIN, MBROWSER, MHELP, MYESNO };
|
||||
|
||||
for (v = 0; v < VITALS; v++) {
|
||||
for (f = allfuncs; f != NULL; f = f->next) {
|
||||
for (int v = 0; v < VITALS; v++) {
|
||||
for (funcstruct *f = allfuncs; f != NULL; f = f->next) {
|
||||
if (f->func == vitals[v] && f->menus & inmenus[v]) {
|
||||
const keystruct *s = first_sc_for(inmenus[v], f->func);
|
||||
if (!s) {
|
||||
@@ -1000,7 +1311,10 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
size_t size = 0;
|
||||
|
||||
while ((len = getline(&buffer, &size, rcstream)) > 0) {
|
||||
char *ptr, *keyword, *option;
|
||||
char *ptr, *keyword, *option, *argument;
|
||||
#ifdef ENABLE_COLOR
|
||||
bool drop_open = FALSE;
|
||||
#endif
|
||||
int set = 0;
|
||||
size_t i;
|
||||
|
||||
@@ -1029,7 +1343,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
/* Handle extending first... */
|
||||
if (!just_syntax && strcasecmp(keyword, "extendsyntax") == 0) {
|
||||
if (!just_syntax && strcmp(keyword, "extendsyntax") == 0) {
|
||||
augmentstruct *newitem, *extra;
|
||||
char *syntaxname = ptr;
|
||||
syntaxtype *sint;
|
||||
@@ -1047,56 +1361,69 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
continue;
|
||||
}
|
||||
|
||||
newitem = nmalloc(sizeof(augmentstruct));;
|
||||
keyword = ptr;
|
||||
argument = copy_of(ptr);
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
/* Store the content of an 'extendsyntax', for later parsing. */
|
||||
newitem->filename = strdup(nanorc);
|
||||
newitem->lineno = lineno;
|
||||
newitem->data = strdup(ptr);
|
||||
newitem->next = NULL;
|
||||
/* File-matching commands need to be processed immediately;
|
||||
* other commands are stored for possible later processing. */
|
||||
if (strcmp(keyword, "header") == 0 || strcmp(keyword, "magic") == 0) {
|
||||
free(argument);
|
||||
live_syntax = sint;
|
||||
opensyntax = TRUE;
|
||||
drop_open = TRUE;
|
||||
} else {
|
||||
newitem = nmalloc(sizeof(augmentstruct));;
|
||||
|
||||
if (sint->augmentations != NULL) {
|
||||
extra = sint->augmentations;
|
||||
while (extra->next != NULL)
|
||||
extra = extra->next;
|
||||
extra->next = newitem;
|
||||
} else
|
||||
sint->augmentations = newitem;
|
||||
newitem->filename = copy_of(nanorc);
|
||||
newitem->lineno = lineno;
|
||||
newitem->data = argument;
|
||||
newitem->next = NULL;
|
||||
|
||||
continue;
|
||||
if (sint->augmentations != NULL) {
|
||||
extra = sint->augmentations;
|
||||
while (extra->next != NULL)
|
||||
extra = extra->next;
|
||||
extra->next = newitem;
|
||||
} else
|
||||
sint->augmentations = newitem;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to parse the keyword. */
|
||||
if (strcasecmp(keyword, "syntax") == 0) {
|
||||
if (strcmp(keyword, "syntax") == 0) {
|
||||
if (intros_only) {
|
||||
check_for_nonempty_syntax();
|
||||
begin_new_syntax(ptr);
|
||||
} else
|
||||
break;
|
||||
} else if (strcasecmp(keyword, "header") == 0) {
|
||||
} else if (strcmp(keyword, "header") == 0) {
|
||||
if (intros_only)
|
||||
grab_and_store("header", ptr, &live_syntax->headers);
|
||||
} else if (strcasecmp(keyword, "magic") == 0) {
|
||||
} else if (strcmp(keyword, "magic") == 0) {
|
||||
#ifdef HAVE_LIBMAGIC
|
||||
if (intros_only)
|
||||
grab_and_store("magic", ptr, &live_syntax->magics);
|
||||
#endif
|
||||
} else if (just_syntax && (strcasecmp(keyword, "set") == 0 ||
|
||||
strcasecmp(keyword, "unset") == 0 ||
|
||||
strcasecmp(keyword, "bind") == 0 ||
|
||||
strcasecmp(keyword, "unbind") == 0 ||
|
||||
strcasecmp(keyword, "include") == 0 ||
|
||||
strcasecmp(keyword, "extendsyntax") == 0)) {
|
||||
} else if (just_syntax && (strcmp(keyword, "set") == 0 ||
|
||||
strcmp(keyword, "unset") == 0 ||
|
||||
strcmp(keyword, "bind") == 0 ||
|
||||
strcmp(keyword, "unbind") == 0 ||
|
||||
strcmp(keyword, "include") == 0 ||
|
||||
strcmp(keyword, "extendsyntax") == 0)) {
|
||||
if (intros_only)
|
||||
jot_error(N_("Command \"%s\" not allowed in included file"),
|
||||
keyword);
|
||||
else
|
||||
break;
|
||||
} else if (intros_only && (strcasecmp(keyword, "color") == 0 ||
|
||||
strcasecmp(keyword, "icolor") == 0 ||
|
||||
strcasecmp(keyword, "comment") == 0 ||
|
||||
strcasecmp(keyword, "tabgives") == 0 ||
|
||||
strcasecmp(keyword, "linter") == 0)) {
|
||||
} else if (intros_only && (strcmp(keyword, "color") == 0 ||
|
||||
strcmp(keyword, "icolor") == 0 ||
|
||||
strcmp(keyword, "comment") == 0 ||
|
||||
strcmp(keyword, "tabgives") == 0 ||
|
||||
strcmp(keyword, "linter") == 0 ||
|
||||
strcmp(keyword, "formatter") == 0)) {
|
||||
if (!opensyntax)
|
||||
jot_error(N_("A '%s' command requires a preceding "
|
||||
"'syntax' command"), keyword);
|
||||
@@ -1105,21 +1432,25 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
continue;
|
||||
} else if (parse_syntax_commands(keyword, ptr))
|
||||
;
|
||||
else if (strcasecmp(keyword, "include") == 0)
|
||||
else if (strcmp(keyword, "include") == 0)
|
||||
parse_includes(ptr);
|
||||
else
|
||||
#endif /* ENABLE_COLOR */
|
||||
if (strcasecmp(keyword, "set") == 0)
|
||||
if (strcmp(keyword, "set") == 0)
|
||||
set = 1;
|
||||
else if (strcasecmp(keyword, "unset") == 0)
|
||||
else if (strcmp(keyword, "unset") == 0)
|
||||
set = -1;
|
||||
else if (strcasecmp(keyword, "bind") == 0)
|
||||
else if (strcmp(keyword, "bind") == 0)
|
||||
parse_binding(ptr, TRUE);
|
||||
else if (strcasecmp(keyword, "unbind") == 0)
|
||||
else if (strcmp(keyword, "unbind") == 0)
|
||||
parse_binding(ptr, FALSE);
|
||||
else if (intros_only)
|
||||
jot_error(N_("Command \"%s\" not understood"), keyword);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (drop_open)
|
||||
opensyntax = FALSE;
|
||||
#endif
|
||||
if (set == 0)
|
||||
continue;
|
||||
|
||||
@@ -1135,7 +1466,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
|
||||
/* Find the just parsed option name among the existing names. */
|
||||
for (i = 0; rcopts[i].name != NULL; i++) {
|
||||
if (strcasecmp(option, rcopts[i].name) == 0)
|
||||
if (strcmp(option, rcopts[i].name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1155,125 +1486,125 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
|
||||
/* An option that takes an argument cannot be unset. */
|
||||
if (set == -1) {
|
||||
jot_error(N_("Cannot unset option \"%s\""), rcopts[i].name);
|
||||
jot_error(N_("Cannot unset option \"%s\""), option);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
jot_error(N_("Option \"%s\" requires an argument"), rcopts[i].name);
|
||||
jot_error(N_("Option \"%s\" requires an argument"), option);
|
||||
continue;
|
||||
}
|
||||
|
||||
option = ptr;
|
||||
if (*option == '"')
|
||||
option++;
|
||||
argument = ptr;
|
||||
if (*argument == '"')
|
||||
argument++;
|
||||
ptr = parse_argument(ptr);
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
/* When in a UTF-8 locale, ignore arguments with invalid sequences. */
|
||||
if (using_utf8() && mbstowcs(NULL, option, 0) == (size_t)-1) {
|
||||
if (using_utf8() && mbstowcs(NULL, argument, 0) == (size_t)-1) {
|
||||
jot_error(N_("Argument is not a valid multibyte string"));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
option = mallocstrcpy(NULL, option);
|
||||
argument = copy_of(argument);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (strcasecmp(rcopts[i].name, "titlecolor") == 0)
|
||||
color_combo[TITLE_BAR] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "numbercolor") == 0)
|
||||
color_combo[LINE_NUMBER] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "stripecolor") == 0)
|
||||
color_combo[GUIDE_STRIPE] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "selectedcolor") == 0)
|
||||
color_combo[SELECTED_TEXT] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "statuscolor") == 0)
|
||||
color_combo[STATUS_BAR] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "errorcolor") == 0)
|
||||
color_combo[ERROR_MESSAGE] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "keycolor") == 0)
|
||||
color_combo[KEY_COMBO] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "functioncolor") == 0)
|
||||
color_combo[FUNCTION_TAG] = parse_interface_color(option);
|
||||
if (strcmp(option, "titlecolor") == 0)
|
||||
color_combo[TITLE_BAR] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "numbercolor") == 0)
|
||||
color_combo[LINE_NUMBER] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "stripecolor") == 0)
|
||||
color_combo[GUIDE_STRIPE] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "selectedcolor") == 0)
|
||||
color_combo[SELECTED_TEXT] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "statuscolor") == 0)
|
||||
color_combo[STATUS_BAR] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "errorcolor") == 0)
|
||||
color_combo[ERROR_MESSAGE] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "keycolor") == 0)
|
||||
color_combo[KEY_COMBO] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "functioncolor") == 0)
|
||||
color_combo[FUNCTION_TAG] = parse_interface_color(argument);
|
||||
else
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
if (strcasecmp(rcopts[i].name, "operatingdir") == 0)
|
||||
operating_dir = option;
|
||||
if (strcmp(option, "operatingdir") == 0)
|
||||
operating_dir = argument;
|
||||
else
|
||||
#endif
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
if (strcasecmp(rcopts[i].name, "fill") == 0) {
|
||||
if (!parse_num(option, &fill)) {
|
||||
jot_error(N_("Requested fill size \"%s\" is invalid"), option);
|
||||
if (strcmp(option, "fill") == 0) {
|
||||
if (!parse_num(argument, &fill)) {
|
||||
jot_error(N_("Requested fill size \"%s\" is invalid"), argument);
|
||||
fill = -COLUMNS_FROM_EOL;
|
||||
}
|
||||
free(option);
|
||||
free(argument);
|
||||
} else
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (strcasecmp(rcopts[i].name, "guidestripe") == 0) {
|
||||
if (!parse_num(option, &stripe_column) || stripe_column <= 0) {
|
||||
jot_error(N_("Guide column \"%s\" is invalid"), option);
|
||||
if (strcmp(option, "guidestripe") == 0) {
|
||||
if (!parse_num(argument, &stripe_column) || stripe_column <= 0) {
|
||||
jot_error(N_("Guide column \"%s\" is invalid"), argument);
|
||||
stripe_column = 0;
|
||||
}
|
||||
free(option);
|
||||
} else if (strcasecmp(rcopts[i].name, "matchbrackets") == 0) {
|
||||
if (has_blank_char(option)) {
|
||||
free(argument);
|
||||
} else if (strcmp(option, "matchbrackets") == 0) {
|
||||
if (has_blank_char(argument)) {
|
||||
jot_error(N_("Non-blank characters required"));
|
||||
free(option);
|
||||
} else if (mbstrlen(option) % 2 != 0) {
|
||||
free(argument);
|
||||
} else if (mbstrlen(argument) % 2 != 0) {
|
||||
jot_error(N_("Even number of characters required"));
|
||||
free(option);
|
||||
free(argument);
|
||||
} else
|
||||
matchbrackets = option;
|
||||
} else if (strcasecmp(rcopts[i].name, "whitespace") == 0) {
|
||||
if (mbstrlen(option) != 2 || breadth(option) != 2) {
|
||||
matchbrackets = argument;
|
||||
} else if (strcmp(option, "whitespace") == 0) {
|
||||
if (mbstrlen(argument) != 2 || breadth(argument) != 2) {
|
||||
jot_error(N_("Two single-column characters required"));
|
||||
free(option);
|
||||
free(argument);
|
||||
} else {
|
||||
whitespace = option;
|
||||
whitespace = argument;
|
||||
whitelen[0] = char_length(whitespace);
|
||||
whitelen[1] = char_length(whitespace + whitelen[0]);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
if (strcasecmp(rcopts[i].name, "punct") == 0) {
|
||||
if (has_blank_char(option)) {
|
||||
if (strcmp(option, "punct") == 0) {
|
||||
if (has_blank_char(argument)) {
|
||||
jot_error(N_("Non-blank characters required"));
|
||||
free(option);
|
||||
free(argument);
|
||||
} else
|
||||
punct = option;
|
||||
} else if (strcasecmp(rcopts[i].name, "brackets") == 0) {
|
||||
if (has_blank_char(option)) {
|
||||
punct = argument;
|
||||
} else if (strcmp(option, "brackets") == 0) {
|
||||
if (has_blank_char(argument)) {
|
||||
jot_error(N_("Non-blank characters required"));
|
||||
free(option);
|
||||
free(argument);
|
||||
} else
|
||||
brackets = option;
|
||||
} else if (strcasecmp(rcopts[i].name, "quotestr") == 0)
|
||||
quotestr = option;
|
||||
brackets = argument;
|
||||
} else if (strcmp(option, "quotestr") == 0)
|
||||
quotestr = argument;
|
||||
else
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (strcasecmp(rcopts[i].name, "backupdir") == 0)
|
||||
backup_dir = option;
|
||||
if (strcmp(option, "backupdir") == 0)
|
||||
backup_dir = argument;
|
||||
else
|
||||
if (strcasecmp(rcopts[i].name, "wordchars") == 0)
|
||||
word_chars = option;
|
||||
if (strcmp(option, "wordchars") == 0)
|
||||
word_chars = argument;
|
||||
else
|
||||
#endif
|
||||
#ifdef ENABLE_SPELLER
|
||||
if (strcasecmp(rcopts[i].name, "speller") == 0)
|
||||
alt_speller = option;
|
||||
if (strcmp(option, "speller") == 0)
|
||||
alt_speller = argument;
|
||||
else
|
||||
#endif
|
||||
if (strcasecmp(rcopts[i].name, "tabsize") == 0) {
|
||||
if (!parse_num(option, &tabsize) || tabsize <= 0) {
|
||||
jot_error(N_("Requested tab size \"%s\" is invalid"), option);
|
||||
if (strcmp(option, "tabsize") == 0) {
|
||||
if (!parse_num(argument, &tabsize) || tabsize <= 0) {
|
||||
jot_error(N_("Requested tab size \"%s\" is invalid"), argument);
|
||||
tabsize = -1;
|
||||
}
|
||||
free(option);
|
||||
free(argument);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1336,6 +1667,7 @@ void do_rcfiles(void)
|
||||
check_vitals_mapped();
|
||||
|
||||
free(nanorc);
|
||||
nanorc = NULL;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
10
src/search.c
10
src/search.c
@@ -76,7 +76,7 @@ void search_init(bool replacing, bool keep_the_answer)
|
||||
|
||||
/* When starting a new search, clear the current answer. */
|
||||
if (!keep_the_answer)
|
||||
answer = mallocstrcpy(answer, NULL);
|
||||
answer = mallocstrcpy(answer, "");
|
||||
|
||||
/* If something was searched for earlier, include it in the prompt. */
|
||||
if (*last_search != '\0') {
|
||||
@@ -88,7 +88,7 @@ void search_init(bool replacing, bool keep_the_answer)
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
thedefault = mallocstrcpy(NULL, "");
|
||||
thedefault = copy_of("");
|
||||
|
||||
while (TRUE) {
|
||||
functionptrtype func;
|
||||
@@ -598,7 +598,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
size_t length_change;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(REPLACE);
|
||||
add_undo(REPLACE, NULL);
|
||||
#endif
|
||||
copy = replace_line(needle);
|
||||
|
||||
@@ -699,7 +699,7 @@ void ask_for_replacement(void)
|
||||
linestruct *edittop_save, *begin;
|
||||
size_t firstcolumn_save, begin_x;
|
||||
ssize_t numreplaced;
|
||||
int response = do_prompt(FALSE, FALSE, MREPLACEWITH, NULL,
|
||||
int response = do_prompt(FALSE, FALSE, MREPLACEWITH, "",
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
&replace_history, edit_refresh, _("Replace with"));
|
||||
|
||||
@@ -758,7 +758,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
if (interactive) {
|
||||
/* Ask for the line and column. */
|
||||
int response = do_prompt(FALSE, FALSE, MGOTOLINE,
|
||||
use_answer ? answer : NULL, NULL, edit_refresh,
|
||||
use_answer ? answer : "", NULL, edit_refresh,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
_("Enter line number, column number"));
|
||||
|
||||
|
||||
551
src/text.c
551
src/text.c
File diff suppressed because it is too large
Load Diff
71
src/utils.c
71
src/utils.c
@@ -49,7 +49,7 @@ void get_homedir(void)
|
||||
/* Only set homedir if some home directory could be determined,
|
||||
* otherwise keep homedir NULL. */
|
||||
if (homenv != NULL && *homenv != '\0')
|
||||
homedir = mallocstrcpy(NULL, homenv);
|
||||
homedir = copy_of(homenv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ bool parse_line_column(const char *str, ssize_t *line, ssize_t *column)
|
||||
if (comma == str)
|
||||
return retval;
|
||||
|
||||
firstpart = mallocstrcpy(NULL, str);
|
||||
firstpart = copy_of(str);
|
||||
firstpart[comma - str] = '\0';
|
||||
|
||||
retval = parse_num(firstpart, line) && retval;
|
||||
@@ -159,23 +159,24 @@ bool parse_line_column(const char *str, ssize_t *line, ssize_t *column)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so encode its nulls as newlines. */
|
||||
void unsunder(char *str, size_t true_len)
|
||||
/* In the given string, recode each embedded NUL as a newline. */
|
||||
void unsunder(char *string, size_t length)
|
||||
{
|
||||
for (; true_len > 0; true_len--, str++) {
|
||||
if (*str == '\0')
|
||||
*str = '\n';
|
||||
while (length > 0) {
|
||||
if (*string == '\0')
|
||||
*string = '\n';
|
||||
length--;
|
||||
string++;
|
||||
}
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so decode its newlines as nulls. */
|
||||
void sunder(char *str)
|
||||
/* In the given string, recode each embedded newline as a NUL. */
|
||||
void sunder(char *string)
|
||||
{
|
||||
for (; *str != '\0'; str++) {
|
||||
if (*str == '\n')
|
||||
*str = '\0';
|
||||
while (*string != '\0') {
|
||||
if (*string == '\n')
|
||||
*string = '\0';
|
||||
string++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,8 +203,8 @@ bool is_separate_word(size_t position, size_t length, const char *buf)
|
||||
size_t word_end = position + length;
|
||||
|
||||
/* Get the characters before and after the word, if any. */
|
||||
parse_mbchar(buf + step_left(buf, position), before, NULL);
|
||||
parse_mbchar(buf + word_end, after, NULL);
|
||||
collect_char(buf + step_left(buf, position), before);
|
||||
collect_char(buf + word_end, after);
|
||||
|
||||
/* If the word starts at the beginning of the line OR the character before
|
||||
* the word isn't a letter, and if the word ends at the end of the line OR
|
||||
@@ -311,24 +312,32 @@ void *nrealloc(void *ptr, size_t howmuch)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Allocate and copy the first n characters of the given src string, after
|
||||
* freeing the destination. Usage: "dest = mallocstrncpy(dest, src, n);". */
|
||||
char *mallocstrncpy(char *dest, const char *src, size_t n)
|
||||
/* Return an appropriately reallocated dest string holding a copy of src.
|
||||
* Usage: "dest = mallocstrcpy(dest, src);". */
|
||||
char *mallocstrcpy(char *dest, const char *src)
|
||||
{
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
size_t count = strlen(src) + 1;
|
||||
|
||||
dest = charealloc(dest, n);
|
||||
strncpy(dest, src, n);
|
||||
dest = charealloc(dest, count);
|
||||
strncpy(dest, src, count);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* Free the dest string and return a malloc'ed copy of src. Should be used as:
|
||||
* "dest = mallocstrcpy(dest, src);". */
|
||||
char *mallocstrcpy(char *dest, const char *src)
|
||||
/* Return an allocated copy of the first count characters of the given string. */
|
||||
char *measured_copy(const char *string, size_t count)
|
||||
{
|
||||
return mallocstrncpy(dest, src, (src == NULL) ? 1 : strlen(src) + 1);
|
||||
char *thecopy = charalloc(count);
|
||||
|
||||
strncpy(thecopy, string, count);
|
||||
|
||||
return thecopy;
|
||||
}
|
||||
|
||||
/* Return an allocated copy of the given string. */
|
||||
char *copy_of(const char *string)
|
||||
{
|
||||
return measured_copy(string, strlen(string) + 1);
|
||||
}
|
||||
|
||||
/* Free the string at dest and return the string at src. */
|
||||
@@ -370,7 +379,7 @@ size_t actual_x(const char *text, size_t column)
|
||||
/* The current accumulated span, in columns. */
|
||||
|
||||
while (*text != '\0') {
|
||||
int charlen = parse_mbchar(text, NULL, &width);
|
||||
int charlen = advance_over(text, &width);
|
||||
|
||||
if (width > column)
|
||||
break;
|
||||
@@ -391,7 +400,7 @@ size_t wideness(const char *text, size_t maxlen)
|
||||
return 0;
|
||||
|
||||
while (*text != '\0') {
|
||||
size_t charlen = parse_mbchar(text, NULL, &width);
|
||||
size_t charlen = advance_over(text, &width);
|
||||
|
||||
if (maxlen <= charlen)
|
||||
break;
|
||||
@@ -409,7 +418,7 @@ size_t breadth(const char *text)
|
||||
size_t span = 0;
|
||||
|
||||
while (*text != '\0')
|
||||
text += parse_mbchar(text, NULL, &span);
|
||||
text += advance_over(text, &span);
|
||||
|
||||
return span;
|
||||
}
|
||||
@@ -418,7 +427,7 @@ size_t breadth(const char *text)
|
||||
void new_magicline(void)
|
||||
{
|
||||
openfile->filebot->next = make_new_node(openfile->filebot);
|
||||
openfile->filebot->next->data = mallocstrcpy(NULL, "");
|
||||
openfile->filebot->next->data = copy_of("");
|
||||
openfile->filebot = openfile->filebot->next;
|
||||
openfile->totsize++;
|
||||
}
|
||||
|
||||
98
src/winio.c
98
src/winio.c
@@ -658,7 +658,8 @@ int parse_kbinput(WINDOW *win)
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When <Tab> is pressed while the mark is on, do an indent. */
|
||||
if (retval == TAB_CODE && openfile->mark && currmenu == MMAIN)
|
||||
if (retval == TAB_CODE && openfile->mark && currmenu == MMAIN &&
|
||||
openfile->mark != openfile->current)
|
||||
return INDENT_KEY;
|
||||
#endif
|
||||
|
||||
@@ -2094,8 +2095,8 @@ void titlebar(const char *path)
|
||||
state = _("View");
|
||||
else if (ISSET(RESTRICTED))
|
||||
state = _("Restricted");
|
||||
|
||||
pluglen = breadth(_("Modified")) + 1;
|
||||
else
|
||||
pluglen = breadth(_("Modified")) + 1;
|
||||
}
|
||||
|
||||
/* Determine the widths of the four elements, including their padding. */
|
||||
@@ -2105,10 +2106,8 @@ void titlebar(const char *path)
|
||||
prefixlen++;
|
||||
pathlen = breadth(path);
|
||||
statelen = breadth(state) + 2;
|
||||
if (statelen > 2) {
|
||||
if (statelen > 2)
|
||||
pathlen++;
|
||||
pluglen = 0;
|
||||
}
|
||||
|
||||
/* Only print the version message when there is room for it. */
|
||||
if (verlen + prefixlen + pathlen + pluglen + statelen <= COLS)
|
||||
@@ -2164,30 +2163,15 @@ void titlebar(const char *path)
|
||||
wrefresh(topwin);
|
||||
}
|
||||
|
||||
/* Display a normal message on the statusbar, quietly. */
|
||||
void statusbar(const char *msg)
|
||||
{
|
||||
statusline(HUSH, msg);
|
||||
}
|
||||
|
||||
/* Warn the user on the statusbar and pause for a moment, so that the
|
||||
* message can be noticed and read. */
|
||||
void warn_and_shortly_pause(const char *msg)
|
||||
{
|
||||
statusline(ALERT, msg);
|
||||
napms(1800);
|
||||
}
|
||||
|
||||
/* Display a message on the statusbar, and set suppress_cursorpos to
|
||||
* TRUE, so that the message won't be immediately overwritten if
|
||||
* constant cursor position display is on. */
|
||||
void statusline(message_type importance, const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
static int alerts = 0;
|
||||
int colorpair;
|
||||
char *compound, *message;
|
||||
size_t start_col;
|
||||
static size_t start_col = 0;
|
||||
bool bracketed;
|
||||
#ifndef NANO_TINY
|
||||
bool old_whitespace = ISSET(WHITESPACE_DISPLAY);
|
||||
@@ -2210,20 +2194,23 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the ALERT status has been reset, reset the counter. */
|
||||
if (lastmessage == HUSH)
|
||||
alerts = 0;
|
||||
|
||||
/* Shortly pause after each of the first three alert messages,
|
||||
* to give the user time to read them. */
|
||||
if (lastmessage == ALERT && alerts < 4 && !ISSET(NO_PAUSES))
|
||||
napms(1200);
|
||||
/* If there are multiple alert messages, add trailing dots to the first. */
|
||||
if (lastmessage == ALERT) {
|
||||
if (start_col > 4) {
|
||||
wmove(bottomwin, 0, COLS + 2 - start_col);
|
||||
wattron(bottomwin, interface_color_pair[ERROR_MESSAGE]);
|
||||
waddstr(bottomwin, "...");
|
||||
wattroff(bottomwin, interface_color_pair[ERROR_MESSAGE]);
|
||||
wnoutrefresh(bottomwin);
|
||||
start_col = 0;
|
||||
napms(100);
|
||||
beep();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (importance == ALERT) {
|
||||
if (++alerts > 3 && !ISSET(NO_PAUSES))
|
||||
msg = _("Further warnings were suppressed");
|
||||
else if (alerts < 4)
|
||||
beep();
|
||||
beep();
|
||||
colorpair = interface_color_pair[ERROR_MESSAGE];
|
||||
} else if (importance == NOTICE)
|
||||
colorpair = interface_color_pair[SELECTED_TEXT];
|
||||
@@ -2277,6 +2264,20 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
statusblank = 26;
|
||||
}
|
||||
|
||||
/* Display a normal message on the statusbar, quietly. */
|
||||
void statusbar(const char *msg)
|
||||
{
|
||||
statusline(HUSH, msg);
|
||||
}
|
||||
|
||||
/* Warn the user on the statusbar and pause for a moment, so that the
|
||||
* message can be noticed and read. */
|
||||
void warn_and_shortly_pause(const char *msg)
|
||||
{
|
||||
statusline(ALERT, msg);
|
||||
napms(1800);
|
||||
}
|
||||
|
||||
/* Display the shortcut list corresponding to menu on the last two rows
|
||||
* of the bottom portion of the window. */
|
||||
void bottombars(int menu)
|
||||
@@ -2403,11 +2404,12 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col)
|
||||
wattron(edit, interface_color_pair[LINE_NUMBER]);
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP) && from_col != 0)
|
||||
mvwprintw(edit, row, 0, "%*s", margin, " ");
|
||||
mvwprintw(edit, row, 0, "%*s", margin - 1, " ");
|
||||
else
|
||||
#endif
|
||||
mvwprintw(edit, row, 0, "%*zd ", margin - 1, line->lineno);
|
||||
mvwprintw(edit, row, 0, "%*zd", margin - 1, line->lineno);
|
||||
wattroff(edit, interface_color_pair[LINE_NUMBER]);
|
||||
wprintw(edit, " ");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2684,7 +2686,7 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col)
|
||||
size_t charlen = 1;
|
||||
|
||||
if (*(converted + target_x) != '\0') {
|
||||
charlen = parse_mbchar(converted + target_x, striped_char, NULL);
|
||||
charlen = collect_char(converted + target_x, striped_char);
|
||||
target_column = wideness(converted, target_x);
|
||||
} else if (target_column + 1 == editwincols) {
|
||||
/* Defeat a VTE bug -- see https://sv.gnu.org/bugs/?55896. */
|
||||
@@ -3043,7 +3045,7 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
||||
|
||||
/* First find the place in text where the current chunk starts. */
|
||||
while (*text != '\0' && column < leftedge)
|
||||
text += parse_mbchar(text, NULL, &column);
|
||||
text += advance_over(text, &column);
|
||||
|
||||
/* Now find the place in text where this chunk should end. */
|
||||
while (*text != '\0' && column <= goal_column) {
|
||||
@@ -3054,7 +3056,7 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
||||
}
|
||||
|
||||
breaking_col = (*text == '\t' ? goal_column : column);
|
||||
text += parse_mbchar(text, NULL, &column);
|
||||
text += advance_over(text, &column);
|
||||
}
|
||||
|
||||
/* If we didn't overshoot the limit, we've found a breaking point;
|
||||
@@ -3067,7 +3069,7 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
||||
/* If we're softwrapping at blanks and we found at least one blank, break
|
||||
* after that blank -- if it doesn't overshoot the screen's edge. */
|
||||
if (farthest_blank != NULL) {
|
||||
parse_mbchar(farthest_blank, NULL, &last_blank_col);
|
||||
advance_over(farthest_blank, &last_blank_col);
|
||||
|
||||
if (last_blank_col <= goal_column)
|
||||
return last_blank_col;
|
||||
@@ -3118,14 +3120,14 @@ size_t chunk_for(size_t column, linestruct *line)
|
||||
* column is on. */
|
||||
size_t leftedge_for(size_t column, linestruct *line)
|
||||
{
|
||||
size_t leftedge;
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
size_t leftedge;
|
||||
|
||||
if (!ISSET(SOFTWRAP))
|
||||
get_chunk_and_edge(column, line, &leftedge);
|
||||
|
||||
return leftedge;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
get_chunk_and_edge(column, line, &leftedge);
|
||||
|
||||
return leftedge;
|
||||
}
|
||||
|
||||
/* Return the row of the last softwrapped chunk of the given line, relative to
|
||||
@@ -3431,7 +3433,7 @@ void spotlight(size_t from_col, size_t to_col)
|
||||
|
||||
/* This is so we can show zero-length matches. */
|
||||
if (to_col == from_col) {
|
||||
word = mallocstrcpy(NULL, " ");
|
||||
word = copy_of(" ");
|
||||
to_col++;
|
||||
} else
|
||||
word = display_string(openfile->current->data, from_col,
|
||||
@@ -3474,7 +3476,7 @@ void spotlight_softwrapped(size_t from_col, size_t to_col)
|
||||
|
||||
/* This is so we can show zero-length matches. */
|
||||
if (break_col == from_col) {
|
||||
word = mallocstrcpy(NULL, " ");
|
||||
word = copy_of(" ");
|
||||
break_col++;
|
||||
} else
|
||||
word = display_string(openfile->current->data, from_col,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
## Here is an example for C/C++.
|
||||
|
||||
syntax c "\.([ch](pp|xx)?|C|cc|c\+\+|cu|H|hh|ii?)$"
|
||||
header "-\*-.*\<C(\+\+)?((;|\s).*)?-\*-"
|
||||
magic "^(C|C\+\+) (source|program)"
|
||||
comment "//"
|
||||
|
||||
|
||||
@@ -17,4 +17,4 @@ color brightred "(GNU )?[Nn]ano [1-4]\.[0-9][-.[:alnum:]]*\>"
|
||||
color magenta "<[[:alnum:].%_+-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}>"
|
||||
|
||||
# Bracketed captions in certain config files.
|
||||
color brightgreen "^\[.*\]$"
|
||||
color brightgreen "^\[[^][]+\]$"
|
||||
|
||||
@@ -17,7 +17,7 @@ color green "-(eq|ne|gt|lt|ge|le)\>"
|
||||
## Variables... official portage ones in red, all others in bright red:
|
||||
color brightred "\$[-0-9@*#?$!]" "\$[[:alpha:]_][[:alnum:]_]*"
|
||||
color brightred "\$\{[#!]?([-@*#?$!]|[0-9]+|[[:alpha:]_][[:alnum:]_]*)(\[([[:digit:]]|@)+\])?(([#%/]|:?[-=?+])[^}]*\}|\[|\})"
|
||||
color red "\<(EAPI|ARCH|HOMEPAGE|DESCRIPTION|IUSE|SRC_URI|LICENSE|SLOT|KEYWORDS|[HPR]?DEPEND|PROVIDE|PROPERTIES|REQUIRED_USE|RESTRICT|USERLAND)\>"
|
||||
color red "\<(EAPI|ARCH|HOMEPAGE|DESCRIPTION|IUSE|SRC_URI|LICENSE|SLOT|KEYWORDS|[BHPR]?DEPEND|PROVIDE|PROPERTIES|REQUIRED_USE|RESTRICT|USERLAND)\>"
|
||||
color red "\<(S|E?D|T|PV|PF|P|PN|PR|PVR|A|CATEGORY|DISTDIR|FILESDIR|EPREFIX|E?ROOT|WORKDIR)\>"
|
||||
color red "\<(AS|C(PP|XX)?|LD)FLAGS\>" "\<C(HOST|TARGET|BUILD)\>" "\<(MERGE_TYPE|REPLACING_VERSIONS|REPLACED_BY_VERSION)\>"
|
||||
color red "\<EBUILD_PHASE(_FUNC)?\>"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
syntax go "\.go$"
|
||||
comment "//"
|
||||
|
||||
formatter gofmt -w
|
||||
|
||||
# Types.
|
||||
color green "\<(bool|u?int(8|16|32|64)?|float(32|64)|complex(64|128)|byte|rune|uintptr|string|error)\>"
|
||||
color green "\<((<-[[:space:]]*)chan|chan[[:space:]]*<-|const|func|interface|map|struct|type|var)\>"
|
||||
|
||||
@@ -4,6 +4,8 @@ syntax html "\.html?$"
|
||||
magic "HTML document"
|
||||
comment "<!--|-->"
|
||||
|
||||
formatter tidy -m -q
|
||||
|
||||
# Tags:
|
||||
color cyan "<[[:alpha:]/!?][^>]*>"
|
||||
# Bold, italic, and underlined:
|
||||
@@ -11,18 +13,19 @@ color brightmagenta "</?[biu]>"
|
||||
|
||||
# Named character references:
|
||||
color red "&[^;[:space:]]*;"
|
||||
|
||||
# Attributes:
|
||||
color red "\<(abbr|accept(-charset)?|accesskey|action|alink|align|alt|archive|axis|background|bgcolor|border)="
|
||||
color red "\<(cell(padding|spacing)|char(off|set)?|checked|cite|class(id)?|compact|code(base|tag)?|cols(pan)?)="
|
||||
color red "\<(content(editable)?|contextmenu|coords|data|datetime|declare|defer|dir|disabled|enctype)="
|
||||
color red "\<(for|frame(border)?|headers|height|hidden|href(lang)?|hspace|http-equiv|id|ismap)="
|
||||
color red "\<(label|lang|link|longdesc|margin(height|width)|maxlength|media|method|multiple)="
|
||||
color red "\<(name|nohref|noresize|noshade|object|onclick|onfocus|onload|onmouseover|profile|readonly|rel|rev)="
|
||||
color red "\<(rows(pan)?|rules|scheme|scope|scrolling|selected|shape|size|span|src|standby|start|style|summary)="
|
||||
color red "\<(tabindex|target|text|title|type|usemap|valign|value(type)?|vlink|vspace|width|xmlns|xml:space)="
|
||||
|
||||
# Strings:
|
||||
color green ""(\\.|[^"])*""
|
||||
|
||||
# Attributes:
|
||||
color red "(abbr|accept(-charset)?|accesskey|action|alink|align|alt|archive|axis|background|bgcolor|border)="
|
||||
color red "(cell(padding|spacing)|char(off|set)?|checked|cite|class(id)?|compact|code(base|tag)?|cols(pan)?)="
|
||||
color red "(content(editable)?|contextmenu|coords|data|datetime|declare|defer|dir|disabled|enctype)="
|
||||
color red "(for|frame(border)?|headers|height|hidden|href(lang)?|hspace|http-equiv|id|ismap)="
|
||||
color red "(label|lang|link|longdesc|margin(height|width)|maxlength|media|method|multiple)="
|
||||
color red "(name|nohref|noresize|noshade|object|onclick|onfocus|onload|onmouseover|profile|readonly|rel|rev)="
|
||||
color red "(rows(pan)?|rules|scheme|scope|scrolling|selected|shape|size|span|src|standby|start|style|summary)="
|
||||
color red "(tabindex|target|text|title|type|usemap|valign|value(type)?|vlink|vspace|width|xmlns|xml:space)="
|
||||
|
||||
# Comments:
|
||||
color yellow start="<!--" end="-->"
|
||||
|
||||
@@ -12,7 +12,9 @@ color brightyellow "\<(await|export|import|throw|try|catch|finally|new|delete)\>
|
||||
color magenta "\<(break|continue|return|yield)\>"
|
||||
|
||||
# Octal/decimal and hexadecimal numbers.
|
||||
color cyan "\<[0-9]+\>" "\<0x[0-9A-Fa-f]+\>"
|
||||
color cyan "\<([0-9]+|0x[0-9A-Fa-f]+)\>"
|
||||
# Special values.
|
||||
color cyan "\<(true|false|null|undefined)\>"
|
||||
|
||||
# Strings.
|
||||
color brightmagenta ""(\\.|[^"])*"" "'(\\.|[^'])*'" "`(\\.|[^`])*`"
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
syntax lua "\.lua$"
|
||||
magic "Lua script"
|
||||
linter "luacheck --no-color"
|
||||
comment "--"
|
||||
|
||||
linter luacheck --no-color
|
||||
|
||||
color brightwhite "\[\[.*\]\]"
|
||||
|
||||
# Operators
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
syntax nanohelp
|
||||
|
||||
# Key combos:
|
||||
color cyan "\^[]4-8A-Z^\_◀▶▲▼]" "[◀▶▲▼]" "\<M-." "\<F1?[0-9]"
|
||||
color cyan "\^[]/4-8A-Z\^_◀▶▲▼]" "[◀▶▲▼]" "\<M-." "\<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:
|
||||
|
||||
@@ -3,26 +3,26 @@
|
||||
syntax nanorc "\.?nanorc$"
|
||||
comment "#"
|
||||
|
||||
# Possible errors and parameters
|
||||
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|tabgives|i?color|extendsyntax).*"
|
||||
# Everything that does not get recolored is invalid
|
||||
color brightred ".*"
|
||||
|
||||
# Keywords
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|breaklonglines|casesensitive|constantshow|cutfromcursor|emptyline|finalnewline|historylog|jumpyscrolling|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabstospaces|tempfile|trimblanks|unix|view|wordbounds|zap)\>"
|
||||
icolor 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))?\>"
|
||||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|stripecolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(fill[[:space:]]+-?[[:digit:]]+|(guidestripe|tabsize)[[:space:]]+[1-9][0-9]*)\>"
|
||||
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]@\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|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:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([[:alpha:]]|[]@\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|linter|tabgives)[[:space:]]+.*"
|
||||
icolor brightgreen "^[[:space:]]*(syntax|linter)[[:space:]]+[^[:blank:]]+"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|tabgives|extendsyntax)\>"
|
||||
color brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|breaklonglines|casesensitive|constantshow|cutfromcursor|emptyline|finalnewline|historylog|jumpyscrolling|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabstospaces|tempfile|trimblanks|unix|view|wordbounds|zap)\>"
|
||||
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:]]*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)\>"
|
||||
|
||||
# Strings
|
||||
color brightmagenta "([[:space:]]|(start|end)=)".+"([[:space:]]|$)"
|
||||
|
||||
# Colors
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
icolor magenta "^[[:space:]]*i?color\>" "\<(start|end)="
|
||||
color yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
color magenta "^[[:space:]]*i?color\>" "\<(start|end)="
|
||||
|
||||
# Comments
|
||||
color brightblue "(^|[[:space:]]+)#.*"
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
syntax python "\.py$"
|
||||
header "^#!.*python"
|
||||
magic "Python script"
|
||||
linter pyflakes
|
||||
comment "#"
|
||||
|
||||
linter pyflakes
|
||||
|
||||
# Function definitions.
|
||||
color brightblue "def [0-9A-Za-z_]+"
|
||||
# Keywords.
|
||||
|
||||
@@ -6,11 +6,11 @@ magic "Ruby script"
|
||||
linter ruby -w -c
|
||||
comment "#"
|
||||
|
||||
# Constants.
|
||||
color brightblue "\<[A-Z]+[0-9A-Z_a-z]*|(\$|@|@@)[0-9A-Z_a-z]+"
|
||||
# Reserved words.
|
||||
color yellow "\<(BEGIN|END|alias|and|begin|break|case|class|def|defined\?|do|else|elsif|end|ensure|false|for|if|in|module)\>"
|
||||
color yellow "\<(next|nil|not|or|redo|rescue|retry|return|self|super|then|true|undef|unless|until|when|while|yield)\>"
|
||||
# Constants.
|
||||
color brightblue "(\$|@|@@)?\<[A-Z]+[0-9A-Z_a-z]*"
|
||||
# Ruby "symbols".
|
||||
color magenta "([ ]|^):[0-9A-Za-z_]+\>"
|
||||
# Some unique things we want to stand out.
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
## Here is an example for Bourne shell scripts.
|
||||
|
||||
syntax sh "(\.sh|\.(a|ba|c|da|k|mk|pdk|tc|z)(sh|shrc|sh_profile)|/(etc/|\.)profile)$"
|
||||
syntax sh "(\.sh|(\.|/)(a|ba|c|da|k|mk|pdk|tc|z)sh(rc|_profile)?|/(etc/|\.)profile)$"
|
||||
header "^#!.*/(((a|ba|c|da|k|mk|pdk|tc|z)?sh)|(busybox|env) +sh|openrc-run|runscript)"
|
||||
magic "(POSIX|Bourne-Again) shell script.*text"
|
||||
linter dash -n
|
||||
comment "#"
|
||||
|
||||
linter dash -n
|
||||
|
||||
# Function declarations.
|
||||
color brightgreen "^[A-Za-z0-9_-]+\(\)"
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
syntax tex "\.tex$"
|
||||
magic "(La)?TeX document"
|
||||
linter chktex -v0 -q -I
|
||||
comment "%"
|
||||
|
||||
linter chktex -v0 -q -I
|
||||
|
||||
color green "\\.|\\[A-Za-z]*"
|
||||
color magenta "[{}]"
|
||||
color blue "(^|[^\])%.*"
|
||||
|
||||
Reference in New Issue
Block a user