Compare commits
421 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7fa43d600 | ||
|
|
49a84f9e8a | ||
|
|
6ee657b7d8 | ||
|
|
6866ea0d0e | ||
|
|
34d38fe1c6 | ||
|
|
b17309b652 | ||
|
|
107abd2654 | ||
|
|
f528ced22b | ||
|
|
71628ad0b8 | ||
|
|
481529e865 | ||
|
|
bc6645f753 | ||
|
|
c1ca578853 | ||
|
|
4ce2e146ea | ||
|
|
39ed865043 | ||
|
|
0de4700002 | ||
|
|
ea95ad24be | ||
|
|
415e55ff37 | ||
|
|
c20134c20d | ||
|
|
56308b3256 | ||
|
|
3d8cd65b1b | ||
|
|
2b6924ef6e | ||
|
|
01d8b0e15d | ||
|
|
16f17f3f1b | ||
|
|
09042f5499 | ||
|
|
3690d60b71 | ||
|
|
4dedb1c1b1 | ||
|
|
067ee1a6b1 | ||
|
|
0c1db4879e | ||
|
|
02efc760bf | ||
|
|
a91bc04e04 | ||
|
|
9a59cddcd4 | ||
|
|
6ab754676a | ||
|
|
9917a05f04 | ||
|
|
fcda76f684 | ||
|
|
639f37669a | ||
|
|
6d720bf7b2 | ||
|
|
f3b030c8e5 | ||
|
|
6b8b7c9d55 | ||
|
|
21ed79938e | ||
|
|
004af03ea5 | ||
|
|
b2c63c3d3c | ||
|
|
ae139021eb | ||
|
|
f6dedf3598 | ||
|
|
8003842e5c | ||
|
|
01477d3b81 | ||
|
|
ebf9279f95 | ||
|
|
304548ef82 | ||
|
|
dd6f129c3c | ||
|
|
c2f007afc5 | ||
|
|
8dc83951ee | ||
|
|
b7dc5abca7 | ||
|
|
8b784785ec | ||
|
|
750b51c343 | ||
|
|
e09ed765a1 | ||
|
|
70a765e387 | ||
|
|
c65fa25ce2 | ||
|
|
cbbfebbc7a | ||
|
|
9d499c769b | ||
|
|
dad2b5541e | ||
|
|
56960ce05e | ||
|
|
e247be69bf | ||
|
|
e209686835 | ||
|
|
047936c338 | ||
|
|
ca0571ea52 | ||
|
|
655cf9573f | ||
|
|
c457f744ef | ||
|
|
8f3ea23ece | ||
|
|
3225c71ecd | ||
|
|
5310a355ef | ||
|
|
d7875cdf4f | ||
|
|
dc05defb8a | ||
|
|
98c11d0a82 | ||
|
|
14f1652842 | ||
|
|
d4b97a08cd | ||
|
|
c934c1d71b | ||
|
|
a16315a65f | ||
|
|
d6beca5dcf | ||
|
|
9d7e62be1a | ||
|
|
5c008726f0 | ||
|
|
8c506d86af | ||
|
|
db7a49edc6 | ||
|
|
2428c5cbe6 | ||
|
|
01bc0148c0 | ||
|
|
a92511ceaf | ||
|
|
19517fc51e | ||
|
|
71c35d3ca2 | ||
|
|
38af812a82 | ||
|
|
622111613f | ||
|
|
21ef05058c | ||
|
|
abcdd6605c | ||
|
|
f2d89cb3bc | ||
|
|
2d05ce37c6 | ||
|
|
2bc5c1987c | ||
|
|
e39e2ddf52 | ||
|
|
ac61254581 | ||
|
|
9e182fde66 | ||
|
|
70d59ffe16 | ||
|
|
fb4bcd8cfd | ||
|
|
2288abcd49 | ||
|
|
42fde1cbc6 | ||
|
|
d675a549de | ||
|
|
6bab8d19c6 | ||
|
|
365058c48f | ||
|
|
5eb7145939 | ||
|
|
4dab491df2 | ||
|
|
9f92341c84 | ||
|
|
3357712928 | ||
|
|
0e59c12af4 | ||
|
|
aab0d43f47 | ||
|
|
9cc32c920b | ||
|
|
72ad00f9d0 | ||
|
|
89217f20af | ||
|
|
477a9b33b4 | ||
|
|
5c6fe50487 | ||
|
|
6c34ae5804 | ||
|
|
4409b275fc | ||
|
|
8848ac5a9b | ||
|
|
c055e629c7 | ||
|
|
e6f26464d7 | ||
|
|
a0aeeba075 | ||
|
|
c640a55b1c | ||
|
|
7d0b7e47c1 | ||
|
|
132ed5c8f0 | ||
|
|
bd88b8b5a6 | ||
|
|
0568f7a2b6 | ||
|
|
1a28b08694 | ||
|
|
3b3a6b12a7 | ||
|
|
50213eee81 | ||
|
|
7cd2a7da7c | ||
|
|
4f67f364bc | ||
|
|
7cf08b93ff | ||
|
|
474a1f0447 | ||
|
|
76d7fbd5ee | ||
|
|
8d87410c94 | ||
|
|
1961c052c8 | ||
|
|
843dbd56ef | ||
|
|
be3c54c670 | ||
|
|
01afcb243c | ||
|
|
b0eb73f7b3 | ||
|
|
1907174c5f | ||
|
|
4da604be5a | ||
|
|
43754bd11d | ||
|
|
acd9046093 | ||
|
|
2fd6181873 | ||
|
|
b15c5a7eaf | ||
|
|
1b1d60b9d7 | ||
|
|
9c70fdaef9 | ||
|
|
fcbe5aedbd | ||
|
|
6c6a3f6bd3 | ||
|
|
e873121372 | ||
|
|
ad52830fb8 | ||
|
|
c802f91f4e | ||
|
|
51913542f4 | ||
|
|
be7e000389 | ||
|
|
1d4411a474 | ||
|
|
76f1a4af4f | ||
|
|
bb1a0bd86c | ||
|
|
8b2b9654ab | ||
|
|
60ae71bf3a | ||
|
|
8625609c2d | ||
|
|
3c4a4b04ce | ||
|
|
b3faf353c9 | ||
|
|
f700b422be | ||
|
|
1b2a2e6737 | ||
|
|
12e5c2f07d | ||
|
|
5c07a747bb | ||
|
|
a9f7277b1b | ||
|
|
d13b6d6896 | ||
|
|
819066c5d5 | ||
|
|
a65982bffb | ||
|
|
6b8f446b52 | ||
|
|
2b97d6563d | ||
|
|
a0506a15ee | ||
|
|
68ca1732b8 | ||
|
|
75f4309c1f | ||
|
|
78767b583d | ||
|
|
a0703ab62d | ||
|
|
9d232cd8af | ||
|
|
03d296eb35 | ||
|
|
2b27df6733 | ||
|
|
f012d54a1d | ||
|
|
61dc2cab0b | ||
|
|
a2313f499c | ||
|
|
cbda89766f | ||
|
|
070ccf4a5b | ||
|
|
8e4b68917c | ||
|
|
0d0d011579 | ||
|
|
71daa1ef6b | ||
|
|
0ed62e84de | ||
|
|
0a31a9aa38 | ||
|
|
6747142cd7 | ||
|
|
6cf442e329 | ||
|
|
d26f16a175 | ||
|
|
8d7f8cda8c | ||
|
|
75a70d98d5 | ||
|
|
b3374ea1fb | ||
|
|
0905c6ae7e | ||
|
|
3eeedd7caf | ||
|
|
410dcee0a1 | ||
|
|
5b4d2350e6 | ||
|
|
cbeea859c2 | ||
|
|
422cd726fa | ||
|
|
9f43b4c758 | ||
|
|
dd429d9c00 | ||
|
|
b63c90bf6b | ||
|
|
fa26889d03 | ||
|
|
30011b8525 | ||
|
|
3ac5432e29 | ||
|
|
1d52548575 | ||
|
|
d5ce44820a | ||
|
|
cc2b4f712c | ||
|
|
98f038ad96 | ||
|
|
f8d2f552bd | ||
|
|
f2ae08ab19 | ||
|
|
325d774393 | ||
|
|
0856f53703 | ||
|
|
7f0bfdfeb2 | ||
|
|
51371e0ca5 | ||
|
|
3bd66b78c1 | ||
|
|
5ea6054a75 | ||
|
|
04738996fc | ||
|
|
07a9477213 | ||
|
|
a5b48f9a0d | ||
|
|
d141e849a3 | ||
|
|
da68ee19e7 | ||
|
|
8b2f7bd5a2 | ||
|
|
6119756347 | ||
|
|
06c80b6ccd | ||
|
|
7ce1f6d86d | ||
|
|
88087f2b2f | ||
|
|
16c4f5bbd0 | ||
|
|
e877c2406e | ||
|
|
b6a1583e8e | ||
|
|
48df800db3 | ||
|
|
ee05daab92 | ||
|
|
74f4c37d5f | ||
|
|
3f5ba950d6 | ||
|
|
0a52e92d4c | ||
|
|
7c57806c6f | ||
|
|
a2f8703df5 | ||
|
|
073251fdb1 | ||
|
|
5a0ee3c2f9 | ||
|
|
6bd5dce954 | ||
|
|
f25059c244 | ||
|
|
856f2c433e | ||
|
|
38c5a4465b | ||
|
|
f494bfcbb9 | ||
|
|
b856fc4664 | ||
|
|
faa96ead44 | ||
|
|
26444bf8df | ||
|
|
4eaade2938 | ||
|
|
662e8b2d20 | ||
|
|
4502295a34 | ||
|
|
25b0bf0ae8 | ||
|
|
f6b6bc47d6 | ||
|
|
a692b01c04 | ||
|
|
a197ccf12d | ||
|
|
67e5913edf | ||
|
|
e864107046 | ||
|
|
7984ea4eb6 | ||
|
|
f38bd5030d | ||
|
|
a2fea9928d | ||
|
|
c64f506933 | ||
|
|
445cd2a6c5 | ||
|
|
fb073ec88d | ||
|
|
c09e96f294 | ||
|
|
0b54785fe5 | ||
|
|
8835c0d486 | ||
|
|
0442eef95b | ||
|
|
6ae11071b3 | ||
|
|
3c177c1bb9 | ||
|
|
e0213b1a41 | ||
|
|
e70ff87c86 | ||
|
|
db10a421dc | ||
|
|
5725336149 | ||
|
|
b8ba27bbc0 | ||
|
|
e3f6638a76 | ||
|
|
f8553f6d3a | ||
|
|
a78da18aa4 | ||
|
|
d764d7094f | ||
|
|
2651554721 | ||
|
|
fa686457c2 | ||
|
|
a65f0ec80c | ||
|
|
e01e1d8ab5 | ||
|
|
58597b6d9b | ||
|
|
196e913681 | ||
|
|
620553b795 | ||
|
|
6df50790cd | ||
|
|
6cd98e32f7 | ||
|
|
f9baa4de71 | ||
|
|
1cd5005d06 | ||
|
|
f7a3b996fa | ||
|
|
ea874112d8 | ||
|
|
25d397e7b3 | ||
|
|
5111b20bf5 | ||
|
|
f571d6ba36 | ||
|
|
0e21baf611 | ||
|
|
1e78881a70 | ||
|
|
077d307b30 | ||
|
|
998992ddcb | ||
|
|
0ff9499583 | ||
|
|
eb1668ce81 | ||
|
|
54b97a6f03 | ||
|
|
5e48c36877 | ||
|
|
9e3fca4021 | ||
|
|
5130c35b85 | ||
|
|
e01651cde1 | ||
|
|
12cf1c9980 | ||
|
|
092711e412 | ||
|
|
0e6d693dc8 | ||
|
|
aac3126183 | ||
|
|
63cddceeaa | ||
|
|
486d4956ff | ||
|
|
7567a67cdd | ||
|
|
c4939c76a5 | ||
|
|
04e557fdaf | ||
|
|
7dcc8f1d7a | ||
|
|
343f97b3ac | ||
|
|
706f3e93f4 | ||
|
|
f47ef539db | ||
|
|
2148e857e5 | ||
|
|
afa4c6b9fc | ||
|
|
27127853db | ||
|
|
a81ba0215a | ||
|
|
3e0bd533db | ||
|
|
e8d20a8e4b | ||
|
|
6896d8df47 | ||
|
|
8455251c35 | ||
|
|
5cf351913e | ||
|
|
416386edcd | ||
|
|
497f126bb2 | ||
|
|
4687322398 | ||
|
|
99f0265d34 | ||
|
|
7b0b9a12ea | ||
|
|
7d483987ce | ||
|
|
f705a9674b | ||
|
|
3233e9cfe0 | ||
|
|
5a98a51173 | ||
|
|
2eaba21a4c | ||
|
|
9a227de3e7 | ||
|
|
3f57200e10 | ||
|
|
1486f32d42 | ||
|
|
e3edce4e7b | ||
|
|
0e559c5bbc | ||
|
|
edfbfbfd0a | ||
|
|
a4eae770ce | ||
|
|
72e5c15110 | ||
|
|
97c8140cea | ||
|
|
c5b03ca4ae | ||
|
|
c2f2c659d9 | ||
|
|
9364bd6c81 | ||
|
|
baa2be3217 | ||
|
|
12742586e5 | ||
|
|
194620c5f0 | ||
|
|
67d37adf98 | ||
|
|
3f0d2fd5ca | ||
|
|
5b07e5fd1f | ||
|
|
3cae32390d | ||
|
|
1be0285832 | ||
|
|
2867f1bbde | ||
|
|
c4d2bf59fb | ||
|
|
5527883c43 | ||
|
|
ade93ccf25 | ||
|
|
84b305f3f0 | ||
|
|
67b89459d5 | ||
|
|
6d916c6c4a | ||
|
|
87542eeaf1 | ||
|
|
29f2e3181a | ||
|
|
8255696b45 | ||
|
|
fc00e89499 | ||
|
|
55946c15e7 | ||
|
|
2e539e2c97 | ||
|
|
38c286c019 | ||
|
|
56d842258c | ||
|
|
8ed8ab69d5 | ||
|
|
4dcbd40c49 | ||
|
|
72645b160d | ||
|
|
dda1b167c9 | ||
|
|
074cf40409 | ||
|
|
6c09504040 | ||
|
|
4991b3bb1a | ||
|
|
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 |
442
ChangeLog
442
ChangeLog
@@ -1,3 +1,445 @@
|
||||
Changes between v4.8 and v4.9:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (209):
|
||||
bindings: remove the translation of ^H to Backspace on the BSDs
|
||||
build: fix compilation for --enable-tiny --enable-justify
|
||||
build: restore non-UTF8 fallbacks, to allow compiling with --disable-utf8
|
||||
build: update the conditional placement of the "Go To Line" menu item
|
||||
bump version numbers and add a news item for the 4.9 release
|
||||
chars: optimize a function for the most common blanks: space and tab
|
||||
copyright: update to the current year for significantly changed files
|
||||
cutting: let M-T cut a trailing empty line, but not nothing at all
|
||||
cutting: with --cutfromcursor, allow ^K to cut the penultimate empty line
|
||||
display: do not show a "[" double-width placeholder when softwrapping
|
||||
display: keep the help items aligned, by not writing too many characters
|
||||
docs: improve the descriptions of --softwrap and 'set softwrap'
|
||||
docs: mark bracketed pasting as done in the TODO list
|
||||
docs: mention that ^[ (Esc) is unbindable, and explain why
|
||||
docs: remove the note saying that nanorc files must be in Unix format
|
||||
docs: trim some TODO items, and condense several others
|
||||
docs: update the form of an option, --suspendable / 'set suspendable'
|
||||
docs: update the missed occurrences of --suspendable / 'set suspendable'
|
||||
feedback: give a clearer message when trying to justify an empty region
|
||||
feedback: make sure that a later message can overwrite a short warning
|
||||
files: be consistent in which code means "New File"
|
||||
files: don't check uninitialized memory when writing new file [valgrind]
|
||||
files: when piping, always pipe whatever was cut to the external command
|
||||
gnulib: update to its current upstream state
|
||||
help: do not break a line inside the 17-column keystrokes area
|
||||
help: increase the minimum help-text width from 32 to 40 columns
|
||||
input: accommodate silly emulators that have LF instead of CR in a paste
|
||||
input: after reallocating a string, do not write to its old address
|
||||
input: allocate sufficient bytes for entering a Unicode codepoint
|
||||
input: keep a multibyte character together during verbatim entry
|
||||
justify: do not copy too many bytes when trimming leading whitespace
|
||||
justify: do not crash when the user attempts to justify an empty region
|
||||
justify: do not take an empty line as template for first-line indentation
|
||||
justify: give the first line of a marked region its proper indentation
|
||||
justify: never break a line in leading whitespace
|
||||
justify: restore a region properly when it was marked backwards
|
||||
justify: skip over blanks after the region, to not skew the indentation
|
||||
justify: skip over in-line whitespace only, not over leading whitespace
|
||||
justify: trim prefixed whitespace when justifying a marked region
|
||||
justify: trim the leading blanks of a marked region at the right moment
|
||||
justify: when appropriate, move end point of marked region forward
|
||||
justify: when the cursor is at the left edge, keep it there
|
||||
locking: do not open an empty buffer when respecting the first lock file
|
||||
moving: do not put the cursor at end-of-line when in a help text
|
||||
options: rename --suspend to --suspendable, to make more sense
|
||||
prompt: insert a burst of bytes in one go instead of characterwise
|
||||
rcfile: allow alternate line endings in nanorc files
|
||||
rcfile: do not allow a regex for name, header, or magic to be empty
|
||||
rcfile: don't store a coloring rule before it is complete
|
||||
rcfile: rename bindable function 'suspendenable' to 'suspendable'
|
||||
rcfile: when a start= is not matched with an end=, abandon the whole rule
|
||||
rcfile: when finding a mistake, skip the rest of the line
|
||||
shutdown: don't refer to an open file when there aren't any
|
||||
softwrap: when typing goes beyond the bottom row, scroll just one row
|
||||
syntax: nanorc: colorize 'rawsequences', not the obsolete 'rebindkeypad'
|
||||
syntax: spec: add two missing % signs, and colorize also "%triggerprein"
|
||||
syntax: spec: colorize the date and author of changelog items differently
|
||||
syntax: spec: drop invalid parentheses after "Summary"
|
||||
tweaks: abort in three situations that should never occur
|
||||
tweaks: add a COUPLE_END undo item a bit later, instead of updating it
|
||||
tweaks: add a different helping variable
|
||||
tweaks: add a supporting variable, in order to condense some statements
|
||||
tweaks: add calls of die() for five theoretical programming mistakes
|
||||
tweaks: adjust some whitespace, reshuffle two ifs, and remove two braces
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: always determine the second lead, to simplify the rewrap call
|
||||
tweaks: avoid a complaint about uninitialized memory [valgrind]
|
||||
tweaks: call add_undo() before the character is actually added
|
||||
tweaks: change a function to return the name of the lock file on success
|
||||
tweaks: change a function with two possible results to boolean
|
||||
tweaks: change an integer to a short, and reshuffle it for better packing
|
||||
tweaks: change another function with two possible results to boolean
|
||||
tweaks: check for a starting quote in one place instead of three
|
||||
tweaks: combine two ifs into one
|
||||
tweaks: condense a comment, reshuffle conditions, and remove unwanted one
|
||||
tweaks: condense a fragment of code
|
||||
tweaks: condense two fragments of code
|
||||
tweaks: convert integers to bytes in one place instead of two
|
||||
tweaks: copy and store a deleted character in a conciser manner
|
||||
tweaks: correct a typo, improve two indentations, and rewrap a line
|
||||
tweaks: correct two typos in a changelog, and drop a doubled word
|
||||
tweaks: create an undo item earlier, and discard it when needed
|
||||
tweaks: don't bother reallocating the line data when undoing a line join
|
||||
tweaks: do some text alignments properly: with spaces, not tabs
|
||||
tweaks: drop a check for something that will not occur
|
||||
tweaks: drop two comments that contain variable names
|
||||
tweaks: elide a function call, by copying a byte directly
|
||||
tweaks: elide an intermediate copy of a character during injection, twice
|
||||
tweaks: elide an intermediate copy of an added character
|
||||
tweaks: elide a parameter, and rename a variable
|
||||
tweaks: elide a supporting variable, to make four loops slightly faster
|
||||
tweaks: elide a variable and an unneeded iteration
|
||||
tweaks: elide one variable and three gotos
|
||||
tweaks: elide three unneeded #defines
|
||||
tweaks: elide two variables and their two assignments
|
||||
tweaks: exclude a function when compiled without spell-checking support
|
||||
tweaks: extend the undo data for deleting and backspacing more directly
|
||||
tweaks: factor out a three-line condition into a separate function
|
||||
tweaks: frob a statement, rewrap two lines, and remove a pair of braces
|
||||
tweaks: frob two statements, condense another, and add a comment
|
||||
tweaks: highlight keystrokes in the documentation more consistently
|
||||
tweaks: improve four comments, and condense two fragments of code
|
||||
tweaks: improve three comments, and reshuffle two declarations
|
||||
tweaks: improve two comments
|
||||
tweaks: improve two comments, and remove an unneeded one
|
||||
tweaks: inject the entire burst of bytes at once into the edit buffer
|
||||
tweaks: instead of swapping the end points later, assign them correctly
|
||||
tweaks: invert the logic of a symbol, to make more sense
|
||||
tweaks: make prompt-bar input more similar to edit-buffer input
|
||||
tweaks: make two conditions more direct, and thus elide two functions
|
||||
tweaks: mesh two bits of code together
|
||||
tweaks: move a function to after the one that it calls
|
||||
tweaks: move a function to before the one that calls it
|
||||
tweaks: move a function to before the one that calls it
|
||||
tweaks: move a function to its proper place in the order of things
|
||||
tweaks: move a function to where it is used
|
||||
tweaks: move another function to where it is used
|
||||
tweaks: move some definitions closer to where they are used
|
||||
tweaks: move two functions to before the ones that call them
|
||||
tweaks: normalize a translator hint, update one, and add another
|
||||
tweaks: normalize the indentation after the previous change
|
||||
tweaks: normalize the indentation after the previous change
|
||||
tweaks: normalize the indentation after the previous two changes
|
||||
tweaks: pull the NUL-terminating of a string into a function
|
||||
tweaks: rearrange a case item, so that PASTE is always after CUT
|
||||
tweaks: rearrange some conditions, for compactness
|
||||
tweaks: relocate a function to before its callers
|
||||
tweaks: relocate eleven functions to before they are called
|
||||
tweaks: remove a now-unused helper function
|
||||
tweaks: remove an unneeded indirection
|
||||
tweaks: remove a redundant assignment
|
||||
tweaks: remove a redundant statement, a spurious reference to 'cutbottom'
|
||||
tweaks: remove a superfluous assignment, and reshuffle a call
|
||||
tweaks: remove non-UTF-8 code from three more functions
|
||||
tweaks: remove some redundant filtering, and thus elide a parameter
|
||||
tweaks: remove some unneeded braces, not used elsewhere either
|
||||
tweaks: remove two redundant case labels
|
||||
tweaks: remove two superfluous checks
|
||||
tweaks: remove two superfluous conditions
|
||||
tweaks: rename a constant, and rename and relocate a function
|
||||
tweaks: rename a function, and condense a few comments
|
||||
tweaks: rename a function, and split a variable into two separate ones
|
||||
tweaks: rename a function, to be more fitting, and improve some comments
|
||||
tweaks: rename a function, to remove an obscuring abbreviation
|
||||
tweaks: rename another function, to remove the obscuring abbreviation
|
||||
tweaks: rename a parameter and a variable, and reword two comments
|
||||
tweaks: rename a symbol, to match the corresponding renamed option
|
||||
tweaks: rename a variable, and add a helping one
|
||||
tweaks: rename a variable, and reshuffle a declaration
|
||||
tweaks: rename a variable, away from a single letter
|
||||
tweaks: rename a variable, away from a single letter
|
||||
tweaks: rename a variable, for aptness
|
||||
tweaks: rename a variable, reshuffle an assignment, and change a code
|
||||
tweaks: rename a variable, to be a bit clearer
|
||||
tweaks: rename a variable, to get out of the way of a later rename
|
||||
tweaks: rename a variable, to not be a substring of a function name
|
||||
tweaks: rename four more functions, to get rid of an abbreviation
|
||||
tweaks: rename four parameters, to be more distinct and telling
|
||||
tweaks: rename four variables, to be a bit more telling
|
||||
tweaks: rename to the same name two variables that have the same role
|
||||
tweaks: rename two elements of an undo record, to be more telling
|
||||
tweaks: rename two functions, for shortness
|
||||
tweaks: rename two functions, to match the style of others
|
||||
tweaks: rename two more elements of an undo record, for symmetry
|
||||
tweaks: rename two more functions, to match the style of others
|
||||
tweaks: rename two more variables, to harmonize with two others
|
||||
tweaks: rename two parameters, to not overlap with other names
|
||||
tweaks: rename two symbols, to be more precise
|
||||
tweaks: rename two variables, and frob four comments
|
||||
tweaks: rename two variables, and reshuffle a few things
|
||||
tweaks: rename two variables, for distinctiveness
|
||||
tweaks: rename two variables, to be different or for more contrast
|
||||
tweaks: rename two variables, to harmonize with two others
|
||||
tweaks: rename two variables, to suit both the marked and unmarked case
|
||||
tweaks: reorder a case item, to have SPLIT_BEGIN always before SPLIT_END
|
||||
tweaks: reshuffle a condition, for compacter code
|
||||
tweaks: reshuffle a condition, for compactness
|
||||
tweaks: reshuffle a few declarations and assignments
|
||||
tweaks: reshuffle an assignment and a free()
|
||||
tweaks: reshuffle some code, in preparation for improving it
|
||||
tweaks: reshuffle some stuff, to have related things together
|
||||
tweaks: reshuffle the setting of the starting point of a cut
|
||||
tweaks: reshuffle the trimming of leading whitespace, for compactness
|
||||
tweaks: reshuffle two declarations plus a fragment of code
|
||||
tweaks: simplify the undoing and redoing of an <Enter>
|
||||
tweaks: strip a parameter that is equivalent to 'openfile' for both calls
|
||||
tweaks: strip a parameter that is TRUE for both calls
|
||||
tweaks: swap the use of 'head' and 'tail' for CUT and PASTE undo items
|
||||
tweaks: trim an unnecessary detail from an error message
|
||||
tweaks: unabbreviate the name of a variable
|
||||
tweaks: unwrap four lines, and use explicit codes where possible
|
||||
tweaks: update several comments after the previous changes
|
||||
tweaks: update some comments after the previous changes
|
||||
tweaks: use a symbol instead of a number, and drop two unneeded casts
|
||||
tweaks: use spaces when aligning things, not tabs
|
||||
tweaks: use the variable that suits 'END' better
|
||||
tweaks: weld two fragments together, twice, by eliding an unneeded 'if'
|
||||
tweaks: when appropriate, move starting point of justified region back
|
||||
tweaks: when extending the marked region, include also exotic blanks
|
||||
tweaks: when undoing an addition or redoing a deletion, do not reallocate
|
||||
undo: do not mark the buffer as modified when pasting back nothing
|
||||
undo: do not try to copy a cutbuffer that is NULL
|
||||
undo: do not try to paste back an empty cutbuffer
|
||||
undo: for an automatic hard-wrap, store the correct previous buffer size
|
||||
undo: store the cursor row, for redoing filtering & justification better
|
||||
undo: treat a cut-until-end-of-buffer like a backward marked region
|
||||
undo: use the correct original fusion point when unjoining two lines
|
||||
undo: when undoing a paste or an insertion, remove an added magic line
|
||||
usage: improve the description of --softwrap
|
||||
|
||||
Neal Gompa (1):
|
||||
syntax: spec: add some keywords that were added in RPM 4.15 and 4.13
|
||||
|
||||
Saagar Jha (1):
|
||||
rcfile: fix an out-of-bounds read on empty lines
|
||||
|
||||
|
||||
Changes between v4.7 and v4.8:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (166):
|
||||
bindings: allow to bind shifted Meta+letter combinations with Sh-M-X
|
||||
bindings: allow to rebind also ^`, although it is synonymous with ^Space
|
||||
bindings: do not show the Full-Justify keystroke when in View mode
|
||||
bindings: force the first letter in a key name to uppercase
|
||||
build: exclude bracketed pasting from the tiny version
|
||||
build: exclude option '-g' when configured without browser and help
|
||||
build: exclude the escape sequences for F13...F16 from the tiny version
|
||||
build: fix compilation for --enable-{tiny,help,multibuffer}
|
||||
build: restrict the use of --with-slang to together with --enable-tiny
|
||||
bump version numbers and add a news item for the 4.8 release
|
||||
copyright: update the years for significantly changed files
|
||||
copyright: update the years for the FSF
|
||||
display: adjust line and column count upon a resize also when using Slang
|
||||
display: clear the help lines before a briefly shown warning
|
||||
display: don't let a message write over the second help line
|
||||
display: ensure the guiding stripe can be shown when not softwrapping
|
||||
display: exclude a bit of feedback from the tiny version
|
||||
display: show the cursor during suspension also when built with Slang
|
||||
display: skip zero-width characters on a Linux console, to avoid a mess
|
||||
docs: add a FAQ item about a self-compiled nano not reading /etc/nanorc
|
||||
docs: document the new -f/--rcfile option
|
||||
docs: document the new Sh-M-X format for binding <Shift+Meta+letter>
|
||||
docs: for the alternative bindings, rebind ^C only in the main menu
|
||||
docs: improve the description of which rc-files are read during startup
|
||||
docs: mention in the FAQ that auto-indentation is suppressed when pasting
|
||||
docs: mention that -D/--boldtext gets overridden by some nanorc options
|
||||
docs: put the three new behaviors in a bulletted list, to catch the eye
|
||||
docs: stop saying that 'set fill' enables hard-wrapping -- it does not
|
||||
docs: use more generally available arrows in the cheatsheet
|
||||
feedback: ask a clearer question when a valid lock file is encountered
|
||||
feedback: report Ctrl+Alt keystrokes as unbindable
|
||||
feedback: restore a message that can occur in help viewer or file browser
|
||||
files: alert the user afterward when an overwritten file is being edited
|
||||
files: revert the previous commit, as the extra warning is annoying
|
||||
files: warn doubly when the user is about to overwrite an existing file
|
||||
files: write a lock file also for a new file and when the name changed
|
||||
gnulib: update to its current upstream state
|
||||
help: don't waste the last column in the help viewer on narrow terminals
|
||||
help: increase the minimum help-text width from 24 to 32 columns
|
||||
help: prevent double spaces from protruding across the right edge
|
||||
help: when a key description wraps, indent its wrapped part
|
||||
input: consume and ignore the raw escape sequences for F17 to F24
|
||||
input: correct the escape sequence for PageUp/PageDown on Eterm/Urxvt
|
||||
input: Ctrl+arrow is "Esc O x" on Eterm, as on rxvt -- not "Esc o x"
|
||||
input: discard partial sequences that Slang produces for F17 to F24
|
||||
input: do not auto-indent when something is pasted into nano from outside
|
||||
input: don't discard the first keystroke after a resize when using Slang
|
||||
input: filter out Ctrl+Meta keystrokes, as they can never be shortcuts
|
||||
input: ignore bracketed pastes in help viewer and file browser
|
||||
input: ignore modifiers on a VT while executing a macro or a string bind
|
||||
input: prevent unintentional marking of text for shifted Meta keystrokes
|
||||
input: read in an external paste in one go, to allow undoing with one M-U
|
||||
input: recognize the raw escape sequences for F13 to F16 on xterm too
|
||||
locking: accept a minimal amount of data, enough for PID plus username
|
||||
locking: avoid crashing when there is a problem writing the lock file
|
||||
locking: check two magic bytes, to verify that it is a lock file
|
||||
locking: do not write a lock file when in view mode
|
||||
locking: when a lock file is unreadable, open the file itself anyway
|
||||
locking: when finding a lock file at startup, quit when user cancels
|
||||
new feature: allow specifying a custom nanorc file on the command line
|
||||
pasting: retain the mark's position when it was set at the cursor
|
||||
prompt: for a Yes-No-All, accept the first character of an external paste
|
||||
rcfile: do set the meta flag for plain <Meta+ASCII> combinations
|
||||
rcfile: require "bright", "start=", and "end=" to be in lowercase too
|
||||
rcfile: unbind keys by their key code instead of by their key string
|
||||
softwrap: suppress the guiding stripe on unaffected chunks
|
||||
speller: avoid messing up the screen when an unknown locale is used
|
||||
suspension: put in an extra terminal-initialization call for Slang
|
||||
syntax: nanohelp, nanorc: colorize the Sh-M-X format as a valid key name
|
||||
syntax: nanorc: colorize all-lowercase Meta key binds as valid too
|
||||
tweaks: add a little change that was overlooked in the previous commit
|
||||
tweaks: add an error message for something that should never occur
|
||||
tweaks: adjust or reword a few items in the FAQ
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: allocate the lock data only when ready to write them
|
||||
tweaks: avoid analyzing the key string when the target key code is known
|
||||
tweaks: avoid determining the key code from the key string twice
|
||||
tweaks: avoid fiddling with the keybuffer when it's not needed
|
||||
tweaks: comment fully, so that all handled escape sequences are findable
|
||||
tweaks: condense a fragment of code
|
||||
tweaks: condense five more fragments of repetitious code
|
||||
tweaks: condense three comments to one, and do the masking more directly
|
||||
tweaks: condense three fragments of repetitious code
|
||||
tweaks: condense two comments, and reshuffle an #endif
|
||||
tweaks: correct a comment
|
||||
tweaks: correct a couple of comments about escape sequences
|
||||
tweaks: correct the description of what nano writes into the lock file
|
||||
tweaks: delete some fragments of code that have become irrelevant
|
||||
tweaks: do not leak a file descriptor when fdopen() fails
|
||||
tweaks: don't bother including Haiku escape sequences in the tiny version
|
||||
tweaks: don't enable bracketed pasting when not handling such pastes
|
||||
tweaks: drop a message that will never be seen
|
||||
tweaks: drop an unneeded call of keypad() -- we never read from topwin
|
||||
tweaks: drop a pointless suffix from two function names
|
||||
tweaks: elide a function that has become too small for its two calls
|
||||
tweaks: elide a helper function, in preparation for an improvement
|
||||
tweaks: elide an 'if', by moving the relevant code to a better place
|
||||
tweaks: elide a small function, as it's in fact needed just once
|
||||
tweaks: elide a somewhat costly call by remembering some state
|
||||
tweaks: elide a variable, and rename its sister
|
||||
tweaks: elide three checks of a shortcut's meta flag
|
||||
tweaks: ensure that editor name and user name are NUL terminated
|
||||
tweaks: exclude an unneeded fragment of code from the tiny version
|
||||
tweaks: exclude two unneeded fragments of code from the tiny version
|
||||
tweaks: free two strings as soon as they are no longer needed
|
||||
tweaks: frob a couple of indentations and white lines
|
||||
tweaks: fuse two nearly identical functions into a single one
|
||||
tweaks: gather four calls that are always done together into a function
|
||||
tweaks: harmonize the amount of lock data that we read and write
|
||||
tweaks: improve a comment by indirectly referring to the ncurses docs
|
||||
tweaks: in comments, reword "titlebar" and "statusbar" to two words each
|
||||
tweaks: initialize three booleans straightaway, when they are declared
|
||||
tweaks: initialize three more booleans straightaway, at declaration
|
||||
tweaks: judge from the key code itself whether it is a Meta keystroke
|
||||
tweaks: make a couple of comments more precise
|
||||
tweaks: move a function to after the one that it calls
|
||||
tweaks: move a function to be before the ones that call it
|
||||
tweaks: move a function to before the one that calls it
|
||||
tweaks: move a function to related ones, and after one that it calls
|
||||
tweaks: move a function to right before the one that calls it
|
||||
tweaks: move another function to after the one that it calls
|
||||
tweaks: move another function to before the one that calls it
|
||||
tweaks: move another function, to group the deleting ones together
|
||||
tweaks: move three functions to the file where they are mainly used
|
||||
tweaks: rearrange a few global variables, to group things better
|
||||
tweaks: recompute the wrapping point just once
|
||||
tweaks: reduce the scope of a variable, and reshuffle a declaration
|
||||
tweaks: reduce the scope of two constants and of four variables
|
||||
tweaks: reformat a comment, and resuffle a line to match byte order
|
||||
tweaks: remove a feedback message that is never shown
|
||||
tweaks: remove a redundant call, as there is nothing to free there
|
||||
tweaks: remove a superfluous check
|
||||
tweaks: remove some superfluous conditions for rewriting a lock file
|
||||
tweaks: remove the now-unneeded code related to bracketed pasting
|
||||
tweaks: remove the now-unused meta flag from 'keystruct'
|
||||
tweaks: remove two superfluous assignments, and rename a variable
|
||||
tweaks: rename a function and its parameter, to be more fitting
|
||||
tweaks: rename a function, to be a bit more expressive
|
||||
tweaks: rename a function, to make it not contain the name of another
|
||||
tweaks: rename a parameter and invert its logic, and correct a comment
|
||||
tweaks: rename five variables, away from a single letter
|
||||
tweaks: rename two functions, to make more sense
|
||||
tweaks: rename two parameters, to be more general and to sound shorter
|
||||
tweaks: rename two variables, to make more sense
|
||||
tweaks: renumber some FAQ items in preparation for adding another
|
||||
tweaks: reorder two symbols
|
||||
tweaks: reshuffle some assignments for a return value
|
||||
tweaks: reshuffle some declarations
|
||||
tweaks: reshuffle some declarations, and expand a few variable names
|
||||
tweaks: reshuffle some lines, to avoid tallying the menus when not needed
|
||||
tweaks: reshuffle some lines, to group all ignored keystrokes together
|
||||
tweaks: reshuffle three lines, to make the grouping tighther
|
||||
tweaks: reshuffle two lines, to do the linking first, then the content
|
||||
tweaks: reword two comments, and rewrap another
|
||||
tweaks: rewrap a comment and a line, and reshuffle a fragment of code
|
||||
tweaks: rewrap two lines, for consistency with similar lines
|
||||
tweaks: rewrite the same file name into the lock file as the first time
|
||||
tweaks: slightly condense a function by conflating case
|
||||
tweaks: stop recognizing escape sequences for a key without meaning
|
||||
tweaks: suggest a few more alternative key bindings and unbindings
|
||||
tweaks: take just one shot at reading the lock file, and correct a type
|
||||
tweaks: trim some excessive error checking and key-name frobbing
|
||||
tweaks: tumble three conditions, for consistency in comparisons
|
||||
tweaks: unabbreviate "argument" in the documentation
|
||||
tweaks: use a simple subtraction instead of a function call
|
||||
usage: improve the description of --restricted and --quickblank
|
||||
|
||||
Brand Huntsman (2):
|
||||
input: beep when invalid key is pressed at yesno prompt or in linter menu
|
||||
input: recognize the start and stop sequences of a bracketed paste
|
||||
|
||||
|
||||
Changes between v4.6 and v4.7:
|
||||
------------------------------
|
||||
|
||||
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:
|
||||
------------------------------
|
||||
|
||||
|
||||
@@ -3448,14 +3448,14 @@ GNU nano 2.1.8 - 2009.02.07
|
||||
2009-01-25 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c (open_file), nanorc.c (parse_include): Don't get_full_path on included
|
||||
rc files, due to it potentially impacting the ability to read files in nano's
|
||||
cwd(). Fixes Savnanah bug #25297 reported by Mike Frysinger.
|
||||
cwd(). Fixes Savannah bug #25297 reported by Mike Frysinger.
|
||||
|
||||
2009-01-24 Chris Allegretta <chrisa@asty.org>
|
||||
* First pass at some caching of caching color info. Right now it's only for
|
||||
* First pass at some caching of color info. Right now it's only for
|
||||
multi-line regexes but this may not be enough to increase performance.
|
||||
* Add interruptability to search functions. New functions enable_nodelay and
|
||||
disable_nodelay and changes to the routines to handle checking for pending
|
||||
searches. Fixes Savnnah bug #24946: Need interrrupt for search.
|
||||
searches. Fixes Savannah bug #24946: Need interrrupt for search.
|
||||
|
||||
2009-01-19 Chris Allegretta <chrisa@asty.org>
|
||||
* Change function definitions to shorts instead of (void *)s. New mapping function
|
||||
|
||||
@@ -2,6 +2,10 @@ Improvements in GNU nano
|
||||
========================
|
||||
|
||||
Since 4.0:
|
||||
- Pasting from outside into nano suppresses auto-indentation.
|
||||
- Such an external paste can be undone with a single M-U.
|
||||
- Shift+Meta+letter key combos can be bound with 'bind Sh-M-letter ...'.
|
||||
- A custom nanorc file may be specified with -f / --rcfile.
|
||||
- What the <Tab> key produces can be specified per syntax with 'tabgives'.
|
||||
- The ability to perform a search at startup with +/string or +?string.
|
||||
- Comment characters are copied when automatic hard-wrapping occurs.
|
||||
|
||||
33
NEWS
33
NEWS
@@ -1,3 +1,36 @@
|
||||
2020.03.24 - GNU nano 4.9 "die fetten Jahre sind vorbei"
|
||||
• When justifying a selection, the new paragraph and the
|
||||
succeeding one get the appropriate first-line indent.
|
||||
• Trying to justify an empty selection does not crash.
|
||||
• Redoing the insertion of an empty file does not crash.
|
||||
• On the BSDs and macOS, ^H has become rebindable again
|
||||
(in most terminal emulators, not on the console).
|
||||
• DOS line endings in nanorc files are accepted.
|
||||
• Option --suspend / 'set suspend' has been renamed to
|
||||
the more logical --suspendable / 'set suspendable'.
|
||||
|
||||
2020.02.07 - GNU nano 4.8 "Jaška"
|
||||
• When something is pasted into nano, auto-indentation is suppressed,
|
||||
and the paste can be undone as a whole with a single M-U.
|
||||
• When a lock file is encountered during startup, pressing ^C/Cancel
|
||||
quits nano. (Pressing 'No' just skips the file and continues.)
|
||||
• Shift+Meta+letter key combos can be bound with 'bind Sh-M-letter'.
|
||||
Making any such binding dismisses the default behavior of ignoring
|
||||
Shift for all Meta+letter keystrokes.
|
||||
• The configuration option --with-slang (to be avoided when possible)
|
||||
can now be used only together with --enable-tiny.
|
||||
• A custom nanorc file can be specified on the command line, with
|
||||
-f filename or --rcfile=filename.
|
||||
|
||||
2019.12.23 - GNU nano 4.7 "Havikskruid"
|
||||
• A <Tab> will indent a marked region only when mark and cursor are
|
||||
on different lines.
|
||||
• 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
|
||||
|
||||
44
TODO
44
TODO
@@ -1,20 +1,20 @@
|
||||
A list of desired features
|
||||
--------------------------
|
||||
|
||||
Somewhat urgent:
|
||||
- Detect when text is being pasted, so that we can handle it faster.
|
||||
See https://savannah.gnu.org/bugs/?40060.
|
||||
- Allow color syntaxes to apply to more than just color, so that we can
|
||||
* Allow color syntaxes to apply to more than just color, so that we can
|
||||
e.g. specify a different alternate spell checker depending on which
|
||||
file type we have open.
|
||||
|
||||
Vague musings:
|
||||
- Add support for right-to-left text (RTL), through FriBidi?
|
||||
- Allow setting marks (saved positions, not to be confused with the
|
||||
* Add support for right-to-left text (RTL).
|
||||
|
||||
* Allow setting bookmarks (saved positions, not to be confused with the
|
||||
mark set via Ctrl-^) at various lines and/or columns in the buffer,
|
||||
and allow movement between them with a single keystroke?
|
||||
- Make matching bracket searches sophisticated enough to skip over
|
||||
brackets inside comments?
|
||||
See https://savannah.gnu.org/bugs/?57577.
|
||||
|
||||
|
||||
For version 4.8:
|
||||
- Detect when text is being pasted, so that we can handle it faster. [DONE]
|
||||
|
||||
For version 4.0:
|
||||
- Make undo/redo work also for justifying. [DONE]
|
||||
@@ -31,8 +31,7 @@ For version 2.8:
|
||||
For version 2.4:
|
||||
- Handle window resizes better. After we've resized, we should stay
|
||||
wherever we were before we resized, as Pico does. [DONE]
|
||||
- Allow even better file-type detection than we have currently, e.g.
|
||||
through libmagic. [DONE]
|
||||
- Allow even better file-type detection, e.g. through libmagic. [DONE]
|
||||
- Compatibility with vim status files to let other editors know we're
|
||||
in a file. [DONE]
|
||||
|
||||
@@ -49,36 +48,31 @@ For version 2.0:
|
||||
- Support for paragraph searches. [DONE]
|
||||
- Support for justifying the entire file at once. [DONE]
|
||||
- Support for filename searches in the file browser. [DONE]
|
||||
- Keystroke to implement "Add next sequence as raw" like vi's ^V. [DONE]
|
||||
- A keystroke to implement "Add next sequence as raw", like vi's ^V. [DONE]
|
||||
- Spell check selected text only. [DONE]
|
||||
- Make "To Line" (^W^T) and "Read from Command" (^R^X) reenter their
|
||||
parent menu when their keystroke is entered a second time (^W^T^T and
|
||||
(^R^X^X) (requires figuring out when to keep cursor position and when
|
||||
not to). [DONE]
|
||||
- Fix resetstatuspos global which we shouldn't have. [DONE]
|
||||
- Make "To Line" (^W^T) and "Read from Command" (^R^X) return to their parent
|
||||
menu when their keystroke is entered again (^W^T^T and ^R^X^X). [DONE]
|
||||
|
||||
For version 1.2:
|
||||
- Single-line scroll up/down? [DONE]
|
||||
- Color syntax highlighting? (There seems to be a demand for it.) [DONE]
|
||||
- Color syntax highlighting? [DONE]
|
||||
- Support for a .nanorc file. [DONE]
|
||||
- Backup making (filename~)? [DONE]
|
||||
- Search/replace string history. [DONE]
|
||||
- Implement Pico's -j and -g flags, as they are pretty easy to do. [DONE]
|
||||
- Make mouse support work with clicking on the shortcuts (-m). [DONE]
|
||||
- Implement Pico's -j and -g flags. [DONE]
|
||||
- Make mouse support (-m) work with clicking on the shortcuts. [DONE]
|
||||
- Implement -o (--operatingdir, a chroot of sorts). [DONE]
|
||||
- Allow -r to take a negative argument, meaning right margin instead of
|
||||
left (allows resizing that way), formerly -W arg. [DONE]
|
||||
- Allow -r to take a negative argument. [DONE]
|
||||
|
||||
For version 1.0:
|
||||
- Implement Spelling. [DONE]
|
||||
- Implement Help. [DONE]
|
||||
- Internationalization [In progress, translators welcome!]
|
||||
- Allow nano to be resized in X. [DONE]
|
||||
- On PageUp/Down, put the cursor on the first line (like Pico), not the
|
||||
center line. [DONE]
|
||||
- On PageUp/Down, put the cursor on the first screen line (like Pico). [DONE]
|
||||
- Implement justify function. [DONE]
|
||||
- Cut to end of line. [DONE]
|
||||
- Built-in speller command. [DONE]
|
||||
- Better statusbar interaction (scrolling, tab completion). [DONE]
|
||||
- Better status-bar interaction (scrolling, tab completion). [DONE]
|
||||
- Unjustify command (^U after ^J). [DONE]
|
||||
- Username completion (~user). [DONE]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="378d2e5e5fe4b892ac3503ab5313126b1b63341e"
|
||||
gnulib_hash="360979fd6fb84567e0ffc6839b0431fc00d6362f"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
11
configure.ac
11
configure.ac
@@ -1,6 +1,6 @@
|
||||
# Configuration for GNU nano - a small and user-friendly text editor
|
||||
#
|
||||
# Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2014, 2017 Mike Frysinger
|
||||
#
|
||||
# GNU nano is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
AC_INIT([GNU nano], [4.6], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [4.9], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.14])
|
||||
@@ -89,6 +89,12 @@ AC_CHECK_HEADERS(libintl.h limits.h pwd.h termios.h sys/param.h)
|
||||
|
||||
dnl Checks for options.
|
||||
|
||||
if test "x$with_slang" = xyes; then
|
||||
if test "x$enable_tiny" != xyes; then
|
||||
AC_MSG_ERROR([--with-slang is supported only together with --enable-tiny])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(browser,
|
||||
AS_HELP_STRING([--disable-browser], [Disable the built-in file browser]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
@@ -516,7 +522,6 @@ int main(void)
|
||||
;;
|
||||
esac], [AC_MSG_RESULT(no)])
|
||||
|
||||
|
||||
dnl Checks for functions.
|
||||
|
||||
if test "x$enable_utf8" != xno; then
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -78,14 +79,14 @@
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+B </td><td>One character backward</td></tr>
|
||||
<tr><td>Ctrl+F</td><td>One character forward</td></tr>
|
||||
<tr><td>Ctrl+⯇</td><td>One word backward</td></tr>
|
||||
<tr><td>Ctrl+⯈</td><td>One word forward</td></tr>
|
||||
<tr><td>Ctrl+<b>←</b></td><td>One word backward</td></tr>
|
||||
<tr><td>Ctrl+<b>→</b></td><td>One word forward</td></tr>
|
||||
<tr><td>Ctrl+A</td><td>To start of line</td></tr>
|
||||
<tr><td>Ctrl+E</td><td>To end of line</td></tr>
|
||||
<tr><td>Ctrl+P</td><td>One line up</td></tr>
|
||||
<tr><td>Ctrl+N</td><td>One line down</td></tr>
|
||||
<tr><td>Ctrl+⯅</td><td>To previous block</td></tr>
|
||||
<tr><td>Ctrl+⯆</td><td>To next block</td></tr>
|
||||
<tr><td>Ctrl+<b>↑</b></td><td>To previous block</td></tr>
|
||||
<tr><td>Ctrl+<b>↓</b></td><td>To next block</td></tr>
|
||||
<tr><td>Ctrl+Y</td><td>One page up</td></tr>
|
||||
<tr><td>Ctrl+V</td><td>One page down</td></tr>
|
||||
<tr><td>Alt+\</td><td>To top of buffer</td></tr>
|
||||
@@ -95,10 +96,10 @@
|
||||
|
||||
<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>
|
||||
<tr><td>Alt+<b>↑</b></td><td>Scroll viewport up</td></tr>
|
||||
<tr><td>Alt+<b>↓</b></td><td>Scroll viewport down</td></tr>
|
||||
<tr><td>Alt+<</td><td>Switch to preceding buffer</td></tr>
|
||||
<tr><td>Alt+></td><td>Switch to succeeding buffer</td></tr>
|
||||
</tbody></table>
|
||||
|
||||
58
doc/faq.html
58
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>
|
||||
@@ -28,11 +31,12 @@
|
||||
<a href="#3.1">3.1. How do I install the RPM or DEB package?</a><br>
|
||||
<a href="#3.2">3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</a><br>
|
||||
<a href="#3.3">3.3. Why does everything go into /usr/local?</a><br>
|
||||
<a href="#3.5">3.5. nano should automatically run strip on the binary when installing it!</a><br>
|
||||
<a href="#3.6">3.6. How can I make the executable smaller? This is too bloated!</a><br>
|
||||
<a href="#3.7">3.7. Tell me more about this multibuffer stuff!</a><br>
|
||||
<a href="#3.8">3.8. Tell me more about this verbatim input stuff!</a><br>
|
||||
<a href="#3.9">3.9. How do I make a .nanorc file that nano will read when I start it?</a><br>
|
||||
<a href="#3.4">3.4. nano should automatically run strip on the binary when installing it!</a><br>
|
||||
<a href="#3.5">3.5. How can I make the executable smaller? This is too bloated!</a><br>
|
||||
<a href="#3.6">3.6. Tell me more about this multibuffer stuff!</a><br>
|
||||
<a href="#3.7">3.7. Tell me more about this verbatim input stuff!</a><br>
|
||||
<a href="#3.8">3.8. How do I make a .nanorc file that nano will read when I start it?</a><br>
|
||||
<a href="#3.9">3.9. Why does my self-compiled nano not read /etc/nanorc?</a><br>
|
||||
</p></blockquote>
|
||||
<h3><a href="#4">4. Running</a></h3>
|
||||
<blockquote><p>
|
||||
@@ -85,7 +89,7 @@
|
||||
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
|
||||
<blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program "establishes a full duplex terminal connection to a remote host", and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote>
|
||||
<h3><a name="1.4"></a>1.4. What is the current version of nano?</h3>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>4.6</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>4.9</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%">
|
||||
@@ -94,8 +98,8 @@
|
||||
<h3><a name="2.1"></a>2.1. Web sites that carry nano.</h3>
|
||||
<blockquote><p>The nano source tarballs can be downloaded from the following web sites:</p>
|
||||
<ul>
|
||||
<li><a href="https://nano-editor.org/dist/">https://nano-editor.org/dist/</a></li>
|
||||
<li><a href="https://ftp.gnu.org/gnu/nano/">https://ftp.gnu.org/gnu/nano/</a></li>
|
||||
<li><a href="https://nano-editor.org/dist/latest/">https://nano-editor.org/dist/latest/</a></li>
|
||||
<li><a href="https://ftpmirror.gnu.org/gnu/nano/">https://ftpmirror.gnu.org/gnu/nano/</a></li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<h3><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h3>
|
||||
@@ -133,10 +137,10 @@
|
||||
<h3><a name="3.3"></a>3.3. Why does everything go into /usr/local?</h3>
|
||||
<blockquote><p>Well, that's what the <b>configure</b> script defaults to. If you wish to change this, simply do this:</p>
|
||||
<p><b>./configure --prefix=/usr</b></p>
|
||||
<p>to put nano into /usr/bin when you run <b>make install</b>.</p></blockquote>
|
||||
<h3><a name="3.5"></a>3.5. nano should automatically run strip on the binary when installing it!</h3>
|
||||
<blockquote><p>Actually, it does, but you have to use <b>make install-strip</b>. The default make install does not, and will not, run strip automatically.</p></blockquote>
|
||||
<h3><a name="3.6"></a>3.6. How can I make the executable smaller? This is too bloated!</h3>
|
||||
<p>This will put nano into /usr/bin when you run <b>make install</b>.</p></blockquote>
|
||||
<h3><a name="3.4"></a>3.4. nano should automatically run strip on the binary when installing it!</h3>
|
||||
<blockquote><p>It does when you use <b>make install-strip</b>. The default <b>make install</b> does not, and will not, run strip automatically.</p></blockquote>
|
||||
<h3><a name="3.5"></a>3.5. How can I make the executable smaller? This is too bloated!</h3>
|
||||
<blockquote><p>Actually, there are several parts of the editor that can be disabled. You can pass arguments to the <b>configure</b> script that disable certain features. Here's a brief list:</p>
|
||||
<pre>
|
||||
<b>--disable-browser</b> Disable the built-in file browser
|
||||
@@ -156,26 +160,28 @@
|
||||
<b>--disable-tabcomp</b> Disable the tab-completion functions
|
||||
<b>--disable-wordcomp</b> Disable the word-completion function
|
||||
<b>--disable-wrapping</b> Disable all hard-wrapping of text</pre>
|
||||
<p>There's also the <b>--enable-tiny</b> option which disables everything above, as well as some larger chunks of the program (like the marker code that you use with Control-^ to select text). Also, if you know you aren't going to be using other languages, you can use <b>--disable-nls</b> to disable internationalization and save a few K to a few dozen K depending on whether you have locale support on your system. And finally, there's always good old <b>strip</b> to strip all debugging code and code that exists in libraries on your system.</p>
|
||||
<p>There's also the <b>--enable-tiny</b> option which disables everything above, as well as some larger chunks of the program (like the undo/redo code and the code for selecting text). Also, if you know you don't need other languages, you can use <b>--disable-nls</b> to disable internationalization and save a few kilobytes. And finally, there's always good old <b>strip</b> to remove all unneeded symbols.</p>
|
||||
</blockquote>
|
||||
<h3><a name="3.7"></a>3.7. Tell me more about this multibuffer stuff!</h3>
|
||||
<h3><a name="3.6"></a>3.6. Tell me more about this multibuffer stuff!</h3>
|
||||
<blockquote><p>To use multiple file buffers, you must not have configured nano with <b>--disable-multibuffer</b> nor with <b>--enable-tiny</b> (use <b>nano -V</b> to check the compilation options). Then when you want to insert a file into its own buffer instead of into the current file, just hit <b>Meta-F</b> after typing <b>^R</b>. If you always want files to be loaded into their own buffers, use the <b>-F</b> or <b>--multibuffer</b> flag when you invoke nano, or add <b>set multibuffer</b> to your .nanorc file.</p>
|
||||
<p>You can move between the buffers you have open with the <b>Meta-<</b> and <b>Meta-></b> keys, or more easily without holding Shift: <b>Meta-,</b> and <b>Meta-.</b> (clear as mud, right? =-). When you have more than one buffer open, the ^X shortcut will say "Close", instead of "Exit".</p></blockquote>
|
||||
<h3><a name="3.8"></a>3.8. Tell me more about this verbatim input stuff!</h3>
|
||||
<h3><a name="3.7"></a>3.7. Tell me more about this verbatim input stuff!</h3>
|
||||
<blockquote><p>When you want to insert a literal character into the file you're editing, such as a control character that nano usually treats as a command, first press <b>Meta-V</b> (if you're not at a prompt, you'll get the message "Verbatim Input" on the status bar), then press the key(s) that generate the character you want.</p>
|
||||
<p>Alternatively, if Unicode support is enabled (see section <a href="#5.3">5.3</a>), you can press <b>Meta-V</b> and then type a six-digit hexadecimal code (from 000000 to 10FFFF, case-insensitive), and the character with the corresponding value will be inserted. The status bar will change to "Unicode Input: ......" when you do this.</p></blockquote>
|
||||
<h3><a name="3.9"></a>3.9. How do I make a .nanorc file that will be read when I start nano?</h3>
|
||||
<blockquote><p>It's not hard at all! But, your nano must <b>not</b> have been compiled with <b>--disable-nanorc</b>. Then simply copy the <b>sample.nanorc</b> that came with the nano source or your nano package (most likely in /usr/doc/nano) to .nanorc in your home directory. If you didn't get one, the syntax of the file is simple. Flags are turned on and off by using the words <b>set</b> and <b>unset</b> plus the long option name for the feature. For example, "set nowrap" or "set smarthome".</p></blockquote>
|
||||
<h3><a name="3.8"></a>3.8. How do I make a .nanorc file that will be read when I start nano?</h3>
|
||||
<blockquote><p>It's not hard at all! Simply copy the <b>sample.nanorc</b> from the doc/ directory in the nano source package (or from /usr/doc/nano on your system) to <b>.nanorc</b> in your home directory, and then edit it. If you didn't get a sample nanorc, the syntax of the file is simple: features are turned on and off by using the words <b>set</b> and <b>unset</b> followed by the long option name of the feature (see <b>man nanorc</b> for the full list of options). For example, "set quickblank" or "set smarthome". Of course, for this to work, your nano must <b>not</b> have been compiled with <b>--disable-nanorc</b>.</p></blockquote>
|
||||
<h3><a name="3.9"></a>3.9. Why does my self-compiled nano not read /etc/nanorc?</h3>
|
||||
<blockquote><p>By default (see <a href="#3.3">3.3</a>), nano gets installed into /usr/local. This also means that, at startup, nano will read <b>/usr/local/etc/nanorc</b> instead of <b>/etc/nanorc</b>. You can make a symlink from the former to the latter if you want your self-compiled nano to read the same nanorc as the system-installed nano. Or you can configure your nano to overwrite the system nano (again, see <a href="#3.3">3.3</a>).</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="4"></a>4. Running</h1>
|
||||
<h3><a name="4.1"></a>4.1. How do I open a file with a name beginning with '+' from the command line?</h3>
|
||||
<blockquote><p>If a command-line option that begins with '+' is followed by another option, the former is always treated as a starting line and column number, and the latter is always treated as a filename. If a command-line option that begins with '+' isn't followed by another option, it's always treated as a filename. Examples:</p>
|
||||
<p>To open '+filename.txt' starting on line 1: <b>nano +filename.txt</b><br>
|
||||
<blockquote><p>If a command-line argument that begins with '+' is followed by another argument, the former is always treated as a starting line (plus column number), and the latter always as a filename. If a command-line argument that begins with '+' isn't followed by another argument, it's treated as a filename. Examples:</p>
|
||||
<p>To open '+filename.txt': <b>nano +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 10: <b>nano +10 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 1, column 20: <b>nano +,20 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 10, column 20: <b>nano +10,20 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 1 and 'filename.txt' starting on line 40 (if nano has been compiled with multibuffer support): <b>nano +1 +filename.txt +40 filename.txt</b></p></blockquote>
|
||||
To open '+filename.txt' starting on line 1 and 'filename.txt' starting on line 40: <b>nano +1 +filename.txt +40 filename.txt</b></p></blockquote>
|
||||
<h3><a name="4.2"></a>4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</h3>
|
||||
<blockquote><p>Try setting your $TERM variable to 'vt100'. nano doesn't yet support every term entry under the sun.</p>
|
||||
<p>Bourne shell users (bash and sh): <b>export TERM=vt100</b><br>
|
||||
@@ -187,9 +193,11 @@
|
||||
<h3><a name="4.5"></a>4.5. How do I select text for or paste text from the clipboard when nano's mouse support is turned on?</h3>
|
||||
<blockquote><p>Try holding down the Shift key and selecting or pasting the text as you normally would.</p></blockquote>
|
||||
<h3><a name="4.6"></a>4.6. When I paste text into a document, each line gets indented further than the last. Why? And how can I stop this?</h3>
|
||||
<blockquote><p>You have the <i>autoindent</i> feature turned on. Hit <b>Meta-I</b> to turn it off, paste your text, and then hit <b>Meta-I</b> again to turn it back on.</p></blockquote>
|
||||
<blockquote><p>You have the <i>autoindent</i> feature turned on. Hit <b>Meta-I</b> to turn it off, paste your text, and then hit <b>Meta-I</b> again to turn it back on.</p>
|
||||
<p><i>Update:</i> Since version 4.8, nano will suppress auto-indentation during a paste, so you no longer need to toggle it off and on manually.</p></blockquote>
|
||||
<h3><a name="4.7"></a>4.7. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</h3>
|
||||
<blockquote><p>When pasting from Windows, in some situations linefeeds are sent instead of carriage returns (Enters). And linefeeds are <b>^J</b>s, which make nano justify (rewrap) the current paragraph. To prevent these linefeeds from causing these unwanted justifications, add this line to your .nanorc on the remote Linux box: <b>unbind ^J main</b> or <b>bind ^J enter main</b>, depending on whether the paste contains CR + LF or only LF.</p></blockquote>
|
||||
<blockquote><p>When pasting from Windows, in some situations linefeeds are sent instead of carriage returns (Enters). And linefeeds are <b>^J</b>s, which make nano justify (rewrap) the current paragraph. To prevent these linefeeds from causing these unwanted justifications, add this line to your .nanorc on the remote Linux box: <b>unbind ^J main</b> or <b>bind ^J enter main</b>, depending on whether the paste contains CR + LF or only LF.</p>
|
||||
<p><i>Update:</i> Since version 4.8, nano will ignore linefeed characters in a paste, so you no longer need the above workaround.</p></blockquote>
|
||||
<h3><a name="4.8"></a>4.8. I've compiled nano with color support, but I don't see any color when I run it!</h3>
|
||||
<blockquote><p>If you want nano to actually use color, you have to specify the color configurations you want it to use in your .nanorc. Several example configurations are in the <b>syntax/</b> subdirectory of the nano source, which are normally installed to <b>/usr/local/share/nano/</b>. To enable all of them, uncomment the line <b># include "/usr/local/share/nano/*.nanorc"</b> in your nanorc. See also section <a href="#3.9">3.9</a>.</p></blockquote>
|
||||
<h3><a name="4.9"></a>4.9. How do I make nano my default editor (in Pine, mutt, etc.)?</h3>
|
||||
|
||||
47
doc/nano.1
47
doc/nano.1
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 4.6" "November 2019"
|
||||
.TH NANO 1 "version 4.9" "March 2020"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, inspired by Pico
|
||||
@@ -28,12 +28,18 @@ nano \- Nano's ANOther editor, inspired by Pico
|
||||
.BR nano " [" \fIoptions "] [[" + [ crCR ]( / | ? ) \fIstring "] " \fIfile ]...
|
||||
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
line by default. It further uses smooth scrolling by default, and by
|
||||
default includes the line below the title bar into the editing area.
|
||||
Since version 4.0, \fBnano\fR by default:
|
||||
.sp
|
||||
.RS 4
|
||||
\(bu does not automatically hard-wrap lines that become overlong,
|
||||
.br
|
||||
\(bu includes the line below the title bar in the editing area,
|
||||
.br
|
||||
\(bu does linewise (smooth) scrolling.
|
||||
.RE
|
||||
.sp
|
||||
If you want the old, Pico behavior back, you can use \fB\-\-breaklonglines\fR,
|
||||
\fB\-\-jumpyscrolling\fR, and \fB\-\-emptyline\fR (or \fB\-bje\fR for short).
|
||||
\fB\-\-emptyline\fR, and \fB\-\-jumpyscrolling\fR (or \fB\-bej\fR for short).
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBnano\fP is a small and friendly editor. It copies the look and feel
|
||||
@@ -44,6 +50,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
|
||||
@@ -105,7 +112,10 @@ numbered one every time a file is saved -- when backups are enabled (\fB\-B\fR).
|
||||
The uniquely numbered files are stored in the specified \fIdirectory\fR.
|
||||
.TP
|
||||
.BR \-D ", " \-\-boldtext
|
||||
Use bold text instead of reverse video text.
|
||||
For the interface, use bold instead of reverse video. This will be overridden
|
||||
by setting the options \fBtitlecolor\fP, \fBstatuscolor\fP, \fBkeycolor\fP,
|
||||
\fBfunctioncolor\fP, \fBnumbercolor\fP, and/or \fBselectedcolor\fP in your
|
||||
nanorc file. See \fBnanorc\fR(5).
|
||||
.TP
|
||||
.BR \-E ", " \-\-tabstospaces
|
||||
Convert typed tabs to spaces.
|
||||
@@ -225,6 +235,10 @@ system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
.BR \-e ", " \-\-emptyline
|
||||
Do not use the line below the title bar, leaving it entirely blank.
|
||||
.TP
|
||||
.BR \-f\ \fIfile ", " \-\-rcfile= \fIfile
|
||||
Read only this \fIfile\fR for setting nano's options, instead of reading
|
||||
both the system-wide and the user's nanorc files.
|
||||
.TP
|
||||
.BR \-g ", " \-\-showcursor
|
||||
Make the cursor visible in the file browser (putting it on the
|
||||
highlighted item) and in the help viewer. Useful for braille users
|
||||
@@ -267,8 +281,8 @@ Set the operating directory. This makes \fBnano\fP set up something
|
||||
similar to a chroot.
|
||||
.TP
|
||||
.BR \-p ", " \-\-preserve
|
||||
Preserve the XON and XOFF sequences (^Q and ^S) so they will be caught
|
||||
by the terminal.
|
||||
Preserve the XON and XOFF sequences (\fB^Q\fR and \fB^S\fR) so they
|
||||
will be caught by the terminal.
|
||||
.TP
|
||||
.BR \-r\ \fInumber ", " \-\-fill= \fInumber
|
||||
Set the target width for justifying and automatic hard-wrapping at this
|
||||
@@ -277,7 +291,7 @@ at the width of the screen minus \fInumber\fR columns, allowing the wrap
|
||||
point to vary along with the width of the screen if the screen is resized.
|
||||
The default value is \-8.
|
||||
.TP
|
||||
.B "\-s ""\fIprogram\fR [\fIarg\fR...]\fB""\fR, \fB\-\-speller=""\fIprogram\fR [\fIarg\fR...]\fB"""
|
||||
.B "\-s ""\fIprogram\fR [\fIargument \fR...]\fB""\fR, \fB\-\-speller=""\fIprogram\fR [\fIargument \fR...]\fB"""
|
||||
Use this command to perform spell checking and correcting, instead of
|
||||
using the built-in corrector that calls \fBhunspell\fR or GNU \fBspell\fR.
|
||||
.TP
|
||||
@@ -306,13 +320,14 @@ Don't show the two help lines at the bottom of the screen.
|
||||
.BR \-y ", " \-\-afterends
|
||||
Make Ctrl+Right stop at word ends instead of beginnings.
|
||||
.TP
|
||||
.BR \-z ", " \-\-suspend
|
||||
Enable the suspend ability.
|
||||
.BR \-z ", " \-\-suspendable
|
||||
Allow the user to suspend the editor (with \fB^Z\fR by default).
|
||||
.TP
|
||||
.BR \-$ ", " \-\-softwrap
|
||||
Enable 'soft wrapping'. This will make \fBnano\fP attempt to display the
|
||||
entire contents of any line, even if it is longer than the screen width, by
|
||||
continuing it over multiple screen lines. Since
|
||||
Display lines that exceed the screen's width over multiple screen lines.
|
||||
(You can make this soft-wrapping occur at whitespace instead of rudely at
|
||||
the screen's edge, by using also \fB\-\-atblanks\fR.)
|
||||
Since
|
||||
\&'$' normally refers to a variable in the Unix shell, you should specify
|
||||
this option last when using other options (e.g.\& 'nano \-wS$') or pass it
|
||||
separately (e.g.\& 'nano \-wS \-$').
|
||||
@@ -326,6 +341,8 @@ hard-wrapping of long lines, \fBM\-S\fR toggles soft-wrapping,
|
||||
See at the end of the \fB^G\fR help text for a complete list.
|
||||
|
||||
.SH FILES
|
||||
When \fB\-\-rcfile\fR is given, \fBnano\fR will read just the specified file
|
||||
for setting its options and syntaxes and key bindings. Without that option,
|
||||
\fBnano\fR will read two configuration files: first the system's
|
||||
\fInanorc\fR (if it exists), and then the user's \fInanorc\fR (if it
|
||||
exists), either \fI~/.nanorc\fR or \fI$XDG_CONFIG_HOME/nano/nanorc\fR
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 4.6
|
||||
@set UPDATED November 2019
|
||||
@set VERSION 4.9
|
||||
@set UPDATED March 2020
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 4.6
|
||||
@subtitle version 4.9
|
||||
|
||||
@author Chris Allegretta
|
||||
@page
|
||||
@@ -33,7 +33,7 @@ This manual documents the GNU @command{nano} editor.
|
||||
This manual is part of the GNU @command{nano} distribution.@*
|
||||
|
||||
@sp 4
|
||||
Copyright @copyright{} 1999-2009, 2014-2019 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1999-2009, 2014-2020 Free Software Foundation, Inc.
|
||||
|
||||
@sp 1
|
||||
This document is dual-licensed. You may distribute and/or modify it
|
||||
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
|
||||
@node Top
|
||||
@top
|
||||
|
||||
This manual documents the GNU @command{nano} editor, version 4.6.
|
||||
This manual documents the GNU @command{nano} editor, version 4.9.
|
||||
|
||||
@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
|
||||
@@ -185,7 +186,10 @@ The uniquely numbered files are stored in the specified directory.
|
||||
|
||||
@item -D
|
||||
@itemx --boldtext
|
||||
Use bold text instead of reverse video text.
|
||||
For the interface, use bold instead of reverse video. This will be overridden
|
||||
by setting the options @code{titlecolor}, @code{statuscolor}, @code{keycolor},
|
||||
@code{functioncolor}, @code{numbercolor}, and/or @code{selectedcolor} in your
|
||||
nanorc file. @xref{@code{set functioncolor}} for details.
|
||||
|
||||
@item -E
|
||||
@itemx --tabstospaces
|
||||
@@ -333,6 +337,11 @@ system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
@itemx --emptyline
|
||||
Do not use the line below the title bar, leaving it entirely blank.
|
||||
|
||||
@item -f @var{file}
|
||||
@itemx --rcfile=@var{file}
|
||||
Read only this @var{file} for setting nano's options, instead of reading
|
||||
both the system-wide and the user's nanorc files.
|
||||
|
||||
@item -g
|
||||
@itemx --showcursor
|
||||
Make the cursor visible in the file browser (putting it on the
|
||||
@@ -397,8 +406,8 @@ point to vary along with the width of the screen if the screen is resized.
|
||||
The default value is @t{-8}.
|
||||
|
||||
@anchor{@option{--speller}}
|
||||
@item -s "@var{program} [@var{arg} @dots{}]"
|
||||
@itemx --speller="@var{program} [@var{arg} @dots{}]"
|
||||
@item -s "@var{program} [@var{argument} @dots{}]"
|
||||
@itemx --speller="@var{program} [@var{argument} @dots{}]"
|
||||
Use the given program to do spell checking and correcting. By default,
|
||||
@command{nano} uses the command specified in the @env{SPELL} environment
|
||||
variable. If @env{SPELL} is not set, and @option{--speller} is
|
||||
@@ -433,7 +442,6 @@ This is the default. (This option is the opposite of @option{-b}
|
||||
(@option{--breaklonglines}) --- the last one given takes effect.)
|
||||
|
||||
|
||||
@anchor{Expert Mode}
|
||||
@item -x
|
||||
@itemx --nohelp
|
||||
Expert Mode: don't show the Shortcut List at the bottom of the screen.
|
||||
@@ -448,15 +456,16 @@ disabled to display the help-system navigation keys.
|
||||
Make Ctrl+Right stop at word ends instead of beginnings.
|
||||
|
||||
@item -z
|
||||
@itemx --suspend
|
||||
@itemx --suspendable
|
||||
Enable the ability to suspend @command{nano} using the system's suspend
|
||||
keystroke (usually @kbd{^Z}).
|
||||
|
||||
@item -$
|
||||
@itemx --softwrap
|
||||
Enable 'soft wrapping'. This will make @command{nano} attempt to display the
|
||||
entire contents of any line, even if it is longer than the screen width, by
|
||||
continuing it over multiple screen lines. Since
|
||||
Display lines that exceed the screen's width over multiple screen lines.
|
||||
(You can make this soft-wrapping occur at whitespace instead of rudely at
|
||||
the screen's edge, by using also @code{--atblanks}.)
|
||||
Since
|
||||
@code{$} normally refers to a variable in the Unix shell, you should specify
|
||||
this option last when using other options (e.g.@: @code{nano -wS$}) or pass it
|
||||
separately (e.g.@: @code{nano -wS -$}).
|
||||
@@ -674,7 +683,7 @@ The following global toggles are available:
|
||||
--- @pxref{Syntax Highlighting}).
|
||||
|
||||
@item Suspension
|
||||
@kbd{Meta-Z} toggles the @option{-z} (@option{--suspend}) command-line option.
|
||||
@kbd{Meta-Z} toggles the @option{-z} (@option{--suspendable}) command-line option.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -682,18 +691,21 @@ The following global toggles are available:
|
||||
@node Nanorc Files
|
||||
@chapter Nanorc Files
|
||||
|
||||
The nanorc files contain the default settings for @command{nano}. They
|
||||
should be in Unix format, not in DOS or Mac format. During startup,
|
||||
@command{nano} will first read the system-wide settings, from /etc/nanorc
|
||||
(the exact path might be different), and then the user-specific settings,
|
||||
The nanorc files contain the default settings for @command{nano}. During
|
||||
startup, if @option{--rcfile} is not given, @command{nano} will read two files:
|
||||
first the system-wide settings, from @file{/etc/nanorc} (the exact path
|
||||
might be different on your system), and then the user-specific settings,
|
||||
either from @file{~/.nanorc} or from @file{$XDG_CONFIG_HOME/nano/nanorc}
|
||||
or from @file{.config/nano/nanorc}, whichever exists first.
|
||||
If @option{--rcfile} is given, @command{nano} will read just the
|
||||
specified settings file.
|
||||
|
||||
A nanorc file accepts a series of "set" and "unset" commands, which can
|
||||
be used to configure @command{nano} on startup without using command-line
|
||||
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
|
||||
@@ -746,9 +758,9 @@ The uniquely numbered files are stored in the specified directory.
|
||||
|
||||
@item set boldtext
|
||||
Use bold instead of reverse video for the title bar, status bar, key combos,
|
||||
function tags, line numbers, and selected text. This can be overridden by
|
||||
function tags, line numbers, and selected text. This is overridden by
|
||||
setting the options @code{titlecolor}, @code{statuscolor}, @code{keycolor},
|
||||
@code{functioncolor}, @code{numbercolor}, and @code{selectedcolor}.
|
||||
@code{functioncolor}, @code{numbercolor}, and/or @code{selectedcolor}.
|
||||
|
||||
@item set brackets "@var{characters}"
|
||||
Set the characters treated as closing brackets when justifying
|
||||
@@ -923,9 +935,11 @@ Deprecated option since it has become the default setting.
|
||||
When needed, use @code{unset jumpyscrolling} instead.
|
||||
|
||||
@item set softwrap
|
||||
Enable soft line wrapping for easier viewing of very long lines.
|
||||
Display lines that exceed the screen's width over multiple screen lines.
|
||||
(You can make this soft-wrapping occur at whitespace instead of rudely at
|
||||
the screen's edge, by using also @code{set atblanks}.)
|
||||
|
||||
@item set speller "@var{program} [@var{arg} @dots{}]"
|
||||
@item set speller "@var{program} [@var{argument} @dots{}]"
|
||||
Use the given program to do spell checking and correcting.
|
||||
@xref{@option{--speller}} for details.
|
||||
|
||||
@@ -937,8 +951,8 @@ Use this color combination for the status bar.
|
||||
Use this color combination for the vertical guiding stripe.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set suspend
|
||||
Allow @command{nano} to be suspended.
|
||||
@item set suspendable
|
||||
Allow @command{nano} to be suspended (with @kbd{^Z} by default).
|
||||
|
||||
@item set tabsize @var{number}
|
||||
Use a tab size of @var{number} columns. The value of @var{number} must be
|
||||
@@ -1048,13 +1062,13 @@ file, to determine whether this syntax should be used for it.
|
||||
(This functionality only works when @code{libmagic} is installed
|
||||
on the system and will be silently ignored otherwise.)
|
||||
|
||||
@item formatter @var{program} [@var{arg} @dots{}]
|
||||
@item formatter @var{program} [@var{argument} @dots{}]
|
||||
Run the given @var{program} on the full contents of the current buffer.
|
||||
(The current buffer is written out to a temporary file, the program is
|
||||
run on it, and then the temporary file is read back in, replacing the
|
||||
contents of the buffer.)
|
||||
|
||||
@item linter @var{program} [@var{arg} @dots{}]
|
||||
@item linter @var{program} [@var{argument} @dots{}]
|
||||
Use the given @var{program} to do a syntax check on the current buffer.
|
||||
|
||||
@item comment "@var{string}"
|
||||
@@ -1107,10 +1121,11 @@ Read in self-contained color syntaxes from "syntaxfile". Note that
|
||||
"syntaxfile" may contain only the above commands, from @code{syntax}
|
||||
to @code{icolor}.
|
||||
|
||||
@item extendsyntax @var{name} @var{command} [@var{arg} @dots{}]
|
||||
@item extendsyntax @var{name} @var{command} @var{argument} @dots{}
|
||||
Extend the syntax previously defined as "@var{name}" with another @var{command}.
|
||||
This allows you to add a new @code{color}, @code{icolor}, @code{header},
|
||||
@code{magic}, @code{comment}, @code{linter}, or @code{formatter} command to an already
|
||||
@code{magic}, @code{formatter}, @code{linter}, @code{comment},
|
||||
or @code{tabgives} command to an already
|
||||
defined syntax --- useful when you want to slightly improve a syntax defined
|
||||
in one of the system-installed files (which normally are not writable).
|
||||
|
||||
@@ -1153,7 +1168,14 @@ Example: @code{^C}.
|
||||
@item
|
||||
@code{M-@var{X}} ------ where @var{X} is any ASCII character except [,
|
||||
or the word "Space".
|
||||
Example: @code{M-C}.
|
||||
Example: @code{M-8}.
|
||||
|
||||
@item
|
||||
@code{Sh-M-@var{X}} ------ where @var{X} is a Latin letter.
|
||||
Example: @code{Sh-M-U}.
|
||||
By default, each Meta+letter keystroke does the same as the corresponding
|
||||
Shift+Meta+letter. But when any Shift+Meta bind is made, that will
|
||||
no longer be the case, for all letters.
|
||||
|
||||
@item
|
||||
@code{F@var{n}} ------ where @var{n} is a numeric value from 1 to 24.
|
||||
@@ -1166,6 +1188,8 @@ with Shift.)
|
||||
@end itemize
|
||||
|
||||
Rebinding @code{^M} (Enter) or @code{^I} (Tab) is probably not a good idea.
|
||||
Rebinding @code{^[} (Esc) is not possible, because its keycode
|
||||
is the starter byte of escape sequences and Meta keystrokes.
|
||||
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.
|
||||
|
||||
@@ -1228,7 +1252,7 @@ Throws away the current line (or the marked region).
|
||||
Deletes from the cursor position to the beginning of the preceding word.
|
||||
(This function is bound by default to <Shift+Ctrl+Delete>. If your terminal
|
||||
produces @code{^H} for <Ctrl+Backspace>, you can make <Ctrl+Backspace> delete
|
||||
the word to the left of the cursor by rebinding ^H to this function.)
|
||||
the word to the left of the cursor by rebinding @kbd{^H} to this function.)
|
||||
|
||||
@item chopwordright
|
||||
Deletes from the cursor position to the beginning of the next word.
|
||||
@@ -1385,7 +1409,7 @@ Refreshes the screen.
|
||||
|
||||
@item suspend
|
||||
Suspends the editor (if the suspending function is enabled, see the
|
||||
"suspendenable" entry below).
|
||||
@code{suspendable} toggle item below).
|
||||
|
||||
@item casesens
|
||||
Toggles whether searching/replacing ignores or respects the case of
|
||||
@@ -1496,8 +1520,10 @@ Toggles whether typed tabs will be converted to spaces.
|
||||
@item mouse
|
||||
Toggles mouse support.
|
||||
|
||||
@item suspendenable
|
||||
Toggles whether the suspend shortcut (normally @kbd{^Z}) will suspend the editor.
|
||||
@item suspendable
|
||||
Toggles whether the suspend keystroke (@kbd{^Z} by default)
|
||||
will actually suspend the editor.
|
||||
(The old name of this function, 'suspendenable', is deprecated.)
|
||||
|
||||
@end table
|
||||
|
||||
@@ -1598,7 +1624,7 @@ whereas Pico does it at screen width minus six columns. You can make
|
||||
By default, @command{nano} will scroll just one line (instead of half
|
||||
a screen) when the cursor is moved to a line that is just out of view.
|
||||
And when paging up or down, @command{nano} keeps the cursor in the same
|
||||
screen position as much as possible, instead always placing it on the
|
||||
screen position as much as possible, instead of always placing it on the
|
||||
first line of the viewport. The Pico-like behavior can be obtained
|
||||
with the @option{--jumpyscrolling} option.
|
||||
|
||||
|
||||
81
doc/nanorc.5
81
doc/nanorc.5
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 2003-2011, 2013-2019 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 2003-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,27 +16,35 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 4.6" "November 2019"
|
||||
.TH NANORC 5 "version 4.9" "March 2020"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
line by default. It further uses smooth scrolling by default, and by
|
||||
default includes the line below the title bar into the editing area.
|
||||
.sp
|
||||
If you want the old, Pico behavior back, you can use \fBset breaklonglines\fR,
|
||||
\fBset jumpyscrolling\fR, and \fBset emptyline\fR.
|
||||
|
||||
.SH DESCRIPTION
|
||||
The \fInanorc\fP file contains the default settings for \fBnano\fP, a
|
||||
small and friendly editor. The file should be in Unix format, not in
|
||||
DOS or Mac format. During startup, \fBnano\fP will first read the
|
||||
The \fInanorc\fP files contain the default settings for \fBnano\fP,
|
||||
a small and friendly editor. During startup, if \fB\-\-rcfile\fR
|
||||
is not given, \fBnano\fR will read two files: first the
|
||||
system-wide settings, from \fI/etc/nanorc\fP (the exact path might be
|
||||
different on your system), and then the user-specific settings, either
|
||||
from \fI~/.nanorc\fR or from \fI$XDG_CONFIG_HOME/nano/nanorc\fR
|
||||
or from \fI~/.config/nano/nanorc\fR, whichever is encountered first.
|
||||
If \fB\-\-rcfile\fR is given, \fBnano\fR will read just the specified
|
||||
settings file.
|
||||
|
||||
.SH NOTICE
|
||||
Since version 4.0, \fBnano\fR by default:
|
||||
.sp
|
||||
.RS 4
|
||||
\(bu does not automatically hard-wrap lines that become overlong,
|
||||
.br
|
||||
\(bu includes the line below the title bar in the editing area,
|
||||
.br
|
||||
\(bu does linewise (smooth) scrolling.
|
||||
.RE
|
||||
.sp
|
||||
To get the old, Pico behavior back, you can use \fBset breaklonglines\fR,
|
||||
\fBset emptyline\fR, and \fBset jumpyscrolling\fR.
|
||||
|
||||
.SH OPTIONS
|
||||
The configuration file accepts a series of \fBset\fP and \fBunset\fP
|
||||
@@ -44,6 +52,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
|
||||
@@ -170,7 +179,7 @@ System, and on the console when gpm is running. Text can still be
|
||||
selected through dragging by holding down the Shift key.
|
||||
.TP
|
||||
.B set multibuffer
|
||||
When reading in a file with ^R, insert it into a new buffer by default.
|
||||
When reading in a file with \fB^R\fR, insert it into a new buffer by default.
|
||||
.TP
|
||||
.B set noconvert
|
||||
Don't convert files from DOS/Mac format.
|
||||
@@ -204,7 +213,7 @@ Save the cursor position of files between editing sessions.
|
||||
The cursor position is remembered for the 200 most-recently edited files.
|
||||
.TP
|
||||
.B set preserve
|
||||
Preserve the XON and XOFF keys (^Q and ^S).
|
||||
Preserve the XON and XOFF keys (\fB^Q\fR and \fB^S\fR).
|
||||
.TP
|
||||
.BI "set punct """ characters """
|
||||
Set the characters treated as closing punctuation when justifying
|
||||
@@ -258,9 +267,11 @@ Deprecated option since it has become the default setting.
|
||||
When needed, use \fBunset jumpyscrolling\fR instead.
|
||||
.TP
|
||||
.B set softwrap
|
||||
Enable soft line wrapping for easier viewing of very long lines.
|
||||
Display lines that exceed the screen's width over multiple screen lines.
|
||||
(You can make this soft-wrapping occur at whitespace instead of rudely at
|
||||
the screen's edge, by using also \fBset atblanks\fR.)
|
||||
.TP
|
||||
.B set speller """\fIprogram\fR [\fIarg\fR...]\fB"""
|
||||
.B set speller """\fIprogram\fR [\fIargument \fR...]\fB"""
|
||||
Use the given \fIprogram\fR to do spell checking and correcting, instead of
|
||||
using the built-in corrector that calls \fBhunspell\fR or GNU \fBspell\fR.
|
||||
.TP
|
||||
@@ -272,8 +283,8 @@ See \fBset titlecolor\fR for more details.
|
||||
Specify the color combination to use for the vertical guiding stripe.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.B set suspend
|
||||
Allow \fBnano\fP to be suspended.
|
||||
.B set suspendable
|
||||
Allow \fBnano\fP to be suspended (with \fB^Z\fR by default).
|
||||
.TP
|
||||
.B set tabsize \fInumber\fR
|
||||
Use a tab size of \fInumber\fR columns. The value of \fInumber\fP must be
|
||||
@@ -381,13 +392,13 @@ file, to determine whether this syntax should be used for it.
|
||||
(This functionality only works when \fBlibmagic\fP is installed on the
|
||||
system and will be silently ignored otherwise.)
|
||||
.TP
|
||||
.BI formatter " program " \fR[ "arg " \fR...]
|
||||
.BI formatter " program " \fR[ "argument " \fR...]
|
||||
Run the given \fIprogram\fR on the full contents of the current buffer.
|
||||
(The current buffer is written out to a temporary file, the program is
|
||||
run on it, and then the temporary file is read back in, replacing the
|
||||
contents of the buffer.)
|
||||
.TP
|
||||
.BI linter " program " \fR[ "arg " \fR...]
|
||||
.BI linter " program " \fR[ "argument " \fR...]
|
||||
Use the given \fIprogram\fR to run a syntax check on the current buffer.
|
||||
.TP
|
||||
.BI "comment """ string """
|
||||
@@ -440,10 +451,11 @@ Read in self-contained color syntaxes from \fIsyntaxfile\fP. Note that
|
||||
\fIsyntaxfile\fP may contain only the above commands, from \fBsyntax\fP
|
||||
to \fBicolor\fP.
|
||||
.TP
|
||||
.BI extendsyntax " name command " \fR[ "arg " \fR...]
|
||||
.BI extendsyntax " name command argument " \fR...
|
||||
Extend the syntax previously defined as \fIname\fR with another
|
||||
\fIcommand\fR. This allows adding a new \fBcolor\fP, \fBicolor\fP,
|
||||
\fBheader\fP, \fBmagic\fP, \fBcomment\fP, \fBlinter\fP, or \fBformatter\fR
|
||||
\fBheader\fR, \fBmagic\fR, \fBformatter\fR, \fBlinter\fR, \fBcomment\fR,
|
||||
or \fBtabgives\fR
|
||||
command to an already defined syntax -- useful when you want to
|
||||
slightly improve a syntax defined in one of the system-installed
|
||||
files (which normally are not writable).
|
||||
@@ -471,7 +483,7 @@ menus where the key exists when \fBall\fP is used).
|
||||
.TP
|
||||
The format of \fIkey\fP should be one of:
|
||||
.RS 3
|
||||
.TP 5
|
||||
.TP 7
|
||||
.BI ^ X
|
||||
where \fIX\fR is a Latin letter, or one of several ASCII characters
|
||||
(@, ], \\, ^, _), or the word "Space".
|
||||
@@ -479,7 +491,14 @@ Example: ^C.
|
||||
.TP
|
||||
.BI M\- X
|
||||
where \fIX\fR is any ASCII character except [, or the word "Space".
|
||||
Example: M\-C.
|
||||
Example: M\-8.
|
||||
.TP
|
||||
.BI Sh\-M\- X
|
||||
where \fIX\fR is a Latin letter.
|
||||
Example: Sh\-M\-U.
|
||||
By default, each Meta+letter keystroke does the same as the corresponding
|
||||
Shift+Meta+letter. But when any Shift+Meta bind is made, that will
|
||||
no longer be the case, for all letters.
|
||||
.TP
|
||||
.BI F N
|
||||
where \fIN\fR is a numeric value from 1 to 24.
|
||||
@@ -491,6 +510,8 @@ Example: F10.
|
||||
.RE
|
||||
|
||||
Rebinding \fB^M\fR (Enter) or \fB^I\fR (Tab) is probably not a good idea.
|
||||
Rebinding \fB^[\fR (Esc) is not possible, because its keycode
|
||||
is the starter byte of escape sequences and Meta keystrokes.
|
||||
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.
|
||||
|
||||
@@ -552,7 +573,7 @@ Throws away the current line (or the marked region).
|
||||
Deletes from the cursor position to the beginning of the preceding word.
|
||||
(This function is bound by default to <Shift+Ctrl+Delete>. If your terminal
|
||||
produces \fB^H\fR for <Ctrl+Backspace>, you can make <Ctrl+Backspace> delete
|
||||
the word to the left of the cursor by rebinding ^H to this function.)
|
||||
the word to the left of the cursor by rebinding \fB^H\fR to this function.)
|
||||
.TP
|
||||
.B chopwordright
|
||||
Deletes from the cursor position to the beginning of the next word.
|
||||
@@ -708,7 +729,7 @@ Refreshes the screen.
|
||||
.TP
|
||||
.B suspend
|
||||
Suspends the editor (if the suspending function is enabled, see the
|
||||
"suspendenable" entry below).
|
||||
\fBsuspendable\fR toggle item below).
|
||||
.TP
|
||||
.B casesens
|
||||
Toggles whether searching/replacing ignores or respects the case of
|
||||
@@ -819,8 +840,10 @@ Toggles whether typed tabs will be converted to spaces.
|
||||
.B mouse
|
||||
Toggles mouse support.
|
||||
.TP
|
||||
.B suspendenable
|
||||
Toggles whether the suspend sequence (normally ^Z) will suspend the editor window.
|
||||
.B suspendable
|
||||
Toggles whether the suspend keystroke (\fB^Z\fR by default)
|
||||
will actually suspend the editor.
|
||||
(The old name of this function, 'suspendenable', is deprecated.)
|
||||
.RE
|
||||
|
||||
.TP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 2002-2007, 2014-2019 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 2002-2007, 2014-2020 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 4.6" "November 2019"
|
||||
.TH RNANO 1 "version 4.9" "March 2020"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
## Sample initialization file for GNU nano.
|
||||
##
|
||||
## This file should not be in DOS or Mac format, and characters
|
||||
## specially interpreted by the shell should not be escaped here.
|
||||
##
|
||||
## To make sure an option is disabled, use "unset <option>".
|
||||
##
|
||||
## For the options that take parameters, the default value is given.
|
||||
## Other options are unset by default.
|
||||
##
|
||||
## Inside string parameters, quotes should not be escaped. The last
|
||||
## Characters that are special in a shell should not be escaped here.
|
||||
## Inside string parameters, quotes should not be escaped -- the last
|
||||
## double quote on the line will be seen as the closing quote.
|
||||
##
|
||||
## For the options that take parameters, the default value is shown.
|
||||
## Other options are unset by default. To make sure that an option
|
||||
## is disabled, you can use "unset <option>".
|
||||
|
||||
## Make the 'nextword' function (Ctrl+Right) stop at word ends
|
||||
## instead of at beginnings.
|
||||
@@ -54,9 +51,9 @@
|
||||
## Do not use the line below the title bar, leaving it entirely blank.
|
||||
# set emptyline
|
||||
|
||||
## Enable hard-wrapping and set the target width, both for automatic
|
||||
## line wrapping and for justifying paragraphs. If the value is 0 or
|
||||
## less, the wrapping point will be the screen width minus this number.
|
||||
## Set the target width for automatic hard-wrapping and for justifying
|
||||
## paragraphs. If the specified value is 0 or less, the wrapping point
|
||||
## will be the terminal's width minus this number.
|
||||
# set fill -8
|
||||
|
||||
## Remember the used search/replace strings for the next session.
|
||||
@@ -145,15 +142,16 @@
|
||||
## beginning of the line.
|
||||
# set smarthome
|
||||
|
||||
## Enable soft line wrapping (AKA full-line display).
|
||||
## Spread overlong lines over multiple screen lines.
|
||||
# set softwrap
|
||||
|
||||
## Use this spelling checker instead of the internal one. This option
|
||||
## does not have a default value.
|
||||
# set speller "aspell -x -c"
|
||||
|
||||
## Allow nano to be suspended.
|
||||
# set suspend
|
||||
## Allow nano to be suspended (with ^Z by default).
|
||||
# set suspendable
|
||||
## (The old form of this option, 'set suspend', is deprecated.)
|
||||
|
||||
## Use this tab size instead of the default; it must be greater than 0.
|
||||
# set tabsize 8
|
||||
@@ -268,6 +266,9 @@
|
||||
## such as ^O for Open, ^F for Find, ^H for Help, and ^Q for Quit,
|
||||
## then uncomment these:
|
||||
#bind ^Q exit all
|
||||
#bind ^S savefile main
|
||||
#bind ^W writeout main
|
||||
#bind ^O insert main
|
||||
#bind ^H help all
|
||||
#bind ^H exit help
|
||||
#bind ^F whereis all
|
||||
@@ -275,23 +276,23 @@
|
||||
#bind ^B wherewas all
|
||||
#bind ^D findprevious all
|
||||
#bind ^R replace main
|
||||
#bind ^W writeout main
|
||||
#bind ^O insert main
|
||||
#unbind ^V all
|
||||
#unbind ^Y all
|
||||
#bind M-X flipnewbuffer all
|
||||
#bind ^X cut all
|
||||
#bind ^C copy all
|
||||
#bind ^C copy main
|
||||
#bind ^V paste all
|
||||
#bind ^P curpos main
|
||||
#bind ^A mark main
|
||||
#unbind ^K main
|
||||
#unbind ^U all
|
||||
#unbind ^N main
|
||||
#unbind ^Y all
|
||||
#unbind M-J main
|
||||
#unbind M-T main
|
||||
#bind ^T gotoline main
|
||||
#bind ^T gotodir browser
|
||||
#bind ^Y speller main
|
||||
#unbind ^K all
|
||||
#unbind ^U all
|
||||
#bind M-U undo main
|
||||
#bind M-R redo main
|
||||
#bind ^U undo main
|
||||
#bind ^E redo main
|
||||
#unbind M-J main
|
||||
#unbind M-T main
|
||||
#set multibuffer
|
||||
|
||||
31
nano.spec.in
31
nano.spec.in
@@ -1,21 +1,21 @@
|
||||
%define name @PACKAGE@
|
||||
%define version @VERSION@
|
||||
%define release 1
|
||||
%define name @PACKAGE@
|
||||
%define version @VERSION@
|
||||
%define release 1
|
||||
|
||||
Name : %{name}
|
||||
Version : %{version}
|
||||
Release : %{release}
|
||||
Summary : a user-friendly editor, a Pico clone with enhancements
|
||||
Name : %{name}
|
||||
Version : %{version}
|
||||
Release : %{release}
|
||||
Summary : a user-friendly editor, a Pico clone with enhancements
|
||||
|
||||
License : GPLv3+
|
||||
Group : Applications/Editors
|
||||
URL : https://nano-editor.org/
|
||||
Source : https://nano-editor.org/dist/latest/%{name}-%{version}.tar.gz
|
||||
License : GPLv3+
|
||||
Group : Applications/Editors
|
||||
URL : https://nano-editor.org/
|
||||
Source : https://nano-editor.org/dist/latest/%{name}-%{version}.tar.gz
|
||||
|
||||
BuildRoot : %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires : autoconf, automake, gettext-devel, ncurses-devel, texinfo
|
||||
Requires(post) : info
|
||||
Requires(preun) : info
|
||||
BuildRoot : %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires : autoconf, automake, gettext-devel, ncurses-devel, texinfo
|
||||
Requires(post) : info
|
||||
Requires(preun) : info
|
||||
|
||||
%description
|
||||
GNU nano is a small and friendly text editor. It aims to emulate the
|
||||
@@ -47,7 +47,6 @@ fi
|
||||
%{_bindir}/*
|
||||
%{_docdir}/nano/*
|
||||
%{_mandir}/man*/*
|
||||
%{_mandir}/fr/man*/*
|
||||
%{_infodir}/nano.info*
|
||||
%{_datadir}/locale/*/LC_MESSAGES/nano.mo
|
||||
%{_datadir}/nano/*
|
||||
|
||||
1444
po/nano.pot
1444
po/nano.pot
File diff suppressed because it is too large
Load Diff
1398
po/pt_BR.po
1398
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1360
po/zh_CN.po
1360
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1356
po/zh_TW.po
1356
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION="4.6"
|
||||
VERSION="4.9"
|
||||
|
||||
./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 &&
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* browser.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2016 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -138,14 +138,20 @@ char *do_browser(char *path)
|
||||
/* If we selected the same filename as last time, fake a
|
||||
* press of the Enter key so that the file is read in. */
|
||||
if (old_selected == selected)
|
||||
unget_kbinput(KEY_ENTER, FALSE);
|
||||
kbinput = KEY_ENTER;
|
||||
}
|
||||
|
||||
continue;
|
||||
if (kbinput == KEY_MOUSE)
|
||||
continue;
|
||||
}
|
||||
#endif /* ENABLE_MOUSE */
|
||||
|
||||
func = parse_browser_input(&kbinput);
|
||||
#ifndef NANO_TINY
|
||||
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) {
|
||||
beep();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
func = interpret(&kbinput);
|
||||
|
||||
if (func == total_refresh) {
|
||||
total_redraw();
|
||||
@@ -153,9 +159,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;
|
||||
@@ -177,9 +183,9 @@ char *do_browser(char *path)
|
||||
} else if (func == do_right) {
|
||||
if (selected < filelist_len - 1)
|
||||
selected++;
|
||||
} else if (func == do_prev_word_void) {
|
||||
} else if (func == to_prev_word) {
|
||||
selected -= (selected % width);
|
||||
} else if (func == do_next_word_void) {
|
||||
} else if (func == to_next_word) {
|
||||
selected += width - 1 - (selected % width);
|
||||
if (selected >= filelist_len)
|
||||
selected = filelist_len - 1;
|
||||
@@ -189,10 +195,10 @@ char *do_browser(char *path)
|
||||
} else if (func == do_down) {
|
||||
if (selected + width <= filelist_len - 1)
|
||||
selected += width;
|
||||
} else if (func == do_prev_block) {
|
||||
} else if (func == to_prev_block) {
|
||||
selected = ((selected / (editwinrows * width)) *
|
||||
editwinrows * width) + selected % width;
|
||||
} else if (func == do_next_block) {
|
||||
} else if (func == to_next_block) {
|
||||
selected = ((selected / (editwinrows * width)) *
|
||||
editwinrows * width) + selected % width +
|
||||
editwinrows * width - width;
|
||||
@@ -219,7 +225,7 @@ char *do_browser(char *path)
|
||||
selected = 0;
|
||||
} else if (func == to_last_file) {
|
||||
selected = filelist_len - 1;
|
||||
} else if (func == goto_dir_void) {
|
||||
} else if (func == goto_dir) {
|
||||
/* Ask for the directory to go to. */
|
||||
if (do_prompt(TRUE, FALSE, MGOTODIR, "", NULL,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
@@ -447,49 +453,10 @@ void read_the_list(const char *path, DIR *dir)
|
||||
width = (COLS + 2) / (longest + 2);
|
||||
}
|
||||
|
||||
/* Return the function that is bound to the given key, accepting certain
|
||||
* plain characters too, for compatibility with Pico. */
|
||||
functionptrtype parse_browser_input(int *kbinput)
|
||||
{
|
||||
if (!meta_key) {
|
||||
switch (*kbinput) {
|
||||
case '-':
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
return do_page_down;
|
||||
case 'W':
|
||||
case 'w':
|
||||
case '/':
|
||||
return do_search_forward;
|
||||
case 'N':
|
||||
return do_findprevious;
|
||||
case 'n':
|
||||
return do_findnext;
|
||||
case 'G':
|
||||
case 'g':
|
||||
return goto_dir_void;
|
||||
case '?':
|
||||
return do_help_void;
|
||||
case 'S':
|
||||
case 's':
|
||||
return do_enter;
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'Q':
|
||||
case 'q':
|
||||
case 'X':
|
||||
case 'x':
|
||||
return do_exit;
|
||||
}
|
||||
}
|
||||
return func_from_key(kbinput);
|
||||
}
|
||||
|
||||
/* Set width to the number of files that we can display per screen row,
|
||||
* if necessary, and display the list of files. */
|
||||
void browser_refresh(void)
|
||||
{
|
||||
size_t i;
|
||||
int row = 0, col = 0;
|
||||
/* The current row and column while the list is getting displayed. */
|
||||
int the_row = 0, the_column = 0;
|
||||
@@ -502,11 +469,10 @@ void browser_refresh(void)
|
||||
|
||||
wmove(edit, 0, 0);
|
||||
|
||||
i = selected - selected % (editwinrows * width);
|
||||
|
||||
for (; i < filelist_len && row < editwinrows; i++) {
|
||||
for (size_t index = selected - selected % (editwinrows * width);
|
||||
index < filelist_len && row < editwinrows; index++) {
|
||||
struct stat st;
|
||||
const char *thename = tail(filelist[i]);
|
||||
const char *thename = tail(filelist[index]);
|
||||
/* The filename we display, minus the path. */
|
||||
size_t namelen = breadth(thename);
|
||||
/* The length of the filename in columns. */
|
||||
@@ -525,7 +491,7 @@ void browser_refresh(void)
|
||||
|
||||
/* If this is the selected item, draw its highlighted bar upfront, and
|
||||
* remember its location to be able to place the cursor on it. */
|
||||
if (i == selected) {
|
||||
if (index == selected) {
|
||||
wattron(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
mvwprintw(edit, row, col, "%*s", longest, " ");
|
||||
the_row = row;
|
||||
@@ -544,8 +510,8 @@ void browser_refresh(void)
|
||||
/* Show information about the file: "--" for symlinks (except when
|
||||
* they point to a directory) and for files that have disappeared,
|
||||
* "(dir)" for directories, and the file size for normal files. */
|
||||
if (lstat(filelist[i], &st) == -1 || S_ISLNK(st.st_mode)) {
|
||||
if (stat(filelist[i], &st) == -1 || !S_ISDIR(st.st_mode))
|
||||
if (lstat(filelist[index], &st) == -1 || S_ISLNK(st.st_mode)) {
|
||||
if (stat(filelist[index], &st) == -1 || !S_ISDIR(st.st_mode))
|
||||
info = copy_of("--");
|
||||
else
|
||||
/* TRANSLATORS: Try to keep this at most 7 characters. */
|
||||
@@ -596,7 +562,7 @@ void browser_refresh(void)
|
||||
mvwaddstr(edit, row, col - infolen, info);
|
||||
|
||||
/* If this is the selected item, finish its highlighting. */
|
||||
if (i == selected)
|
||||
if (index == selected)
|
||||
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
|
||||
free(info);
|
||||
|
||||
134
src/chars.c
134
src/chars.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* chars.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2018 Benno Schulenberg *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -44,118 +44,91 @@ bool using_utf8(void)
|
||||
}
|
||||
#endif /* ENABLE_UTF8 */
|
||||
|
||||
/* Concatenate two allocated strings, and free the second. */
|
||||
char *addstrings(char* str1, size_t len1, char* str2, size_t len2)
|
||||
{
|
||||
str1 = charealloc(str1, len1 + len2 + 1);
|
||||
str1[len1] = '\0';
|
||||
|
||||
strncat(&str1[len1], str2, len2);
|
||||
free(str2);
|
||||
|
||||
return str1;
|
||||
}
|
||||
|
||||
/* Return TRUE if the value of c is in byte range, and FALSE otherwise. */
|
||||
bool is_byte(int c)
|
||||
{
|
||||
return ((unsigned int)c == (unsigned char)c);
|
||||
}
|
||||
|
||||
/* This function is equivalent to isalpha() for multibyte characters. */
|
||||
bool is_alpha_mbchar(const char *c)
|
||||
#ifdef ENABLE_SPELLER
|
||||
/* Return TRUE when the given character is some kind of letter. */
|
||||
bool is_alpha_char(const char *c)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
wchar_t wc;
|
||||
wchar_t wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return FALSE;
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return FALSE;
|
||||
|
||||
return iswalpha(wc);
|
||||
} else
|
||||
return iswalpha(wc);
|
||||
#else
|
||||
return isalpha((unsigned char)*c);
|
||||
#endif
|
||||
return isalpha((unsigned char)*c);
|
||||
}
|
||||
#endif /* ENABLE_SPELLER */
|
||||
|
||||
/* This function is equivalent to isalnum() for multibyte characters. */
|
||||
bool is_alnum_mbchar(const char *c)
|
||||
/* Return TRUE when the given character is some kind of letter or a digit. */
|
||||
bool is_alnum_char(const char *c)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
wchar_t wc;
|
||||
wchar_t wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return FALSE;
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return FALSE;
|
||||
|
||||
return iswalnum(wc);
|
||||
} else
|
||||
return iswalnum(wc);
|
||||
#else
|
||||
return isalnum((unsigned char)*c);
|
||||
#endif
|
||||
return isalnum((unsigned char)*c);
|
||||
}
|
||||
|
||||
/* This function is equivalent to isblank() for multibyte characters. */
|
||||
bool is_blank_mbchar(const char *c)
|
||||
/* Return TRUE when the given character is space or tab or other whitespace. */
|
||||
bool is_blank_char(const char *c)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
wchar_t wc;
|
||||
wchar_t wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return FALSE;
|
||||
if ((signed char)*c >= 0)
|
||||
return (*c == ' ' || *c == '\t');
|
||||
|
||||
return iswblank(wc);
|
||||
} else
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return FALSE;
|
||||
|
||||
return iswblank(wc);
|
||||
#else
|
||||
return isblank((unsigned char)*c);
|
||||
#endif
|
||||
return isblank((unsigned char)*c);
|
||||
}
|
||||
|
||||
/* This function is equivalent to iscntrl(), except in that it only
|
||||
* handles non-high-bit control characters. */
|
||||
bool is_ascii_cntrl_char(int c)
|
||||
{
|
||||
return (0 <= c && c < 32);
|
||||
}
|
||||
|
||||
/* This function is equivalent to iscntrl() for multibyte characters,
|
||||
* except in that it also handles multibyte control characters with
|
||||
* their high bits set. */
|
||||
bool is_cntrl_mbchar(const char *c)
|
||||
/* Return TRUE when the given character is a control character. */
|
||||
bool is_cntrl_char(const char *c)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
return ((c[0] & 0xE0) == 0 || c[0] == 127 ||
|
||||
return ((c[0] & 0xE0) == 0 || c[0] == DEL_CODE ||
|
||||
((signed char)c[0] == -62 && (signed char)c[1] < -96));
|
||||
} else
|
||||
#endif
|
||||
return (((unsigned char)*c & 0x60) == 0 || (unsigned char)*c == 127);
|
||||
return ((*c & 0x60) == 0 || *c == DEL_CODE);
|
||||
}
|
||||
|
||||
/* This function is equivalent to ispunct() for multibyte characters. */
|
||||
bool is_punct_mbchar(const char *c)
|
||||
/* Return TRUE when the given character is a punctuation character. */
|
||||
bool is_punct_char(const char *c)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
wchar_t wc;
|
||||
wchar_t wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return FALSE;
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return FALSE;
|
||||
|
||||
return iswpunct(wc);
|
||||
} else
|
||||
return iswpunct(wc);
|
||||
#else
|
||||
return ispunct((unsigned char)*c);
|
||||
#endif
|
||||
return ispunct((unsigned char)*c);
|
||||
}
|
||||
|
||||
/* Return TRUE when the given multibyte character c is a word-forming
|
||||
* character (that is: alphanumeric, or specified in wordchars, or
|
||||
* punctuation when allow_punct is TRUE), and FALSE otherwise. */
|
||||
bool is_word_mbchar(const char *c, bool allow_punct)
|
||||
/* Return TRUE when the given character is word-forming (it is alphanumeric or
|
||||
* specified in 'wordchars', or it is punctuation when allow_punct is TRUE). */
|
||||
bool is_word_char(const char *c, bool allow_punct)
|
||||
{
|
||||
if (*c == '\0')
|
||||
return FALSE;
|
||||
|
||||
if (is_alnum_mbchar(c))
|
||||
if (is_alnum_char(c))
|
||||
return TRUE;
|
||||
|
||||
if (word_chars != NULL && *word_chars != '\0') {
|
||||
@@ -166,7 +139,7 @@ bool is_word_mbchar(const char *c, bool allow_punct)
|
||||
return (strstr(word_chars, symbol) != NULL);
|
||||
}
|
||||
|
||||
return (allow_punct && is_punct_mbchar(c));
|
||||
return (allow_punct && is_punct_char(c));
|
||||
}
|
||||
|
||||
/* Return the visible representation of control character c. */
|
||||
@@ -229,11 +202,10 @@ int mbwidth(const char *c)
|
||||
* allocated) multibyte character and a length of zero. */
|
||||
char *make_mbchar(long code, int *length)
|
||||
{
|
||||
char *mb_char;
|
||||
char *mb_char = charalloc(MAXCHARLEN);
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
mb_char = charalloc(MAXCHARLEN);
|
||||
*length = wctomb(mb_char, (wchar_t)code);
|
||||
|
||||
/* Reject invalid Unicode characters. */
|
||||
@@ -244,7 +216,7 @@ char *make_mbchar(long code, int *length)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
mb_char = measured_copy((char *)&code, 1);
|
||||
*mb_char = (char)code;
|
||||
*length = 1;
|
||||
}
|
||||
|
||||
@@ -319,7 +291,7 @@ int advance_over(const char *string, size_t *column)
|
||||
int charlen = mblen(string, MAXCHARLEN);
|
||||
|
||||
if (charlen > 0) {
|
||||
if (is_cntrl_mbchar(string))
|
||||
if (is_cntrl_char(string))
|
||||
*column += 2;
|
||||
else
|
||||
*column += mbwidth(string);
|
||||
@@ -612,7 +584,7 @@ bool has_blank_char(const char *string)
|
||||
while (*string != '\0') {
|
||||
string += collect_char(string, symbol);
|
||||
|
||||
if (is_blank_mbchar(symbol))
|
||||
if (is_blank_char(symbol))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -623,7 +595,7 @@ bool has_blank_char(const char *string)
|
||||
/* Return TRUE when the given string is empty or consists of only blanks. */
|
||||
bool white_string(const char *string)
|
||||
{
|
||||
while (*string != '\0' && (is_blank_mbchar(string) || *string == '\r'))
|
||||
while (*string != '\0' && (is_blank_char(string) || *string == '\r'))
|
||||
string += char_length(string);
|
||||
|
||||
return !*string;
|
||||
|
||||
94
src/color.c
94
src/color.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* color.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -40,13 +40,13 @@
|
||||
|
||||
/* Assign pair numbers for the colors in the given syntax, giving identical
|
||||
* color pairs the same number. */
|
||||
void set_syntax_colorpairs(syntaxtype *sint)
|
||||
void set_syntax_colorpairs(syntaxtype *sntx)
|
||||
{
|
||||
int new_number = NUMBER_OF_ELEMENTS + 1;
|
||||
colortype *ink;
|
||||
|
||||
for (ink = sint->color; ink != NULL; ink = ink->next) {
|
||||
const colortype *beforenow = sint->color;
|
||||
for (ink = sntx->color; ink != NULL; ink = ink->next) {
|
||||
const colortype *beforenow = sntx->color;
|
||||
|
||||
while (beforenow != ink && (beforenow->fg != ink->fg ||
|
||||
beforenow->bg != ink->bg))
|
||||
@@ -65,9 +65,7 @@ void set_syntax_colorpairs(syntaxtype *sint)
|
||||
* for the colors in each loaded syntax. */
|
||||
void set_colorpairs(void)
|
||||
{
|
||||
syntaxtype *sint;
|
||||
bool using_defaults = FALSE;
|
||||
size_t i;
|
||||
|
||||
/* Tell ncurses to enable colors. */
|
||||
start_color();
|
||||
@@ -78,36 +76,37 @@ void set_colorpairs(void)
|
||||
#endif
|
||||
|
||||
/* Initialize the color pairs for nano's interface elements. */
|
||||
for (i = 0; i < NUMBER_OF_ELEMENTS; i++) {
|
||||
colortype *combo = color_combo[i];
|
||||
for (size_t index = 0; index < NUMBER_OF_ELEMENTS; index++) {
|
||||
colortype *combo = color_combo[index];
|
||||
|
||||
if (combo != NULL) {
|
||||
if (combo->fg == USE_THE_DEFAULT && !using_defaults)
|
||||
combo->fg = COLOR_WHITE;
|
||||
if (combo->bg == USE_THE_DEFAULT && !using_defaults)
|
||||
combo->bg = COLOR_BLACK;
|
||||
init_pair(i + 1, combo->fg, combo->bg);
|
||||
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BANDAID |
|
||||
combo->attributes;
|
||||
init_pair(index + 1, combo->fg, combo->bg);
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1) | A_BANDAID |
|
||||
combo->attributes;
|
||||
} else {
|
||||
if (i == FUNCTION_TAG)
|
||||
interface_color_pair[i] = A_NORMAL;
|
||||
else if (i == GUIDE_STRIPE)
|
||||
interface_color_pair[i] = A_REVERSE;
|
||||
else if (i == ERROR_MESSAGE) {
|
||||
init_pair(i + 1, COLOR_WHITE, COLOR_RED);
|
||||
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BOLD | A_BANDAID;
|
||||
if (index == FUNCTION_TAG)
|
||||
interface_color_pair[index] = A_NORMAL;
|
||||
else if (index == GUIDE_STRIPE)
|
||||
interface_color_pair[index] = A_REVERSE;
|
||||
else if (index == ERROR_MESSAGE) {
|
||||
init_pair(index + 1, COLOR_WHITE, COLOR_RED);
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1) |
|
||||
A_BOLD | A_BANDAID;
|
||||
} else
|
||||
interface_color_pair[i] = hilite_attribute;
|
||||
interface_color_pair[index] = hilite_attribute;
|
||||
}
|
||||
|
||||
free(color_combo[i]);
|
||||
free(color_combo[index]);
|
||||
}
|
||||
|
||||
/* For each loaded syntax, assign pair numbers to color combinations. */
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next)
|
||||
if (sint->filename == NULL)
|
||||
set_syntax_colorpairs(sint);
|
||||
for (syntaxtype *sntx = syntaxes; sntx != NULL; sntx = sntx->next)
|
||||
if (sntx->filename == NULL)
|
||||
set_syntax_colorpairs(sntx);
|
||||
}
|
||||
|
||||
/* Initialize the color information. */
|
||||
@@ -167,7 +166,7 @@ bool found_in_list(regexlisttype *head, const char *shibboleth)
|
||||
/* Update the color information based on the current filename and content. */
|
||||
void color_update(void)
|
||||
{
|
||||
syntaxtype *sint = NULL;
|
||||
syntaxtype *sntx = NULL;
|
||||
|
||||
/* If the rcfiles were not read, or contained no syntaxes, get out. */
|
||||
if (syntaxes == NULL)
|
||||
@@ -179,42 +178,39 @@ void color_update(void)
|
||||
if (strcmp(syntaxstr, "none") == 0)
|
||||
return;
|
||||
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (strcmp(sint->name, syntaxstr) == 0)
|
||||
for (sntx = syntaxes; sntx != NULL; sntx = sntx->next)
|
||||
if (strcmp(sntx->name, syntaxstr) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (sint == NULL && !inhelp)
|
||||
if (sntx == NULL && !inhelp)
|
||||
statusline(ALERT, _("Unknown syntax name: %s"), syntaxstr);
|
||||
}
|
||||
|
||||
/* If no syntax-override string was specified, or it didn't match,
|
||||
* try finding a syntax based on the filename (extension). */
|
||||
if (sint == NULL && !inhelp) {
|
||||
if (sntx == NULL && !inhelp) {
|
||||
char *fullname = get_full_path(openfile->filename);
|
||||
|
||||
if (fullname == NULL)
|
||||
fullname = mallocstrcpy(fullname, openfile->filename);
|
||||
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (found_in_list(sint->extensions, fullname))
|
||||
for (sntx = syntaxes; sntx != NULL; sntx = sntx->next)
|
||||
if (found_in_list(sntx->extensions, fullname))
|
||||
break;
|
||||
}
|
||||
|
||||
free(fullname);
|
||||
}
|
||||
|
||||
/* If the filename didn't match anything, try the first line. */
|
||||
if (sint == NULL && !inhelp) {
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (found_in_list(sint->headers, openfile->filetop->data))
|
||||
if (sntx == NULL && !inhelp) {
|
||||
for (sntx = syntaxes; sntx != NULL; sntx = sntx->next)
|
||||
if (found_in_list(sntx->headers, openfile->filetop->data))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBMAGIC
|
||||
/* If we still don't have an answer, try using magic. */
|
||||
if (sint == NULL && !inhelp) {
|
||||
if (sntx == NULL && !inhelp) {
|
||||
struct stat fileinfo;
|
||||
magic_t cookie = NULL;
|
||||
const char *magicstring = NULL;
|
||||
@@ -238,10 +234,9 @@ void color_update(void)
|
||||
|
||||
/* Now try and find a syntax that matches the magic string. */
|
||||
if (magicstring != NULL) {
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (found_in_list(sint->magics, magicstring))
|
||||
for (sntx = syntaxes; sntx != NULL; sntx = sntx->next)
|
||||
if (found_in_list(sntx->magics, magicstring))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stat(openfile->filename, &fileinfo) == 0)
|
||||
@@ -250,21 +245,20 @@ void color_update(void)
|
||||
#endif /* HAVE_LIBMAGIC */
|
||||
|
||||
/* If nothing at all matched, see if there is a default syntax. */
|
||||
if (sint == NULL && !inhelp) {
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (strcmp(sint->name, "default") == 0)
|
||||
if (sntx == NULL && !inhelp) {
|
||||
for (sntx = syntaxes; sntx != NULL; sntx = sntx->next)
|
||||
if (strcmp(sntx->name, "default") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* When the syntax isn't loaded yet, parse it and initialize its colors. */
|
||||
if (sint != NULL && sint->filename != NULL) {
|
||||
parse_one_include(sint->filename, sint);
|
||||
set_syntax_colorpairs(sint);
|
||||
if (sntx != NULL && sntx->filename != NULL) {
|
||||
parse_one_include(sntx->filename, sntx);
|
||||
set_syntax_colorpairs(sntx);
|
||||
}
|
||||
|
||||
openfile->syntax = sint;
|
||||
openfile->colorstrings = (sint == NULL ? NULL : sint->color);
|
||||
openfile->syntax = sntx;
|
||||
openfile->colorstrings = (sntx == NULL ? NULL : sntx->color);
|
||||
}
|
||||
|
||||
/* Allocate and initialize (for the given line) the cache for multiline info. */
|
||||
@@ -272,7 +266,7 @@ void set_up_multicache(linestruct *line)
|
||||
{
|
||||
line->multidata = (short *)nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
|
||||
for (int index = 0; index < openfile->syntax->nmultis; index++)
|
||||
for (short index = 0; index < openfile->syntax->nmultis; index++)
|
||||
line->multidata[index] = -1;
|
||||
}
|
||||
|
||||
|
||||
235
src/cut.c
235
src/cut.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* cut.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014 Mark Majeres *
|
||||
* Copyright (C) 2016, 2018, 2019 Benno Schulenberg *
|
||||
* *
|
||||
@@ -41,7 +41,7 @@ void do_deletion(undo_type action)
|
||||
/* If the type of action changed or the cursor moved to a different
|
||||
* line, create a new undo item, otherwise update the existing item. */
|
||||
if (action != openfile->last_action ||
|
||||
openfile->current->lineno != openfile->current_undo->lineno)
|
||||
openfile->current->lineno != openfile->current_undo->head_lineno)
|
||||
add_undo(action, NULL);
|
||||
else
|
||||
update_undo(action);
|
||||
@@ -120,7 +120,7 @@ void do_delete(void)
|
||||
zap_text();
|
||||
else
|
||||
#endif
|
||||
do_deletion(DEL);
|
||||
do_deletion(DEL);
|
||||
}
|
||||
|
||||
/* Backspace over one character. That is, move the cursor left one
|
||||
@@ -132,12 +132,38 @@ void do_backspace(void)
|
||||
zap_text();
|
||||
else
|
||||
#endif
|
||||
if (openfile->current != openfile->filetop || openfile->current_x > 0) {
|
||||
if (openfile->current_x > 0 || openfile->current != openfile->filetop) {
|
||||
do_left();
|
||||
do_deletion(BACK);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return FALSE when a cut command would not actually cut anything: when
|
||||
* on an empty line at EOF, or when the mark covers zero characters, or
|
||||
* (when test_cliff is TRUE) when the magic line would be cut. */
|
||||
bool is_cuttable(bool test_cliff)
|
||||
{
|
||||
size_t from = (test_cliff) ? openfile->current_x : 0;
|
||||
|
||||
if ((openfile->current->next == NULL && openfile->current->data[from] == '\0'
|
||||
#ifndef NANO_TINY
|
||||
&& openfile->mark == NULL) ||
|
||||
(openfile->mark == openfile->current &&
|
||||
openfile->mark_x == openfile->current_x) ||
|
||||
(from > 0 && !ISSET(NO_NEWLINES) &&
|
||||
openfile->current->data[from] == '\0' &&
|
||||
openfile->current->next == openfile->filebot
|
||||
#endif
|
||||
)) {
|
||||
#ifndef NANO_TINY
|
||||
statusbar(_("Nothing was cut"));
|
||||
openfile->mark = NULL;
|
||||
#endif
|
||||
return FALSE;
|
||||
} else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Delete text from the cursor until the first start of a word to
|
||||
* the left, or to the right when forward is TRUE. */
|
||||
@@ -205,11 +231,167 @@ void chop_next_word(void)
|
||||
{
|
||||
openfile->mark = NULL;
|
||||
|
||||
if (is_cuttable(openfile->current_x > 0))
|
||||
if (is_cuttable(TRUE))
|
||||
chop_word(FORWARD);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Move all text between (top, top_x) and (bot, bot_x) from the current buffer
|
||||
* into the cutbuffer. */
|
||||
void extract_segment(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x)
|
||||
{
|
||||
bool edittop_inside = (openfile->edittop->lineno >= top->lineno &&
|
||||
openfile->edittop->lineno <= bot->lineno);
|
||||
#ifndef NANO_TINY
|
||||
bool mark_inside = (openfile->mark &&
|
||||
openfile->mark->lineno >= top->lineno &&
|
||||
openfile->mark->lineno <= bot->lineno &&
|
||||
(openfile->mark != top || openfile->mark_x >= top_x) &&
|
||||
(openfile->mark != bot || openfile->mark_x <= bot_x));
|
||||
bool same_line = (openfile->mark == top);
|
||||
|
||||
if (top == bot && top_x == bot_x)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Reduce the buffer to cover just the text that needs to be extracted. */
|
||||
partition_buffer(top, top_x, bot, bot_x);
|
||||
|
||||
/* Subtract the number of characters in that text from the file size. */
|
||||
openfile->totsize -= get_totsize(top, bot);
|
||||
|
||||
/* If the cutbuffer is currently empty, just move all the text directly
|
||||
* into it; otherwise, append the text to what is already there. */
|
||||
if (cutbuffer == NULL) {
|
||||
cutbuffer = openfile->filetop;
|
||||
cutbottom = openfile->filebot;
|
||||
} else {
|
||||
/* Tack the data of the first line of the text onto the data of
|
||||
* the last line in the given buffer. */
|
||||
cutbottom->data = charealloc(cutbottom->data,
|
||||
strlen(cutbottom->data) +
|
||||
strlen(openfile->filetop->data) + 1);
|
||||
strcat(cutbottom->data, openfile->filetop->data);
|
||||
|
||||
/* Attach the second line of the text (if any) to the last line
|
||||
* of the buffer, then remove the now superfluous first line. */
|
||||
cutbottom->next = openfile->filetop->next;
|
||||
delete_node(openfile->filetop);
|
||||
|
||||
/* If there is a second line, make the reverse attachment too and
|
||||
* update the buffer pointer to point at the end of the text. */
|
||||
if (cutbottom->next != NULL) {
|
||||
cutbottom->next->prev = cutbottom;
|
||||
cutbottom = openfile->filebot;
|
||||
}
|
||||
}
|
||||
|
||||
/* Since the text has now been saved, remove it from the file buffer. */
|
||||
openfile->filetop = make_new_node(NULL);
|
||||
openfile->filetop->data = copy_of("");
|
||||
openfile->filebot = openfile->filetop;
|
||||
|
||||
/* Set the cursor at the point where the text was removed. */
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = top_x;
|
||||
#ifndef NANO_TINY
|
||||
/* If the mark was inside the partition, put it where the cursor now is. */
|
||||
if (mark_inside) {
|
||||
openfile->mark = openfile->current;
|
||||
openfile->mark_x = openfile->current_x;
|
||||
} else if (same_line)
|
||||
/* Update the pointer to this partially cut line. */
|
||||
openfile->mark = openfile->current;
|
||||
#endif
|
||||
|
||||
/* Glue the texts before and after the extraction together. */
|
||||
unpartition_buffer();
|
||||
|
||||
renumber_from(openfile->current);
|
||||
|
||||
/* If the top of the edit window was inside the old partition, put
|
||||
* it in range of current. */
|
||||
if (edittop_inside) {
|
||||
adjust_viewport(STATIONARY);
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* If the text doesn't end with a newline, and it should, add one. */
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
}
|
||||
|
||||
/* Meld the buffer that starts at topline into the current file buffer
|
||||
* at the current cursor position. */
|
||||
void ingraft_buffer(linestruct *topline)
|
||||
{
|
||||
size_t current_x_save = openfile->current_x;
|
||||
/* Remember whether the current line is at the top of the edit window. */
|
||||
bool edittop_inside = (openfile->edittop == openfile->current);
|
||||
#ifndef NANO_TINY
|
||||
/* Remember whether mark and cursor are on the same line, and their order. */
|
||||
bool right_side_up = (openfile->mark && mark_is_before_cursor());
|
||||
bool same_line = (openfile->mark == openfile->current);
|
||||
#endif
|
||||
|
||||
/* Partition the buffer so that it contains no text, then delete it.*/
|
||||
partition_buffer(openfile->current, openfile->current_x,
|
||||
openfile->current, openfile->current_x);
|
||||
delete_node(openfile->filetop);
|
||||
|
||||
/* Replace the current buffer with the passed buffer. */
|
||||
openfile->filetop = topline;
|
||||
openfile->filebot = topline;
|
||||
while (openfile->filebot->next != NULL)
|
||||
openfile->filebot = openfile->filebot->next;
|
||||
|
||||
/* Put the cursor at the end of the pasted text. */
|
||||
openfile->current = openfile->filebot;
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
|
||||
/* When the pasted stuff contains no newline, adjust the cursor's
|
||||
* x coordinate for the text that is before the pasted stuff. */
|
||||
if (openfile->filetop == openfile->filebot)
|
||||
openfile->current_x += current_x_save;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When needed, refresh the mark's pointer and compensate the mark's
|
||||
* x coordinate for the change in the current line. */
|
||||
if (same_line) {
|
||||
if (!right_side_up) {
|
||||
openfile->mark = openfile->filebot;
|
||||
openfile->mark_x += openfile->current_x - current_x_save;
|
||||
} else
|
||||
openfile->mark = openfile->filetop;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add the number of characters in the copied text to the file size. */
|
||||
openfile->totsize += get_totsize(openfile->filetop, openfile->filebot);
|
||||
|
||||
/* If we pasted onto the first line of the edit window, the corresponding
|
||||
* record has been freed, so... point at the start of the copied text. */
|
||||
if (edittop_inside)
|
||||
openfile->edittop = openfile->filetop;
|
||||
|
||||
/* Weld the pasted text into the surrounding content of the buffer. */
|
||||
unpartition_buffer();
|
||||
|
||||
renumber_from(topline);
|
||||
|
||||
/* If the text doesn't end with a newline, and it should, add one. */
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
}
|
||||
|
||||
/* Meld a copy of the given buffer into the current file buffer. */
|
||||
void copy_from_buffer(linestruct *somebuffer)
|
||||
{
|
||||
linestruct *the_copy = copy_buffer(somebuffer);
|
||||
|
||||
ingraft_buffer(the_copy);
|
||||
}
|
||||
|
||||
/* Move the whole current line from the current buffer to the cutbuffer. */
|
||||
void cut_line(void)
|
||||
{
|
||||
@@ -217,9 +399,9 @@ void cut_line(void)
|
||||
* head of this line to the head of the next line into the cutbuffer;
|
||||
* otherwise, move all of the text of this line into the cutbuffer. */
|
||||
if (openfile->current != openfile->filebot)
|
||||
extract(openfile->current, 0, openfile->current->next, 0);
|
||||
extract_segment(openfile->current, 0, openfile->current->next, 0);
|
||||
else
|
||||
extract(openfile->current, 0,
|
||||
extract_segment(openfile->current, 0,
|
||||
openfile->current, strlen(openfile->current->data));
|
||||
|
||||
openfile->placewewant = 0;
|
||||
@@ -237,10 +419,10 @@ void cut_to_eol(void)
|
||||
* the cutbuffer. Otherwise, when not at the end of the buffer,
|
||||
* move the line separation into the cutbuffer. */
|
||||
if (openfile->current_x < data_len)
|
||||
extract(openfile->current, openfile->current_x,
|
||||
extract_segment(openfile->current, openfile->current_x,
|
||||
openfile->current, data_len);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
extract(openfile->current, openfile->current_x,
|
||||
extract_segment(openfile->current, openfile->current_x,
|
||||
openfile->current->next, 0);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
@@ -255,7 +437,7 @@ void cut_marked(bool *right_side_up)
|
||||
get_region((const linestruct **)&top, &top_x,
|
||||
(const linestruct **)&bot, &bot_x, right_side_up);
|
||||
|
||||
extract(top, top_x, bot, bot_x);
|
||||
extract_segment(top, top_x, bot, bot_x);
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
@@ -263,7 +445,7 @@ void cut_marked(bool *right_side_up)
|
||||
/* Move all text from the cursor position to end-of-file into the cutbuffer. */
|
||||
void cut_to_eof(void)
|
||||
{
|
||||
extract(openfile->current, openfile->current_x,
|
||||
extract_segment(openfile->current, openfile->current_x,
|
||||
openfile->filebot, strlen(openfile->filebot->data));
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
@@ -350,30 +532,6 @@ void do_snip(bool copying, bool marked, bool until_eof, bool append)
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* Return FALSE when a cut command would not actually cut anything: when
|
||||
* on an empty line at EOF, or when the mark covers zero characters, or
|
||||
* (when test_cliff is TRUE) when the magic line would be cut. */
|
||||
bool is_cuttable(bool test_cliff)
|
||||
{
|
||||
if ((openfile->current->next == NULL && openfile->current->data[0] == '\0'
|
||||
#ifndef NANO_TINY
|
||||
&& openfile->mark == NULL) ||
|
||||
(openfile->mark == openfile->current &&
|
||||
openfile->mark_x == openfile->current_x) ||
|
||||
(test_cliff && openfile->current->data[openfile->current_x] == '\0' &&
|
||||
((ISSET(NO_NEWLINES) && openfile->current == openfile->filebot) ||
|
||||
(!ISSET(NO_NEWLINES) && openfile->current == openfile->filebot->prev))
|
||||
#endif
|
||||
)) {
|
||||
#ifndef NANO_TINY
|
||||
openfile->mark = NULL;
|
||||
#endif
|
||||
statusbar(_("Nothing was cut"));
|
||||
return FALSE;
|
||||
} else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Move text from the current buffer into the cutbuffer. */
|
||||
void cut_text(void)
|
||||
{
|
||||
@@ -429,9 +587,10 @@ void copy_text(void)
|
||||
/* Cut from the current cursor position to the end of the file. */
|
||||
void cut_till_eof(void)
|
||||
{
|
||||
if ((openfile->current == openfile->filebot && openfile->current->data[0] == '\0') ||
|
||||
(!ISSET(NO_NEWLINES) && openfile->current->next == openfile->filebot &&
|
||||
openfile->current->data[openfile->current_x] == '\0')) {
|
||||
if (openfile->current->data[openfile->current_x] == '\0' &&
|
||||
(openfile->current->next == NULL ||
|
||||
(!ISSET(NO_NEWLINES) && openfile->current_x > 0 &&
|
||||
openfile->current->next == openfile->filebot))) {
|
||||
statusbar(_("Nothing was cut"));
|
||||
return;
|
||||
}
|
||||
|
||||
678
src/files.c
678
src/files.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* files.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2019 Benno Schulenberg *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -29,35 +29,12 @@
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#define LOCKBUFSIZE 8192
|
||||
|
||||
/* Verify that the containing directory of the given filename exists. */
|
||||
bool has_valid_path(const char *filename)
|
||||
{
|
||||
char *namecopy = copy_of(filename);
|
||||
char *parentdir = dirname(namecopy);
|
||||
struct stat parentinfo;
|
||||
bool validity = FALSE;
|
||||
|
||||
if (stat(parentdir, &parentinfo) == -1) {
|
||||
if (errno == ENOENT)
|
||||
statusline(ALERT, _("Directory '%s' does not exist"), parentdir);
|
||||
else
|
||||
statusline(ALERT, _("Path '%s': %s"), parentdir, strerror(errno));
|
||||
} else if (!S_ISDIR(parentinfo.st_mode))
|
||||
statusline(ALERT, _("Path '%s' is not a directory"), parentdir);
|
||||
else if (access(parentdir, X_OK) == -1)
|
||||
statusline(ALERT, _("Path '%s' is not accessible"), parentdir);
|
||||
else if (ISSET(LOCKING) && access(parentdir, W_OK) == -1)
|
||||
statusline(MILD, _("Directory '%s' is not writable"), parentdir);
|
||||
else
|
||||
validity = TRUE;
|
||||
|
||||
free(namecopy);
|
||||
|
||||
return validity;
|
||||
}
|
||||
#ifndef NANO_TINY
|
||||
static pid_t pid_of_command = -1;
|
||||
/* The PID of a forked process -- needed when wanting to abort it. */
|
||||
#endif
|
||||
|
||||
/* Add an item to the circular list of openfile structs. */
|
||||
void make_new_buffer(void)
|
||||
@@ -124,77 +101,54 @@ void make_new_buffer(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Mark the current file as modified if it isn't already, and then
|
||||
* update the titlebar to display the file's new status. */
|
||||
void set_modified(void)
|
||||
{
|
||||
if (openfile->modified)
|
||||
return;
|
||||
|
||||
openfile->modified = TRUE;
|
||||
titlebar(NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (!ISSET(LOCKING) || openfile->filename[0] == '\0')
|
||||
return;
|
||||
|
||||
if (openfile->lock_filename != NULL) {
|
||||
char *fullname = get_full_path(openfile->filename);
|
||||
|
||||
write_lockfile(openfile->lock_filename, fullname, TRUE);
|
||||
free(fullname);
|
||||
}
|
||||
#endif
|
||||
/* Delete the lockfile. Return TRUE on success, and FALSE otherwise. */
|
||||
bool delete_lockfile(const char *lockfilename)
|
||||
{
|
||||
if (unlink(lockfilename) < 0 && errno != ENOENT) {
|
||||
statusline(MILD, _("Error deleting lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
return FALSE;
|
||||
} else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Actually write the lockfile. This function will ALWAYS annihilate
|
||||
* any previous version of the file. We'll borrow INSECURE_BACKUP here
|
||||
* to decide about lockfile paranoia here as well...
|
||||
*
|
||||
* Args:
|
||||
* lockfilename: file name for lock
|
||||
* origfilename: name of the file the lock is for
|
||||
* modified: whether to set the modified bit in the file
|
||||
*
|
||||
* Returns 1 on success, and 0 on failure (but continue anyway). */
|
||||
int write_lockfile(const char *lockfilename, const char *origfilename, bool modified)
|
||||
#define LOCKSIZE 1024
|
||||
#define SKIPTHISFILE (char *)-1
|
||||
const char *locking_prefix = ".";
|
||||
const char *locking_suffix = ".swp";
|
||||
|
||||
/* Write a lock file, under the given lockfilename. This always annihilates an
|
||||
* existing version of that file. Return TRUE on success; FALSE otherwise. */
|
||||
bool write_lockfile(const char *lockfilename, const char *filename, bool modified)
|
||||
{
|
||||
#ifdef HAVE_PWD_H
|
||||
pid_t mypid = getpid();
|
||||
uid_t myuid = geteuid();
|
||||
struct passwd *mypwuid = getpwuid(myuid);
|
||||
char myhostname[32];
|
||||
struct stat fileinfo;
|
||||
int cflags, fd;
|
||||
FILE *filestream;
|
||||
pid_t mypid;
|
||||
uid_t myuid;
|
||||
struct passwd *mypwuid;
|
||||
struct stat fileinfo;
|
||||
char *lockdata = charalloc(1024);
|
||||
char myhostname[32];
|
||||
size_t lockdatalen = 1024;
|
||||
char *lockdata;
|
||||
size_t wroteamt;
|
||||
|
||||
mypid = getpid();
|
||||
myuid = geteuid();
|
||||
|
||||
/* First run things that might fail before blowing away the old state. */
|
||||
if ((mypwuid = getpwuid(myuid)) == NULL) {
|
||||
if (mypwuid == NULL) {
|
||||
/* TRANSLATORS: Keep the next eight messages at most 76 characters. */
|
||||
statusline(MILD, _("Couldn't determine my identity for lock file"));
|
||||
goto free_the_data;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gethostname(myhostname, 31) < 0) {
|
||||
if (errno == ENAMETOOLONG)
|
||||
myhostname[31] = '\0';
|
||||
else {
|
||||
statusline(MILD, _("Couldn't determine hostname: %s"), strerror(errno));
|
||||
goto free_the_data;
|
||||
}
|
||||
}
|
||||
if (gethostname(myhostname, 31) < 0 && errno != ENAMETOOLONG) {
|
||||
statusline(MILD, _("Couldn't determine hostname: %s"), strerror(errno));
|
||||
return FALSE;
|
||||
} else
|
||||
myhostname[31] = '\0';
|
||||
|
||||
/* If the lockfile exists, try to delete it. */
|
||||
if (stat(lockfilename, &fileinfo) != -1)
|
||||
if (delete_lockfile(lockfilename) < 0)
|
||||
goto free_the_data;
|
||||
if (!delete_lockfile(lockfilename))
|
||||
return FALSE;
|
||||
|
||||
if (ISSET(INSECURE_BACKUP))
|
||||
cflags = O_WRONLY | O_CREAT | O_APPEND;
|
||||
@@ -204,138 +158,120 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
/* Try to create the lockfile. */
|
||||
fd = open(lockfilename, cflags,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
|
||||
if (fd < 0) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
goto free_the_data;
|
||||
lockfilename, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Try to associate a stream with the now open lockfile. */
|
||||
filestream = fdopen(fd, "wb");
|
||||
|
||||
if (filestream == NULL) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"), lockfilename,
|
||||
strerror(errno));
|
||||
goto free_the_data;
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This is the lock data we will store:
|
||||
lockdata = charalloc(LOCKSIZE);
|
||||
memset(lockdata, 0, LOCKSIZE);
|
||||
|
||||
/* This is the lock data we will store (other bytes remain 0x00):
|
||||
*
|
||||
* byte 0 - 0x62
|
||||
* byte 1 - 0x30
|
||||
* bytes 2-12 - program name which created the lock
|
||||
* bytes 24-27 - PID (little endian) of creator process
|
||||
* bytes 28-44 - username of who created the lock
|
||||
* bytes 68-100 - hostname of where the lock was created
|
||||
* bytes 108-876 - filename the lock is for
|
||||
* byte 1007 - 0x55 if file is modified
|
||||
* bytes 0-1 - 0x62 0x30
|
||||
* bytes 2-11 - name of program that created the lock
|
||||
* bytes 24-27 - PID (little endian) of creator process
|
||||
* bytes 28-43 - username of the user who created the lock
|
||||
* bytes 68-99 - hostname of machine from where the lock was created
|
||||
* bytes 108-876 - filename that the lock is for
|
||||
* byte 1007 - 0x55 if file is modified
|
||||
*
|
||||
* Looks like VIM also stores undo state in this file, so we're
|
||||
* gonna have to figure out how to slap a 'OMG don't use recover on
|
||||
* our lockfile' message in here...
|
||||
*
|
||||
* This is likely very wrong, so this is a WIP. */
|
||||
memset(lockdata, 0, lockdatalen);
|
||||
* Nano does not write the page size (bytes 12-15), nor the modification
|
||||
* time (bytes 16-19), nor the inode of the relevant file (bytes 20-23).
|
||||
* Nano also does not use all available space for user name (40 bytes),
|
||||
* host name (40 bytes), and file name (890 bytes). Nor does nano write
|
||||
* some byte-order-checking numbers (bytes 1008-1022). */
|
||||
lockdata[0] = 0x62;
|
||||
lockdata[1] = 0x30;
|
||||
snprintf(&lockdata[2], 10, "nano %s", VERSION);
|
||||
lockdata[24] = mypid % 256;
|
||||
lockdata[25] = (mypid / 256) % 256;
|
||||
lockdata[26] = (mypid / (256 * 256)) % 256;
|
||||
lockdata[27] = mypid / (256 * 256 * 256);
|
||||
snprintf(&lockdata[2], 11, "nano %s", VERSION);
|
||||
strncpy(&lockdata[28], mypwuid->pw_name, 16);
|
||||
strncpy(&lockdata[68], myhostname, 31);
|
||||
if (origfilename != NULL)
|
||||
strncpy(&lockdata[108], origfilename, 768);
|
||||
if (modified == TRUE)
|
||||
lockdata[1007] = 0x55;
|
||||
strncpy(&lockdata[68], myhostname, 32);
|
||||
strncpy(&lockdata[108], filename, 768);
|
||||
lockdata[1007] = (modified) ? 0x55 : 0x00;
|
||||
|
||||
wroteamt = fwrite(lockdata, sizeof(char), lockdatalen, filestream);
|
||||
if (wroteamt < lockdatalen) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, ferror(filestream));
|
||||
fclose(filestream);
|
||||
goto free_the_data;
|
||||
}
|
||||
|
||||
if (fclose(filestream) == EOF) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
goto free_the_data;
|
||||
}
|
||||
|
||||
openfile->lock_filename = (char *)lockfilename;
|
||||
wroteamt = fwrite(lockdata, sizeof(char), LOCKSIZE, filestream);
|
||||
|
||||
free(lockdata);
|
||||
return 1;
|
||||
|
||||
free_the_data:
|
||||
free(lockdata);
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
if (fclose(filestream) == EOF || wroteamt < LOCKSIZE) {
|
||||
statusline(MILD, _("Error writing lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Delete the lockfile. Return -1 if unsuccessful, and 1 otherwise. */
|
||||
int delete_lockfile(const char *lockfilename)
|
||||
{
|
||||
if (unlink(lockfilename) < 0 && errno != ENOENT) {
|
||||
statusline(MILD, _("Error deleting lock file %s: %s"), lockfilename,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Deal with lockfiles. Return -1 on refusing to override the lockfile,
|
||||
* and 1 on successfully creating it; 0 means we were not successful in
|
||||
* creating the lockfile but we should continue to load the file. */
|
||||
int do_lockfile(const char *filename)
|
||||
/* First check if a lock file already exists. If so, and ask_the_user is TRUE,
|
||||
* then ask whether to open the corresponding file anyway. Return SKIPTHISFILE
|
||||
* when the user answers "No", return the name of the lock file on success, and
|
||||
* return NULL on failure. */
|
||||
char *do_lockfile(const char *filename, bool ask_the_user)
|
||||
{
|
||||
char *namecopy = copy_of(filename);
|
||||
char *secondcopy = copy_of(filename);
|
||||
size_t locknamesize = strlen(filename) + strlen(locking_prefix)
|
||||
+ strlen(locking_suffix) + 3;
|
||||
size_t locknamesize = strlen(filename) + strlen(locking_prefix) +
|
||||
strlen(locking_suffix) + 3;
|
||||
char *lockfilename = charalloc(locknamesize);
|
||||
static char lockprog[11], lockuser[17];
|
||||
struct stat fileinfo;
|
||||
int lockfd, lockpid, retval = -1;
|
||||
|
||||
snprintf(lockfilename, locknamesize, "%s/%s%s%s", dirname(namecopy),
|
||||
locking_prefix, basename(secondcopy), locking_suffix);
|
||||
free(secondcopy);
|
||||
free(namecopy);
|
||||
|
||||
if (stat(lockfilename, &fileinfo) != -1) {
|
||||
size_t readtot = 0;
|
||||
size_t readamt = 0;
|
||||
if (!ask_the_user && stat(lockfilename, &fileinfo) != -1)
|
||||
warn_and_shortly_pause(_("Someone else is also editing this file"));
|
||||
else if (stat(lockfilename, &fileinfo) != -1) {
|
||||
char *lockbuf, *question, *pidstring, *postedname, *promptstr;
|
||||
int room, choice;
|
||||
static char lockprog[11], lockuser[17];
|
||||
int lockfd, lockpid, room, choice;
|
||||
ssize_t readamt;
|
||||
|
||||
if ((lockfd = open(lockfilename, O_RDONLY)) < 0) {
|
||||
statusline(MILD, _("Error opening lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
goto free_the_name;
|
||||
statusline(ALERT, _("Error opening lock file %s: %s"),
|
||||
lockfilename, strerror(errno));
|
||||
free(lockfilename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lockbuf = charalloc(LOCKBUFSIZE);
|
||||
do {
|
||||
readamt = read(lockfd, &lockbuf[readtot], LOCKBUFSIZE - readtot);
|
||||
readtot += readamt;
|
||||
} while (readamt > 0 && readtot < LOCKBUFSIZE);
|
||||
lockbuf = charalloc(LOCKSIZE);
|
||||
|
||||
readamt = read(lockfd, lockbuf, LOCKSIZE);
|
||||
|
||||
close(lockfd);
|
||||
|
||||
if (readtot < 48) {
|
||||
statusline(MILD, _("Error reading lock file %s: "
|
||||
"Not enough data read"), lockfilename);
|
||||
/* If not enough data has been read to show the needed things,
|
||||
* or the two magic bytes are not there, skip the lock file. */
|
||||
if (readamt < 68 || lockbuf[0] != 0x62 || lockbuf[1] != 0x30) {
|
||||
statusline(ALERT, _("Bad lock file is ignored: %s"), lockfilename);
|
||||
free(lockfilename);
|
||||
free(lockbuf);
|
||||
goto free_the_name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy(lockprog, &lockbuf[2], 10);
|
||||
lockprog[10] = '\0';
|
||||
lockpid = (((unsigned char)lockbuf[27] * 256 + (unsigned char)lockbuf[26]) * 256 +
|
||||
(unsigned char)lockbuf[25]) * 256 + (unsigned char)lockbuf[24];
|
||||
strncpy(lockuser, &lockbuf[28], 16);
|
||||
lockuser[16] = '\0';
|
||||
free(lockbuf);
|
||||
|
||||
pidstring = charalloc(11);
|
||||
@@ -345,7 +281,7 @@ int do_lockfile(const char *filename)
|
||||
as_an_at = FALSE;
|
||||
|
||||
/* TRANSLATORS: The second %s is the name of the user, the third that of the editor. */
|
||||
question = _("File %s is being edited (by %s with %s, PID %s); continue?");
|
||||
question = _("File %s is being edited by %s (with %s, PID %s); open anyway?");
|
||||
room = COLS - breadth(question) + 7 - breadth(lockuser) -
|
||||
breadth(lockprog) - breadth(pidstring);
|
||||
if (room < 4)
|
||||
@@ -370,21 +306,22 @@ int do_lockfile(const char *filename)
|
||||
choice = do_yesno_prompt(FALSE, promptstr);
|
||||
free(promptstr);
|
||||
|
||||
/* When the user cancelled while we're still starting up, quit. */
|
||||
if (choice < 0 && !we_are_running)
|
||||
finish();
|
||||
|
||||
if (choice < 1) {
|
||||
free(lockfilename);
|
||||
wipe_statusbar();
|
||||
goto free_the_name;
|
||||
return SKIPTHISFILE;
|
||||
}
|
||||
}
|
||||
|
||||
retval = write_lockfile(lockfilename, filename, FALSE);
|
||||
if (write_lockfile(lockfilename, filename, FALSE))
|
||||
return lockfilename;
|
||||
|
||||
free_the_name:
|
||||
free(namecopy);
|
||||
free(secondcopy);
|
||||
if (retval < 1)
|
||||
free(lockfilename);
|
||||
|
||||
return retval;
|
||||
free(lockfilename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Perform a stat call on the given filename, allocating a stat struct
|
||||
@@ -402,18 +339,49 @@ void stat_with_alloc(const char *filename, struct stat **pstat)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Verify that the containing directory of the given filename exists. */
|
||||
bool has_valid_path(const char *filename)
|
||||
{
|
||||
char *namecopy = copy_of(filename);
|
||||
char *parentdir = dirname(namecopy);
|
||||
struct stat parentinfo;
|
||||
bool validity = FALSE;
|
||||
|
||||
if (stat(parentdir, &parentinfo) == -1) {
|
||||
if (errno == ENOENT)
|
||||
statusline(ALERT, _("Directory '%s' does not exist"), parentdir);
|
||||
else
|
||||
statusline(ALERT, _("Path '%s': %s"), parentdir, strerror(errno));
|
||||
} else if (!S_ISDIR(parentinfo.st_mode))
|
||||
statusline(ALERT, _("Path '%s' is not a directory"), parentdir);
|
||||
else if (access(parentdir, X_OK) == -1)
|
||||
statusline(ALERT, _("Path '%s' is not accessible"), parentdir);
|
||||
#ifndef NANO_TINY
|
||||
else if (ISSET(LOCKING) && !ISSET(VIEW_MODE) && access(parentdir, W_OK) < 0)
|
||||
statusline(MILD, _("Directory '%s' is not writable"), parentdir);
|
||||
#endif
|
||||
else
|
||||
validity = TRUE;
|
||||
|
||||
free(namecopy);
|
||||
|
||||
return validity;
|
||||
}
|
||||
|
||||
/* This does one of three things. If the filename is "", it just creates
|
||||
* a new empty buffer. When the filename is not empty, it reads that file
|
||||
* into a new buffer when requested, otherwise into the existing buffer. */
|
||||
bool open_buffer(const char *filename, bool new_buffer)
|
||||
bool open_buffer(const char *filename, bool new_one)
|
||||
{
|
||||
char *realname;
|
||||
/* The filename after tilde expansion. */
|
||||
#ifndef NANO_TINY
|
||||
char *thelocksname = NULL;
|
||||
#endif
|
||||
struct stat fileinfo;
|
||||
int descriptor = 0;
|
||||
/* Code 0 means new file, -1 means failure, and else it's the fd. */
|
||||
FILE *f;
|
||||
int rc;
|
||||
/* rc == -2 means that we have a new file. -1 means that the
|
||||
* open() failed. 0 means that the open() succeeded. */
|
||||
|
||||
/* Display newlines in filenames as ^J. */
|
||||
as_an_at = FALSE;
|
||||
@@ -448,39 +416,34 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If we're going to load into a new buffer, first create the new
|
||||
* buffer and (if possible) lock the corresponding file. */
|
||||
if (new_buffer) {
|
||||
make_new_buffer();
|
||||
|
||||
if (has_valid_path(realname)) {
|
||||
/* When loading into a new buffer, first check the file's path is valid,
|
||||
* and then (if requested and possible) create a lock file for it. */
|
||||
if (new_one && has_valid_path(realname)) {
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(LOCKING) && filename[0] != '\0') {
|
||||
/* When not overriding an existing lock, discard the buffer. */
|
||||
if (do_lockfile(realname) < 0) {
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (openfile != openfile->next)
|
||||
close_buffer();
|
||||
#endif
|
||||
free(realname);
|
||||
return FALSE;
|
||||
}
|
||||
if (ISSET(LOCKING) && !ISSET(VIEW_MODE) && filename[0] != '\0') {
|
||||
thelocksname = do_lockfile(realname, TRUE);
|
||||
|
||||
/* When not overriding an existing lock, don't open a buffer. */
|
||||
if (thelocksname == SKIPTHISFILE) {
|
||||
free(realname);
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If the filename isn't blank, and we are not in NOREAD_MODE,
|
||||
* open the file. Otherwise, treat it as a new file. */
|
||||
rc = (filename[0] != '\0' && !ISSET(NOREAD_MODE)) ?
|
||||
open_file(realname, new_buffer, &f) : -2;
|
||||
if (new_one)
|
||||
make_new_buffer();
|
||||
|
||||
/* If we have a non-new file, read it in. Then, if the buffer has
|
||||
* no stat, update the stat, if applicable. */
|
||||
if (rc > 0) {
|
||||
/* If we have a filename and are not in NOREAD mode, open the file. */
|
||||
if (filename[0] != '\0' && !ISSET(NOREAD_MODE))
|
||||
descriptor = open_file(realname, new_one, &f);
|
||||
|
||||
/* If we've successfully opened an existing file, read it in. */
|
||||
if (descriptor > 0) {
|
||||
install_handler_for_Ctrl_C();
|
||||
|
||||
read_file(f, rc, realname, !new_buffer);
|
||||
read_file(f, descriptor, realname, !new_one);
|
||||
|
||||
restore_handler_for_Ctrl_C();
|
||||
|
||||
@@ -490,10 +453,13 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If we have a file, and we've loaded it into a new buffer, set
|
||||
* the filename and put the cursor at the start of the buffer. */
|
||||
if (rc != -1 && new_buffer) {
|
||||
/* When we've loaded a file into a new buffer, set the filename
|
||||
* and put the cursor at the start of the buffer. */
|
||||
if (descriptor >= 0 && new_one) {
|
||||
openfile->filename = mallocstrcpy(openfile->filename, realname);
|
||||
#ifndef NANO_TINY
|
||||
openfile->lock_filename = thelocksname;
|
||||
#endif
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
@@ -502,64 +468,33 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
#ifdef ENABLE_COLOR
|
||||
/* If we're loading into a new buffer, update the colors to account
|
||||
* for it, if applicable. */
|
||||
if (new_buffer)
|
||||
if (new_one)
|
||||
color_update();
|
||||
#endif
|
||||
free(realname);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#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,
|
||||
const char *operation)
|
||||
/* Mark the current file as modified if it isn't already, and
|
||||
* then update the title bar to display the file's new status. */
|
||||
void set_modified(void)
|
||||
{
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
int descriptor;
|
||||
FILE *f;
|
||||
if (openfile->modified)
|
||||
return;
|
||||
|
||||
descriptor = open_file(filename, FALSE, &f);
|
||||
|
||||
if (descriptor < 0)
|
||||
return FALSE;
|
||||
openfile->modified = TRUE;
|
||||
titlebar(NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(COUPLE_BEGIN, operation);
|
||||
if (openfile->lock_filename != NULL)
|
||||
write_lockfile(openfile->lock_filename, openfile->filename, TRUE);
|
||||
#endif
|
||||
|
||||
/* When nothing is marked, start at the top of the buffer. */
|
||||
if (!marked) {
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
|
||||
/* Throw away the marked region or the whole buffer. */
|
||||
cutbuffer = NULL;
|
||||
#ifndef NANO_TINY
|
||||
add_undo(action, NULL);
|
||||
#endif
|
||||
do_snip(FALSE, marked, !marked, FALSE);
|
||||
#ifndef NANO_TINY
|
||||
update_undo(action);
|
||||
#endif
|
||||
free_lines(cutbuffer);
|
||||
cutbuffer = was_cutbuffer;
|
||||
|
||||
/* Insert the spell-checked file into the cleared area. */
|
||||
read_file(f, descriptor, filename, TRUE);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(COUPLE_END, operation);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* ENABLE_SPELLER */
|
||||
|
||||
/* Update the titlebar and the multiline cache to match the current buffer. */
|
||||
/* Update the title bar and the multiline cache to match the current buffer. */
|
||||
void prepare_for_display(void)
|
||||
{
|
||||
/* Update the titlebar, since the filename may have changed. */
|
||||
/* Update the title bar, since the filename may have changed. */
|
||||
if (!inhelp)
|
||||
titlebar(NULL);
|
||||
|
||||
@@ -583,7 +518,7 @@ void mention_name_and_linecount(void)
|
||||
(openfile->filebot->data[0] == '\0' ? 1 : 0);
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->fmt != NIX_FILE)
|
||||
/* TRANSLATORS: first %s is file name, second %s is file format. */
|
||||
/* TRANSLATORS: First %s is file name, second %s is file format. */
|
||||
statusline(HUSH, P_("%s -- %zu line (%s)", "%s -- %zu lines (%s)", count),
|
||||
openfile->filename[0] == '\0' ?
|
||||
_("New Buffer") : tail(openfile->filename), count,
|
||||
@@ -614,7 +549,7 @@ void redecorate_after_switch(void)
|
||||
openfile->firstcolumn = 0;
|
||||
#endif
|
||||
|
||||
/* Update titlebar and multiline info to match the current buffer. */
|
||||
/* Update title bar and multiline info to match the current buffer. */
|
||||
prepare_for_display();
|
||||
|
||||
/* Ensure that the main loop will redraw the help lines. */
|
||||
@@ -658,7 +593,7 @@ void close_buffer(void)
|
||||
free(orphan->current_stat);
|
||||
free(orphan->lock_filename);
|
||||
/* Free the undo stack. */
|
||||
discard_until(NULL, orphan, TRUE);
|
||||
discard_until(NULL);
|
||||
#endif
|
||||
|
||||
openfile = orphan->prev;
|
||||
@@ -918,31 +853,30 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
}
|
||||
|
||||
/* Open the file with the given name. If the file does not exist, display
|
||||
* "New File" if newfie is TRUE, and say "File not found" otherwise.
|
||||
* Return -2 if we say "New File", -1 if the file isn't opened, and the
|
||||
* obtained fd otherwise. *f is set to the opened file. */
|
||||
int open_file(const char *filename, bool newfie, FILE **f)
|
||||
* "New File" if new_one is TRUE, and say "File not found" otherwise.
|
||||
* Return 0 if we say "New File", -1 upon failure, and the obtained file
|
||||
* descriptor otherwise. The opened filestream is returned in *f. */
|
||||
int open_file(const char *filename, bool new_one, FILE **f)
|
||||
{
|
||||
struct stat fileinfo, fileinfo2;
|
||||
int fd;
|
||||
char *full_filename = get_full_path(filename);
|
||||
struct stat fileinfo;
|
||||
int fd;
|
||||
|
||||
/* If the full path is unusable (due to some component's permissions),
|
||||
* but the relative path is okay, then just use that one. */
|
||||
if (full_filename == NULL || (stat(full_filename, &fileinfo) == -1 &&
|
||||
stat(filename, &fileinfo2) != -1))
|
||||
/* If the absolute path is unusable (due to some component's permissions),
|
||||
* try the given path instead (as it is probably relative). */
|
||||
if (full_filename == NULL || stat(full_filename, &fileinfo) == -1)
|
||||
full_filename = mallocstrcpy(full_filename, filename);
|
||||
|
||||
if (stat(full_filename, &fileinfo) == -1) {
|
||||
if (newfie) {
|
||||
statusbar(_("New File"));
|
||||
free(full_filename);
|
||||
return -2;
|
||||
}
|
||||
|
||||
statusline(ALERT, _("File \"%s\" not found"), filename);
|
||||
free(full_filename);
|
||||
return -1;
|
||||
|
||||
if (new_one) {
|
||||
statusbar(_("New File"));
|
||||
return 0;
|
||||
} else {
|
||||
statusline(ALERT, _("File \"%s\" not found"), filename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -1019,6 +953,161 @@ char *get_next_filename(const char *name, const char *suffix)
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Send an unconditional kill signal to the running external command. */
|
||||
RETSIGTYPE cancel_the_command(int signal)
|
||||
{
|
||||
kill(pid_of_command, SIGKILL);
|
||||
}
|
||||
|
||||
/* Send the text that starts at the given line to file descriptor fd. */
|
||||
void send_data(const linestruct *line, int fd)
|
||||
{
|
||||
FILE *tube = fdopen(fd, "w");
|
||||
|
||||
if (tube == NULL)
|
||||
exit(4);
|
||||
|
||||
/* Send each line, except a final empty line. */
|
||||
while (line != NULL && (line->next != NULL || line->data[0] != '\0')) {
|
||||
fprintf(tube, "%s%s", line->data, line->next == NULL ? "" : "\n");
|
||||
line = line->next;
|
||||
}
|
||||
|
||||
fclose(tube);
|
||||
}
|
||||
|
||||
/* Execute the given command in a shell. Return TRUE on success. */
|
||||
bool execute_command(const char *command)
|
||||
{
|
||||
int from_fd[2], to_fd[2];
|
||||
/* The pipes through which text will be written and read. */
|
||||
const bool should_pipe = (command[0] == '|');
|
||||
FILE *stream;
|
||||
struct sigaction oldaction, newaction = {{0}};
|
||||
/* Original and temporary handlers for SIGINT. */
|
||||
|
||||
/* Create a pipe to read the command's output from, and, if needed,
|
||||
* a pipe to feed the command's input through. */
|
||||
if (pipe(from_fd) == -1 || (should_pipe && pipe(to_fd) == -1)) {
|
||||
statusline(ALERT, _("Could not create pipe"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Fork a child process to run the command in. */
|
||||
if ((pid_of_command = fork()) == 0) {
|
||||
const char *theshell = getenv("SHELL");
|
||||
|
||||
if (theshell == NULL)
|
||||
theshell = (char *)"/bin/sh";
|
||||
|
||||
/* Child: close the unused read end of the output pipe. */
|
||||
close(from_fd[0]);
|
||||
|
||||
/* Connect the write end of the output pipe to the process' output streams. */
|
||||
dup2(from_fd[1], fileno(stdout));
|
||||
dup2(from_fd[1], fileno(stderr));
|
||||
|
||||
/* If the parent sends text, connect the read end of the
|
||||
* feeding pipe to the child's input stream. */
|
||||
if (should_pipe) {
|
||||
dup2(to_fd[0], fileno(stdin));
|
||||
close(to_fd[1]);
|
||||
}
|
||||
|
||||
/* Run the given command inside the preferred shell. */
|
||||
execl(theshell, tail(theshell), "-c", should_pipe ? &command[1] : command, NULL);
|
||||
|
||||
/* If the exec call returns, there was an error. */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Parent: close the unused write end of the pipe. */
|
||||
close(from_fd[1]);
|
||||
|
||||
if (pid_of_command == -1) {
|
||||
statusline(ALERT, _("Could not fork"));
|
||||
close(from_fd[0]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
statusbar(_("Executing..."));
|
||||
|
||||
/* If the command starts with "|", pipe buffer or region to the command. */
|
||||
if (should_pipe) {
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
cutbuffer = NULL;
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (ISSET(MULTIBUFFER)) {
|
||||
openfile = openfile->prev;
|
||||
if (openfile->mark)
|
||||
do_snip(TRUE, TRUE, FALSE, FALSE);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* TRANSLATORS: This one goes with Undid/Redid messages. */
|
||||
add_undo(COUPLE_BEGIN, N_("filtering"));
|
||||
if (openfile->mark == NULL) {
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
add_undo(CUT, NULL);
|
||||
do_snip(FALSE, openfile->mark != NULL, openfile->mark == NULL, FALSE);
|
||||
update_undo(CUT);
|
||||
}
|
||||
|
||||
/* Create a separate process for piping the data to the command. */
|
||||
if (fork() == 0) {
|
||||
send_data(cutbuffer, to_fd[1]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
close(to_fd[0]);
|
||||
close(to_fd[1]);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (ISSET(MULTIBUFFER))
|
||||
openfile = openfile->next;
|
||||
#endif
|
||||
free_lines(cutbuffer);
|
||||
cutbuffer = was_cutbuffer;
|
||||
}
|
||||
|
||||
/* Re-enable interpretation of the special control keys so that we get
|
||||
* SIGINT when Ctrl-C is pressed. */
|
||||
enable_kb_interrupt();
|
||||
|
||||
/* Set up a signal handler so that ^C will terminate the forked process. */
|
||||
newaction.sa_handler = cancel_the_command;
|
||||
newaction.sa_flags = 0;
|
||||
sigaction(SIGINT, &newaction, &oldaction);
|
||||
|
||||
stream = fdopen(from_fd[0], "rb");
|
||||
if (stream == NULL)
|
||||
statusline(ALERT, _("Failed to open pipe: %s"), strerror(errno));
|
||||
else
|
||||
read_file(stream, 0, "pipe", TRUE);
|
||||
|
||||
if (should_pipe && !ISSET(MULTIBUFFER))
|
||||
add_undo(COUPLE_END, N_("filtering"));
|
||||
|
||||
/* Wait for the external command (and possibly data sender) to terminate. */
|
||||
wait(NULL);
|
||||
if (should_pipe)
|
||||
wait(NULL);
|
||||
|
||||
/* Restore the original handler for SIGINT. */
|
||||
sigaction(SIGINT, &oldaction, NULL);
|
||||
|
||||
/* Restore the terminal to its desired state, and disable
|
||||
* interpretation of the special control keys again. */
|
||||
terminal_init();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* NANO_TINY */
|
||||
|
||||
/* Insert a file into the current buffer, or into a new buffer when
|
||||
* the MULTIBUFFER flag is set. */
|
||||
void do_insertfile(void)
|
||||
@@ -1026,7 +1115,7 @@ void do_insertfile(void)
|
||||
int response;
|
||||
const char *msg;
|
||||
char *given = copy_of("");
|
||||
/* The last answer the user typed at the statusbar prompt. */
|
||||
/* The last answer the user typed at the status-bar prompt. */
|
||||
#ifndef NANO_TINY
|
||||
format_type was_fmt = openfile->fmt;
|
||||
bool execute = FALSE;
|
||||
@@ -1121,7 +1210,7 @@ void do_insertfile(void)
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (func == to_files_void) {
|
||||
if (func == to_files) {
|
||||
char *chosen = do_browse_from(answer);
|
||||
|
||||
/* If no file was chosen, go back to the prompt. */
|
||||
@@ -1505,12 +1594,12 @@ bool write_file(const char *name, FILE *thefile, bool tmp,
|
||||
kind_of_writing_type method, bool fullbuffer)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
bool isactualfile = FALSE;
|
||||
bool is_existing_file;
|
||||
/* Becomes TRUE when the file is non-temporary and exists. */
|
||||
struct stat st;
|
||||
/* The status fields filled in by stat(). */
|
||||
#endif
|
||||
char *realname;
|
||||
char *realname = real_dir_from_tilde(name);
|
||||
/* The filename after tilde expansion. */
|
||||
char *tempname = NULL;
|
||||
/* The name of the temporary file we use when prepending. */
|
||||
@@ -1521,13 +1610,6 @@ bool write_file(const char *name, FILE *thefile, bool tmp,
|
||||
bool retval = FALSE;
|
||||
/* The return value, to become TRUE when writing has succeeded. */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (*name == '\0')
|
||||
die("Tried to write a nameless file -- please report a bug\n");
|
||||
#endif
|
||||
|
||||
realname = real_dir_from_tilde(name);
|
||||
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
/* If we're writing a temporary file, we're probably going outside
|
||||
* the operating directory, so skip the operating directory test. */
|
||||
@@ -1538,20 +1620,19 @@ bool write_file(const char *name, FILE *thefile, bool tmp,
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
/* Check whether the file (at the end of the symlink) exists. */
|
||||
if (!tmp)
|
||||
isactualfile = (stat(realname, &st) != -1);
|
||||
is_existing_file = (!tmp) && (stat(realname, &st) != -1);
|
||||
|
||||
/* If we haven't stat()d this file before (say, the user just specified
|
||||
* it interactively), stat and save the value now, or else we will chase
|
||||
* null pointers when we do modtime checks and such during backup. */
|
||||
if (openfile->current_stat == NULL && isactualfile)
|
||||
if (openfile->current_stat == NULL && is_existing_file)
|
||||
stat_with_alloc(realname, &openfile->current_stat);
|
||||
|
||||
/* We back up only if the backup toggle is set, and the file exists and
|
||||
* isn't temporary. Furthermore, if we aren't appending, prepending, or
|
||||
* writing a selection, we back up only if the file has not been modified
|
||||
* by someone else since nano opened it. */
|
||||
if (ISSET(BACKUP_FILE) && isactualfile && openfile->current_stat &&
|
||||
if (ISSET(BACKUP_FILE) && is_existing_file && openfile->current_stat &&
|
||||
(method != OVERWRITE || openfile->mark ||
|
||||
openfile->current_stat->st_mtime == st.st_mtime)) {
|
||||
static struct timespec filetime[2];
|
||||
@@ -1733,7 +1814,7 @@ bool write_file(const char *name, FILE *thefile, bool tmp,
|
||||
}
|
||||
}
|
||||
|
||||
if (!tmp && S_ISFIFO(st.st_mode))
|
||||
if (is_existing_file && S_ISFIFO(st.st_mode))
|
||||
statusbar(_("Writing to FIFO..."));
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
@@ -1867,8 +1948,16 @@ bool write_file(const char *name, FILE *thefile, bool tmp,
|
||||
|
||||
/* When having written an entire buffer, update some administrivia. */
|
||||
if (fullbuffer && method == OVERWRITE && !tmp) {
|
||||
/* If the filename was changed, check if this means a new syntax. */
|
||||
/* If the filename was changed, write a new lockfile when needed,
|
||||
* and check whether it means a different syntax gets used. */
|
||||
if (strcmp(openfile->filename, realname) != 0) {
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->lock_filename != NULL) {
|
||||
delete_lockfile(openfile->lock_filename);
|
||||
free(openfile->lock_filename);
|
||||
openfile->lock_filename = do_lockfile(realname, FALSE);
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
const char *oldname, *newname;
|
||||
|
||||
@@ -2046,7 +2135,7 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
given = mallocstrcpy(given, answer);
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (func == to_files_void) {
|
||||
if (func == to_files) {
|
||||
char *chosen = do_browse_from(answer);
|
||||
|
||||
if (chosen == NULL)
|
||||
@@ -2074,7 +2163,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
|
||||
@@ -2245,8 +2334,7 @@ char *real_dir_from_tilde(const char *path)
|
||||
#ifdef HAVE_PWD_H
|
||||
const struct passwd *userdata;
|
||||
|
||||
tilded = measured_copy(path, i + 1);
|
||||
tilded[i] = '\0';
|
||||
tilded = measured_copy(path, i);
|
||||
|
||||
do {
|
||||
userdata = getpwent();
|
||||
@@ -2453,7 +2541,7 @@ char **cwd_tab_completion(const char *buf, bool allow_files,
|
||||
return matches;
|
||||
}
|
||||
|
||||
/* Do tab completion. place refers to how much the statusbar cursor
|
||||
/* Do tab completion. place refers to how much the status-bar cursor
|
||||
* position should be advanced. refresh_func is the function we will
|
||||
* call to refresh the edit window. */
|
||||
char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
|
||||
834
src/global.c
834
src/global.c
File diff suppressed because it is too large
Load Diff
109
src/help.c
109
src/help.c
@@ -1,9 +1,9 @@
|
||||
/**************************************************************************
|
||||
* help.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2000-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2000-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2017 Rishabh Dave *
|
||||
* Copyright (C) 2014-2018 Benno Schulenberg *
|
||||
* Copyright (C) 2014-2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -43,16 +43,31 @@ static size_t location;
|
||||
void wrap_help_text_into_buffer(void)
|
||||
{
|
||||
size_t sum = 0;
|
||||
/* Avoid overtight and overwide paragraphs in the introductory text. */
|
||||
size_t wrapping_point = (COLS < 40) ? 40 : (COLS > 74) ? 74 : COLS;
|
||||
const char *ptr = start_of_body;
|
||||
|
||||
make_new_buffer();
|
||||
|
||||
/* Copy the help text into the just-created new buffer. */
|
||||
while (*ptr != '\0') {
|
||||
int length = help_line_len(ptr);
|
||||
char *oneline = nmalloc(length + 1);
|
||||
int length, shim;
|
||||
char *oneline;
|
||||
|
||||
if (ptr == end_of_intro)
|
||||
wrapping_point = (COLS < 40) ? 40 : COLS;
|
||||
|
||||
if (ptr > end_of_intro && *(ptr - 1) != '\n') {
|
||||
length = break_line(ptr, (COLS < 40) ? 22 : COLS - 18, TRUE);
|
||||
oneline = nmalloc(length + 5);
|
||||
snprintf(oneline, length + 5, "\t\t %s", ptr);
|
||||
} else {
|
||||
length = break_line(ptr, wrapping_point, TRUE);
|
||||
oneline = nmalloc(length + 1);
|
||||
shim = (*(ptr + length - 1) == ' ') ? 0 : 1;
|
||||
snprintf(oneline, length + shim, "%s", ptr);
|
||||
}
|
||||
|
||||
snprintf(oneline, length + 1, "%s", ptr);
|
||||
free(openfile->current->data);
|
||||
openfile->current->data = oneline;
|
||||
|
||||
@@ -88,8 +103,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;
|
||||
@@ -140,8 +155,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 +166,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 = measured_copy(help_text, length + 1);
|
||||
title[length] = '\0';
|
||||
title = measured_copy(help_text, length);
|
||||
|
||||
titlebar(title);
|
||||
|
||||
@@ -171,7 +186,13 @@ void do_help(void)
|
||||
kbinput = get_kbinput(edit, didfind == 1 || ISSET(SHOW_CURSOR));
|
||||
didfind = 0;
|
||||
|
||||
func = parse_help_input(&kbinput);
|
||||
#ifndef NANO_TINY
|
||||
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) {
|
||||
beep();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
func = interpret(&kbinput);
|
||||
|
||||
if (func == total_refresh) {
|
||||
total_redraw();
|
||||
@@ -541,73 +562,13 @@ void help_init(void)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
}
|
||||
|
||||
/* Return the function that is bound to the given key, accepting certain
|
||||
* plain characters too, for consistency with the file browser. */
|
||||
functionptrtype parse_help_input(int *kbinput)
|
||||
{
|
||||
if (!meta_key) {
|
||||
switch (*kbinput) {
|
||||
case '-':
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
return do_page_down;
|
||||
case 'W':
|
||||
case 'w':
|
||||
case '/':
|
||||
return do_search_forward;
|
||||
case 'N':
|
||||
return do_findprevious;
|
||||
case 'n':
|
||||
return do_findnext;
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'Q':
|
||||
case 'q':
|
||||
case 'X':
|
||||
case 'x':
|
||||
return do_exit;
|
||||
}
|
||||
}
|
||||
return func_from_key(kbinput);
|
||||
}
|
||||
|
||||
/* Calculate the displayable length of the help-text line starting at ptr. */
|
||||
size_t help_line_len(const char *ptr)
|
||||
{
|
||||
size_t wrapping_point = (COLS > 24) ? COLS - 1 : 24;
|
||||
/* The target width for wrapping long lines. */
|
||||
ssize_t wrap_location;
|
||||
/* Actual position where the line can be wrapped. */
|
||||
size_t length = 0;
|
||||
/* Full length of the line, until the first newline. */
|
||||
|
||||
/* Avoid overwide paragraphs in the introductory text. */
|
||||
if (ptr < end_of_intro && COLS > 74)
|
||||
wrapping_point = 74;
|
||||
|
||||
wrap_location = break_line(ptr, wrapping_point, TRUE);
|
||||
|
||||
/* Get the length of the entire line up to a null or a newline. */
|
||||
while (*(ptr + length) != '\0' && *(ptr + length) != '\n')
|
||||
length = step_right(ptr, length);
|
||||
|
||||
/* If the entire line will just fit the screen, don't wrap it. */
|
||||
if (wideness(ptr, length) <= wrapping_point + 1)
|
||||
return length;
|
||||
else if (wrap_location > 0)
|
||||
return wrap_location;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_HELP */
|
||||
|
||||
/* Start the help viewer. */
|
||||
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();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* history.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2003-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* Copyright (C) 2003-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2017, 2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
|
||||
24
src/move.c
24
src/move.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* move.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2018 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -37,7 +37,7 @@ void to_first_line(void)
|
||||
void to_last_line(void)
|
||||
{
|
||||
openfile->current = openfile->filebot;
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
openfile->current_x = (inhelp) ? 0 : strlen(openfile->filebot->data);
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* Set the last line of the screen as the target for the cursor. */
|
||||
@@ -192,7 +192,7 @@ void do_para_end(linestruct **line)
|
||||
}
|
||||
|
||||
/* Move up to first start of a paragraph before the current line. */
|
||||
void do_para_begin_void(void)
|
||||
void to_para_begin(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
@@ -203,7 +203,7 @@ void do_para_begin_void(void)
|
||||
}
|
||||
|
||||
/* Move down to just after the first found end of a paragraph. */
|
||||
void do_para_end_void(void)
|
||||
void to_para_end(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
@@ -222,7 +222,7 @@ void do_para_end_void(void)
|
||||
#endif /* ENABLE_JUSTIFY */
|
||||
|
||||
/* Move to the preceding block of text. */
|
||||
void do_prev_block(void)
|
||||
void to_prev_block(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
bool is_text = FALSE, seen_text = FALSE;
|
||||
@@ -244,7 +244,7 @@ void do_prev_block(void)
|
||||
}
|
||||
|
||||
/* Move to the next block of text. */
|
||||
void do_next_block(void)
|
||||
void to_next_block(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
bool is_white = white_string(openfile->current->data);
|
||||
@@ -281,7 +281,7 @@ void do_prev_word(bool allow_punct)
|
||||
openfile->current_x = step_left(openfile->current->data,
|
||||
openfile->current_x);
|
||||
|
||||
if (is_word_mbchar(openfile->current->data + openfile->current_x,
|
||||
if (is_word_char(openfile->current->data + openfile->current_x,
|
||||
allow_punct)) {
|
||||
seen_a_word = TRUE;
|
||||
/* If at the head of a line now, this surely is a word start. */
|
||||
@@ -305,7 +305,7 @@ void do_prev_word(bool allow_punct)
|
||||
* part of a word. Return TRUE if we started on a word, and FALSE otherwise. */
|
||||
bool do_next_word(bool after_ends, bool allow_punct)
|
||||
{
|
||||
bool started_on_word = is_word_mbchar(openfile->current->data +
|
||||
bool started_on_word = is_word_char(openfile->current->data +
|
||||
openfile->current_x, allow_punct);
|
||||
bool seen_space = !started_on_word;
|
||||
#ifndef NANO_TINY
|
||||
@@ -332,7 +332,7 @@ bool do_next_word(bool after_ends, bool allow_punct)
|
||||
if (after_ends) {
|
||||
/* If this is a word character, continue; else it's a separator,
|
||||
* and if we've already seen a word, then it's a word end. */
|
||||
if (is_word_mbchar(openfile->current->data + openfile->current_x,
|
||||
if (is_word_char(openfile->current->data + openfile->current_x,
|
||||
allow_punct))
|
||||
seen_word = TRUE;
|
||||
else if (seen_word)
|
||||
@@ -342,7 +342,7 @@ bool do_next_word(bool after_ends, bool allow_punct)
|
||||
{
|
||||
/* If this is not a word character, then it's a separator; else
|
||||
* if we've already seen a separator, then it's a word start. */
|
||||
if (!is_word_mbchar(openfile->current->data + openfile->current_x,
|
||||
if (!is_word_char(openfile->current->data + openfile->current_x,
|
||||
allow_punct))
|
||||
seen_space = TRUE;
|
||||
else if (seen_space)
|
||||
@@ -355,7 +355,7 @@ bool do_next_word(bool after_ends, bool allow_punct)
|
||||
|
||||
/* Move to the previous word in the file, treating punctuation as part of a
|
||||
* word if the WORD_BOUNDS flag is set, and update the screen afterwards. */
|
||||
void do_prev_word_void(void)
|
||||
void to_prev_word(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
@@ -367,7 +367,7 @@ void do_prev_word_void(void)
|
||||
/* Move to the next word in the file. If the AFTER_ENDS flag is set, stop
|
||||
* at word ends instead of beginnings. If the WORD_BOUNDS flag is set, treat
|
||||
* punctuation as part of a word. Update the screen afterwards. */
|
||||
void do_next_word_void(void)
|
||||
void to_next_word(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
|
||||
670
src/nano.c
670
src/nano.c
File diff suppressed because it is too large
Load Diff
37
src/nano.h
37
src/nano.h
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* nano.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -178,10 +178,12 @@ typedef enum {
|
||||
/* Structure types. */
|
||||
#ifdef ENABLE_COLOR
|
||||
typedef struct colortype {
|
||||
short id;
|
||||
/* An ordinal number (if this color combo is for a multiline regex). */
|
||||
short fg;
|
||||
/* This syntax's foreground color. */
|
||||
/* This combo's foreground color. */
|
||||
short bg;
|
||||
/* This syntax's background color. */
|
||||
/* This combo's background color. */
|
||||
short pairnum;
|
||||
/* The pair number for this foreground/background color combination. */
|
||||
int attributes;
|
||||
@@ -191,9 +193,7 @@ typedef struct colortype {
|
||||
regex_t *end;
|
||||
/* The compiled regular expression for 'end=', if any. */
|
||||
struct colortype *next;
|
||||
/* Next set of colors. */
|
||||
int id;
|
||||
/* Basic id for assigning to lines later. */
|
||||
/* Next color combination. */
|
||||
} colortype;
|
||||
|
||||
typedef struct regexlisttype {
|
||||
@@ -241,7 +241,7 @@ typedef struct syntaxtype {
|
||||
#endif
|
||||
colortype *color;
|
||||
/* The colors and their regexes used in this syntax. */
|
||||
int nmultis;
|
||||
short nmultis;
|
||||
/* How many multiline regex strings this syntax has. */
|
||||
struct syntaxtype *next;
|
||||
/* Next syntax. */
|
||||
@@ -310,9 +310,9 @@ typedef struct undostruct {
|
||||
/* The operation type that this undo item is for. */
|
||||
int xflags;
|
||||
/* Some flag data to mark certain corner cases. */
|
||||
ssize_t lineno;
|
||||
ssize_t head_lineno;
|
||||
/* The line number where the operation began or ended. */
|
||||
size_t begin;
|
||||
size_t head_x;
|
||||
/* The x position where the operation began or ended. */
|
||||
char *strdata;
|
||||
/* String data to help restore the affected line. */
|
||||
@@ -324,9 +324,9 @@ typedef struct undostruct {
|
||||
/* Undo info specific to groups of lines. */
|
||||
linestruct *cutbuffer;
|
||||
/* A copy of the cutbuffer. */
|
||||
ssize_t mark_begin_lineno;
|
||||
ssize_t tail_lineno;
|
||||
/* Mostly the line number of the current line; sometimes something else. */
|
||||
size_t mark_begin_x;
|
||||
size_t tail_x;
|
||||
/* The x position corresponding to the above line number. */
|
||||
struct undostruct *next;
|
||||
/* A pointer to the undo item of the preceding action. */
|
||||
@@ -422,8 +422,6 @@ typedef struct rcoption {
|
||||
typedef struct keystruct {
|
||||
const char *keystr;
|
||||
/* The string that describes the keystroke, like "^C" or "M-R". */
|
||||
bool meta;
|
||||
/* Whether this is a Meta keystroke. */
|
||||
int keycode;
|
||||
/* The integer that, together with meta, identifies the keystroke. */
|
||||
int menus;
|
||||
@@ -495,7 +493,7 @@ enum
|
||||
CASE_SENSITIVE,
|
||||
CONSTANT_SHOW,
|
||||
NO_HELP,
|
||||
SUSPEND,
|
||||
SUSPENDABLE,
|
||||
NO_WRAP,
|
||||
AUTOINDENT,
|
||||
VIEW_MODE,
|
||||
@@ -567,8 +565,6 @@ enum
|
||||
#endif
|
||||
|
||||
/* Basic control codes. */
|
||||
#define BS_CODE 0x08
|
||||
#define TAB_CODE 0x09
|
||||
#define ESC_CODE 0x1B
|
||||
#define DEL_CODE 0x7F
|
||||
|
||||
@@ -610,6 +606,9 @@ enum
|
||||
/* A special keycode for when <Tab> is pressed while the mark is on. */
|
||||
#define INDENT_KEY 0x4F1
|
||||
|
||||
/* A special keycode to signal the beginning and end of a bracketed paste. */
|
||||
#define BRACKETED_PASTE_MARKER 0x4FB
|
||||
|
||||
#ifdef USE_SLANG
|
||||
#ifdef ENABLE_UTF8
|
||||
#define KEY_BAD 0xFF /* Clipped error code. */
|
||||
@@ -624,11 +623,11 @@ enum
|
||||
#define KEY_WINCH -2
|
||||
|
||||
/* Some extra flags for the undo function. */
|
||||
#define WAS_FINAL_BACKSPACE (1<<1)
|
||||
#define WAS_BACKSPACE_AT_EOF (1<<1)
|
||||
#define WAS_WHOLE_LINE (1<<2)
|
||||
#define WAS_FINAL_LINE (1<<3)
|
||||
#define INCLUDED_LAST_LINE (1<<3)
|
||||
#define MARK_WAS_SET (1<<4)
|
||||
#define WAS_MARKED_FORWARD (1<<5)
|
||||
#define WAS_MARKED_BACKWARDS (1<<5)
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* The default number of columns from end of line where wrapping occurs. */
|
||||
|
||||
432
src/prompt.c
432
src/prompt.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* prompt.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2018 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -24,18 +24,144 @@
|
||||
#include <string.h>
|
||||
|
||||
static char *prompt = NULL;
|
||||
/* The prompt string used for statusbar questions. */
|
||||
/* The prompt string used for status-bar questions. */
|
||||
static size_t typing_x = HIGHEST_POSITIVE;
|
||||
/* The cursor position in answer. */
|
||||
|
||||
/* Move to the beginning of the answer. */
|
||||
void do_statusbar_home(void)
|
||||
{
|
||||
typing_x = 0;
|
||||
}
|
||||
|
||||
/* Move to the end of the answer. */
|
||||
void do_statusbar_end(void)
|
||||
{
|
||||
typing_x = strlen(answer);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Move to the next word in the answer. */
|
||||
void do_statusbar_next_word(void)
|
||||
{
|
||||
bool seen_space = !is_word_char(answer + typing_x, FALSE);
|
||||
bool seen_word = !seen_space;
|
||||
|
||||
/* Move forward until we reach either the end or the start of a word,
|
||||
* depending on whether the AFTER_ENDS flag is set or not. */
|
||||
while (answer[typing_x] != '\0') {
|
||||
typing_x = step_right(answer, typing_x);
|
||||
|
||||
if (ISSET(AFTER_ENDS)) {
|
||||
/* If this is a word character, continue; else it's a separator,
|
||||
* and if we've already seen a word, then it's a word end. */
|
||||
if (is_word_char(answer + typing_x, FALSE))
|
||||
seen_word = TRUE;
|
||||
else if (seen_word)
|
||||
break;
|
||||
} else {
|
||||
/* If this is not a word character, then it's a separator; else
|
||||
* if we've already seen a separator, then it's a word start. */
|
||||
if (!is_word_char(answer + typing_x, FALSE))
|
||||
seen_space = TRUE;
|
||||
else if (seen_space)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to the previous word in the answer. */
|
||||
void do_statusbar_prev_word(void)
|
||||
{
|
||||
bool seen_a_word = FALSE, step_forward = FALSE;
|
||||
|
||||
/* Move backward until we pass over the start of a word. */
|
||||
while (typing_x != 0) {
|
||||
typing_x = step_left(answer, typing_x);
|
||||
|
||||
if (is_word_char(answer + typing_x, FALSE))
|
||||
seen_a_word = TRUE;
|
||||
else if (seen_a_word) {
|
||||
/* This is space now: we've overshot the start of the word. */
|
||||
step_forward = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (step_forward)
|
||||
/* Move one character forward again to sit on the start of the word. */
|
||||
typing_x = step_right(answer, typing_x);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Move left one character in the answer. */
|
||||
void do_statusbar_left(void)
|
||||
{
|
||||
if (typing_x > 0)
|
||||
typing_x = step_left(answer, typing_x);
|
||||
}
|
||||
|
||||
/* Move right one character in the answer. */
|
||||
void do_statusbar_right(void)
|
||||
{
|
||||
if (answer[typing_x] != '\0')
|
||||
typing_x = step_right(answer, typing_x);
|
||||
}
|
||||
|
||||
/* Delete one character in the answer. */
|
||||
void do_statusbar_delete(void)
|
||||
{
|
||||
if (answer[typing_x] != '\0') {
|
||||
int charlen = char_length(answer + typing_x);
|
||||
|
||||
memmove(answer + typing_x, answer + typing_x + charlen,
|
||||
strlen(answer) - typing_x - charlen + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Backspace over one character in the answer. */
|
||||
void do_statusbar_backspace(void)
|
||||
{
|
||||
if (typing_x > 0) {
|
||||
typing_x = step_left(answer, typing_x);
|
||||
do_statusbar_delete();
|
||||
}
|
||||
}
|
||||
|
||||
/* Zap some or all text from the answer. */
|
||||
void do_statusbar_cut_text(void)
|
||||
{
|
||||
if (!ISSET(CUT_FROM_CURSOR))
|
||||
typing_x = 0;
|
||||
|
||||
answer[typing_x] = '\0';
|
||||
}
|
||||
|
||||
/* Paste the first line of the cutbuffer into the current answer. */
|
||||
void paste_into_answer(void)
|
||||
{
|
||||
size_t pastelen = strlen(cutbuffer->data);
|
||||
char *fusion = charalloc(strlen(answer) + pastelen + 1);
|
||||
|
||||
/* Concatenate: the current answer before the cursor, the first line
|
||||
* of the cutbuffer, plus the rest of the current answer. */
|
||||
strncpy(fusion, answer, typing_x);
|
||||
strncpy(fusion + typing_x, cutbuffer->data, pastelen);
|
||||
strcpy(fusion + typing_x + pastelen, answer + typing_x);
|
||||
|
||||
free(answer);
|
||||
answer = fusion;
|
||||
typing_x += pastelen;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
/* Handle a mouse click on the statusbar prompt or the shortcut list. */
|
||||
/* Handle a mouse click on the status-bar prompt or the shortcut list. */
|
||||
int do_statusbar_mouse(void)
|
||||
{
|
||||
int click_row, click_col;
|
||||
int retval = get_mouseinput(&click_row, &click_col, TRUE);
|
||||
|
||||
/* We can click on the statusbar window text to move the cursor. */
|
||||
/* We can click on the status-bar window text to move the cursor. */
|
||||
if (retval == 0 && wmouse_trafo(bottomwin, &click_row, &click_col, FALSE)) {
|
||||
size_t start_col = breadth(prompt) + 2;
|
||||
|
||||
@@ -50,6 +176,35 @@ int do_statusbar_mouse(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Insert the given short burst of bytes into the answer. */
|
||||
void inject_into_answer(char *burst, size_t count)
|
||||
{
|
||||
/* First encode any embedded NUL byte as 0x0A. */
|
||||
for (size_t index = 0; index < count; index++)
|
||||
if (burst[index] == '\0')
|
||||
burst[index] = '\n';
|
||||
|
||||
answer = charealloc(answer, strlen(answer) + count + 1);
|
||||
memmove(answer + typing_x + count, answer + typing_x,
|
||||
strlen(answer) - typing_x + 1);
|
||||
strncpy(answer + typing_x, burst , count);
|
||||
|
||||
typing_x += count;
|
||||
}
|
||||
|
||||
/* Get a verbatim keystroke and insert it into the answer. */
|
||||
void do_statusbar_verbatim_input(void)
|
||||
{
|
||||
char *bytes;
|
||||
size_t count;
|
||||
|
||||
bytes = get_verbatim_kbinput(bottomwin, &count);
|
||||
|
||||
inject_into_answer(bytes, count);
|
||||
|
||||
free(bytes);
|
||||
}
|
||||
|
||||
/* Read in a keystroke, interpret it if it is a shortcut or toggle, and
|
||||
* return it. Set finished to TRUE if we're done after running
|
||||
* or trying to run a function associated with a shortcut key. */
|
||||
@@ -57,9 +212,9 @@ int do_statusbar_input(bool *finished)
|
||||
{
|
||||
int input;
|
||||
/* The character we read in. */
|
||||
static int *kbinput = NULL;
|
||||
static char *puddle = NULL;
|
||||
/* The input buffer. */
|
||||
static size_t kbinput_len = 0;
|
||||
static size_t depth = 0;
|
||||
/* The length of the input buffer. */
|
||||
const keystruct *shortcut;
|
||||
|
||||
@@ -87,40 +242,30 @@ int do_statusbar_input(bool *finished)
|
||||
/* Check for a shortcut in the current list. */
|
||||
shortcut = get_shortcut(&input);
|
||||
|
||||
/* If we got a non-high-bit control key, a meta key sequence, or a
|
||||
* function key, and it's not a shortcut or toggle, throw it out. */
|
||||
/* If not a command, discard anything that is not a normal character byte.
|
||||
* Apart from that, only accept input when not in restricted mode, or when
|
||||
* not at the "Write File" prompt, or when there is no filename yet. */
|
||||
if (shortcut == NULL) {
|
||||
if (is_ascii_cntrl_char(input) || meta_key || !is_byte(input)) {
|
||||
if (input < 0x20 || input > 0xFF || meta_key)
|
||||
beep();
|
||||
input = ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the keystroke isn't a shortcut nor a toggle, it's a normal text
|
||||
* character: add the it to the input buffer, when allowed. */
|
||||
if (input != ERR && shortcut == NULL) {
|
||||
/* Only accept input when not in restricted mode, or when not at
|
||||
* the "Write File" prompt, or when there is no filename yet. */
|
||||
if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
|
||||
else if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
|
||||
openfile->filename[0] == '\0') {
|
||||
kbinput_len++;
|
||||
kbinput = (int *)nrealloc(kbinput, kbinput_len * sizeof(int));
|
||||
kbinput[kbinput_len - 1] = input;
|
||||
puddle = charealloc(puddle, depth + 2);
|
||||
puddle[depth++] = (char)input;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we got a shortcut, or if there aren't any other keystrokes waiting
|
||||
* after the one we read in, we need to insert all the characters in the
|
||||
* input buffer (if not empty) into the answer. */
|
||||
if ((shortcut || get_key_buffer_len() == 0) && kbinput != NULL) {
|
||||
/* Inject all characters in the input buffer at once, filtering out
|
||||
* control characters. */
|
||||
do_statusbar_output(kbinput, kbinput_len, TRUE);
|
||||
/* If we got a shortcut, or if there aren't any other keystrokes waiting,
|
||||
* it's time to insert all characters in the input buffer (if not empty)
|
||||
* into the answer, and then clear the input buffer. */
|
||||
if ((shortcut || get_key_buffer_len() == 0) && puddle != NULL) {
|
||||
puddle[depth] = '\0';
|
||||
|
||||
/* Empty the input buffer. */
|
||||
kbinput_len = 0;
|
||||
free(kbinput);
|
||||
kbinput = NULL;
|
||||
inject_into_answer(puddle, depth);
|
||||
|
||||
free(puddle);
|
||||
puddle = NULL;
|
||||
depth = 0;
|
||||
}
|
||||
|
||||
if (shortcut) {
|
||||
@@ -136,9 +281,9 @@ int do_statusbar_input(bool *finished)
|
||||
else if (shortcut->func == do_right)
|
||||
do_statusbar_right();
|
||||
#ifndef NANO_TINY
|
||||
else if (shortcut->func == do_prev_word_void)
|
||||
else if (shortcut->func == to_prev_word)
|
||||
do_statusbar_prev_word();
|
||||
else if (shortcut->func == do_next_word_void)
|
||||
else if (shortcut->func == to_next_word)
|
||||
do_statusbar_next_word();
|
||||
#endif
|
||||
else if (shortcut->func == do_home)
|
||||
@@ -169,7 +314,7 @@ int do_statusbar_input(bool *finished)
|
||||
do_statusbar_backspace();
|
||||
else if (shortcut->func == paste_text) {
|
||||
if (cutbuffer != NULL)
|
||||
do_statusbar_uncut_text();
|
||||
paste_into_answer();
|
||||
} else {
|
||||
/* Handle any other shortcut in the current menu, setting finished
|
||||
* to TRUE to indicate that we're done after running or trying to
|
||||
@@ -183,187 +328,8 @@ int do_statusbar_input(bool *finished)
|
||||
return input;
|
||||
}
|
||||
|
||||
/* The user typed input_len multibyte characters. Add them to the answer,
|
||||
* filtering out ASCII control characters if filtering is TRUE. */
|
||||
void do_statusbar_output(int *the_input, size_t input_len,
|
||||
bool filtering)
|
||||
{
|
||||
char *output = charalloc(input_len + 1);
|
||||
char onechar[MAXCHARLEN];
|
||||
size_t charlen, i, j = 0;
|
||||
|
||||
/* Copy the typed stuff so it can be treated. */
|
||||
for (i = 0; i < input_len; i++)
|
||||
output[i] = (char)the_input[i];
|
||||
output[i] = '\0';
|
||||
|
||||
while (j < input_len) {
|
||||
/* Encode any NUL byte as 0x0A. */
|
||||
if (output[j] == '\0')
|
||||
output[j] = '\n';
|
||||
|
||||
/* Interpret the next multibyte character. */
|
||||
charlen = collect_char(output + j, onechar);
|
||||
|
||||
j += charlen;
|
||||
|
||||
/* When filtering, skip any ASCII control character. */
|
||||
if (filtering && is_ascii_cntrl_char(*(output + j - charlen)))
|
||||
continue;
|
||||
|
||||
/* Insert the typed character into the existing answer string. */
|
||||
answer = charealloc(answer, strlen(answer) + charlen + 1);
|
||||
memmove(answer + typing_x + charlen, answer + typing_x,
|
||||
strlen(answer) - typing_x + 1);
|
||||
strncpy(answer + typing_x, onechar, charlen);
|
||||
|
||||
typing_x += charlen;
|
||||
}
|
||||
|
||||
free(output);
|
||||
}
|
||||
|
||||
/* Move to the beginning of the answer. */
|
||||
void do_statusbar_home(void)
|
||||
{
|
||||
typing_x = 0;
|
||||
}
|
||||
|
||||
/* Move to the end of the answer. */
|
||||
void do_statusbar_end(void)
|
||||
{
|
||||
typing_x = strlen(answer);
|
||||
}
|
||||
|
||||
/* Move left one character. */
|
||||
void do_statusbar_left(void)
|
||||
{
|
||||
if (typing_x > 0)
|
||||
typing_x = step_left(answer, typing_x);
|
||||
}
|
||||
|
||||
/* Move right one character. */
|
||||
void do_statusbar_right(void)
|
||||
{
|
||||
if (answer[typing_x] != '\0')
|
||||
typing_x = step_right(answer, typing_x);
|
||||
}
|
||||
|
||||
/* Delete one character. */
|
||||
void do_statusbar_delete(void)
|
||||
{
|
||||
if (answer[typing_x] != '\0') {
|
||||
int charlen = char_length(answer + typing_x);
|
||||
|
||||
memmove(answer + typing_x, answer + typing_x + charlen,
|
||||
strlen(answer) - typing_x - charlen + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Backspace over one character. */
|
||||
void do_statusbar_backspace(void)
|
||||
{
|
||||
if (typing_x > 0) {
|
||||
typing_x = step_left(answer, typing_x);
|
||||
do_statusbar_delete();
|
||||
}
|
||||
}
|
||||
|
||||
/* Zap some or all text from the answer. */
|
||||
void do_statusbar_cut_text(void)
|
||||
{
|
||||
if (!ISSET(CUT_FROM_CURSOR))
|
||||
typing_x = 0;
|
||||
|
||||
answer[typing_x] = '\0';
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Move to the next word in the answer. */
|
||||
void do_statusbar_next_word(void)
|
||||
{
|
||||
bool seen_space = !is_word_mbchar(answer + typing_x, FALSE);
|
||||
bool seen_word = !seen_space;
|
||||
|
||||
/* Move forward until we reach either the end or the start of a word,
|
||||
* depending on whether the AFTER_ENDS flag is set or not. */
|
||||
while (answer[typing_x] != '\0') {
|
||||
typing_x = step_right(answer, typing_x);
|
||||
|
||||
if (ISSET(AFTER_ENDS)) {
|
||||
/* If this is a word character, continue; else it's a separator,
|
||||
* and if we've already seen a word, then it's a word end. */
|
||||
if (is_word_mbchar(answer + typing_x, FALSE))
|
||||
seen_word = TRUE;
|
||||
else if (seen_word)
|
||||
break;
|
||||
} else {
|
||||
/* If this is not a word character, then it's a separator; else
|
||||
* if we've already seen a separator, then it's a word start. */
|
||||
if (!is_word_mbchar(answer + typing_x, FALSE))
|
||||
seen_space = TRUE;
|
||||
else if (seen_space)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to the previous word in the answer. */
|
||||
void do_statusbar_prev_word(void)
|
||||
{
|
||||
bool seen_a_word = FALSE, step_forward = FALSE;
|
||||
|
||||
/* Move backward until we pass over the start of a word. */
|
||||
while (typing_x != 0) {
|
||||
typing_x = step_left(answer, typing_x);
|
||||
|
||||
if (is_word_mbchar(answer + typing_x, FALSE))
|
||||
seen_a_word = TRUE;
|
||||
else if (seen_a_word) {
|
||||
/* This is space now: we've overshot the start of the word. */
|
||||
step_forward = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (step_forward)
|
||||
/* Move one character forward again to sit on the start of the word. */
|
||||
typing_x = step_right(answer, typing_x);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Get verbatim input and inject it into the answer, without filtering. */
|
||||
void do_statusbar_verbatim_input(void)
|
||||
{
|
||||
int *kbinput;
|
||||
size_t kbinput_len;
|
||||
|
||||
kbinput = get_verbatim_kbinput(bottomwin, &kbinput_len);
|
||||
|
||||
do_statusbar_output(kbinput, kbinput_len, FALSE);
|
||||
|
||||
free(kbinput);
|
||||
}
|
||||
|
||||
/* Paste the first line of the cutbuffer into the current answer. */
|
||||
void do_statusbar_uncut_text(void)
|
||||
{
|
||||
size_t pastelen = strlen(cutbuffer->data);
|
||||
char *fusion = charalloc(strlen(answer) + pastelen + 1);
|
||||
|
||||
/* Concatenate: the current answer before the cursor, the first line
|
||||
* of the cutbuffer, plus the rest of the current answer. */
|
||||
strncpy(fusion, answer, typing_x);
|
||||
strncpy(fusion + typing_x, cutbuffer->data, pastelen);
|
||||
strcpy(fusion + typing_x + pastelen, answer + typing_x);
|
||||
|
||||
free(answer);
|
||||
answer = fusion;
|
||||
typing_x += pastelen;
|
||||
}
|
||||
|
||||
/* Return the column number of the first character of the answer that is
|
||||
* displayed in the statusbar when the cursor is at the given column,
|
||||
* displayed in the status bar when the cursor is at the given column,
|
||||
* with the available room for the answer starting at base. Note that
|
||||
* (0 <= column - get_statusbar_page_start(column) < COLS). */
|
||||
size_t get_statusbar_page_start(size_t base, size_t column)
|
||||
@@ -436,7 +402,7 @@ void add_or_remove_pipe_symbol_from_answer(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get a string of input at the statusbar prompt. */
|
||||
/* Get a string of input at the status-bar prompt. */
|
||||
functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
bool allow_files, bool *listed, linestruct **history_list,
|
||||
void (*refresh_func)(void))
|
||||
@@ -494,7 +460,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
if (func == do_tab) {
|
||||
#ifdef ENABLE_HISTORIES
|
||||
if (history_list != NULL) {
|
||||
if (last_kbinput != the_code_for(do_tab, TAB_CODE))
|
||||
if (last_kbinput != the_code_for(do_tab, '\t'))
|
||||
complete_len = strlen(answer);
|
||||
|
||||
if (complete_len > 0) {
|
||||
@@ -543,14 +509,18 @@ 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. */
|
||||
* the status-bar prompt. */
|
||||
finished = FALSE;
|
||||
}
|
||||
#ifndef NANO_TINY
|
||||
else if (func == do_nothing)
|
||||
finished = FALSE;
|
||||
#endif
|
||||
|
||||
/* If we have a shortcut with an associated function, break out if
|
||||
* we're finished after running or trying to run the function. */
|
||||
@@ -575,7 +545,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
return func;
|
||||
}
|
||||
|
||||
/* Ask a question on the statusbar. Return 0 when text was entered,
|
||||
/* Ask a question on the status bar. Return 0 when text was entered,
|
||||
* -1 for a cancelled entry, -2 for a blank string, and the relevant
|
||||
* keycode when a valid shortcut key was pressed.
|
||||
*
|
||||
@@ -591,7 +561,7 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
||||
int retval;
|
||||
functionptrtype func = NULL;
|
||||
bool listed = FALSE;
|
||||
/* Save a possible current statusbar x position and prompt. */
|
||||
/* Save a possible current status-bar x position and prompt. */
|
||||
size_t was_typing_x = typing_x;
|
||||
char *saved_prompt = prompt;
|
||||
|
||||
@@ -645,7 +615,7 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
||||
}
|
||||
|
||||
/* Ask a simple Yes/No (and optionally All) question, specified in msg,
|
||||
* on the statusbar. Return 1 for Yes, 0 for No, 2 for All (if all is
|
||||
* on the status bar. Return 1 for Yes, 0 for No, 2 for All (if all is
|
||||
* TRUE when passed in), and -1 for Cancel. */
|
||||
int do_yesno_prompt(bool all, const char *msg)
|
||||
{
|
||||
@@ -707,6 +677,12 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
/* When not replacing, show the cursor while waiting for a key. */
|
||||
kbinput = get_kbinput(bottomwin, !all);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Accept the first character of an external paste. */
|
||||
if (bracketed_paste && kbinput == BRACKETED_PASTE_MARKER)
|
||||
kbinput = get_kbinput(bottomwin, BLIND);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
letter[index++] = (unsigned char)kbinput;
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -762,6 +738,14 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_MOUSE */
|
||||
else
|
||||
beep();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Ignore the rest of an external paste. */
|
||||
while (bracketed_paste)
|
||||
kbinput = get_kbinput(bottomwin, BLIND);
|
||||
#endif
|
||||
}
|
||||
|
||||
return choice;
|
||||
|
||||
135
src/proto.h
135
src/proto.h
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* proto.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -27,9 +27,19 @@ extern volatile sig_atomic_t the_window_resized;
|
||||
#endif
|
||||
|
||||
extern bool on_a_vt;
|
||||
extern bool shifted_metas;
|
||||
|
||||
extern bool meta_key;
|
||||
extern bool shift_held;
|
||||
extern bool mute_modifiers;
|
||||
extern bool bracketed_paste;
|
||||
|
||||
extern bool started_curses;
|
||||
extern bool we_are_running;
|
||||
extern bool more_than_one;
|
||||
|
||||
extern bool inhelp;
|
||||
extern char *title;
|
||||
|
||||
extern bool focusing;
|
||||
|
||||
@@ -39,23 +49,21 @@ extern bool control_C_was_pressed;
|
||||
|
||||
extern bool suppress_cursorpos;
|
||||
|
||||
extern bool started_curses;
|
||||
|
||||
extern message_type lastmessage;
|
||||
|
||||
extern linestruct *pletion_line;
|
||||
|
||||
extern bool inhelp;
|
||||
extern char *title;
|
||||
|
||||
extern bool more_than_one;
|
||||
|
||||
extern bool also_the_last;
|
||||
|
||||
extern bool is_shorter;
|
||||
extern char *answer;
|
||||
|
||||
extern char *last_search;
|
||||
extern int didfind;
|
||||
|
||||
extern char *present_path;
|
||||
|
||||
extern unsigned flags[4];
|
||||
|
||||
extern int controlleft, controlright;
|
||||
extern int controlup, controldown;
|
||||
extern int controlhome, controlend;
|
||||
@@ -78,12 +86,6 @@ extern ssize_t fill;
|
||||
extern size_t wrap_at;
|
||||
#endif
|
||||
|
||||
extern char *last_search;
|
||||
|
||||
extern char *present_path;
|
||||
|
||||
extern unsigned flags[4];
|
||||
|
||||
extern WINDOW *topwin;
|
||||
extern WINDOW *edit;
|
||||
extern WINDOW *bottomwin;
|
||||
@@ -120,14 +122,10 @@ extern regex_t quotereg;
|
||||
|
||||
extern char *word_chars;
|
||||
|
||||
extern char *answer;
|
||||
|
||||
extern ssize_t tabsize;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern char *backup_dir;
|
||||
extern const char *locking_prefix;
|
||||
extern const char *locking_suffix;
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
extern char *operating_dir;
|
||||
@@ -176,6 +174,9 @@ extern char *statedir;
|
||||
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
||||
extern char *startup_problem;
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
extern char *custom_nanorc;
|
||||
#endif
|
||||
|
||||
extern bool spotlighted;
|
||||
extern size_t light_from_col;
|
||||
@@ -202,13 +203,10 @@ char *strip_last_component(const char *path);
|
||||
void utf8_init(void);
|
||||
bool using_utf8(void);
|
||||
#endif
|
||||
char *addstrings(char* str1, size_t len1, char* str2, size_t len2);
|
||||
bool is_byte(int c);
|
||||
bool is_alpha_mbchar(const char *c);
|
||||
bool is_blank_mbchar(const char *c);
|
||||
bool is_ascii_cntrl_char(int c);
|
||||
bool is_cntrl_mbchar(const char *c);
|
||||
bool is_word_mbchar(const char *c, bool allow_punct);
|
||||
bool is_alpha_char(const char *c);
|
||||
bool is_blank_char(const char *c);
|
||||
bool is_cntrl_char(const char *c);
|
||||
bool is_word_char(const char *c, bool allow_punct);
|
||||
char control_mbrep(const char *c, bool isdata);
|
||||
#ifdef ENABLE_UTF8
|
||||
int mbwidth(const char *c);
|
||||
@@ -257,10 +255,15 @@ void do_backspace(void);
|
||||
#ifndef NANO_TINY
|
||||
void chop_previous_word(void);
|
||||
void chop_next_word(void);
|
||||
#endif
|
||||
void extract_segment(linestruct *top, size_t top_x,
|
||||
linestruct *bot, size_t bot_x);
|
||||
void ingraft_buffer(linestruct *somebuffer);
|
||||
void copy_from_buffer(linestruct *somebuffer);
|
||||
#ifndef NANO_TINY
|
||||
void cut_marked(bool *right_side_up);
|
||||
#endif
|
||||
void do_snip(bool copying, bool marked, bool until_eof, bool append);
|
||||
bool is_cuttable(bool test_cliff);
|
||||
void cut_text(void);
|
||||
#ifndef NANO_TINY
|
||||
void copy_text(void);
|
||||
@@ -271,12 +274,11 @@ void paste_text(void);
|
||||
|
||||
/* Most functions in files.c. */
|
||||
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,
|
||||
const char *operation);
|
||||
#ifndef NANO_TINY
|
||||
bool delete_lockfile(const char *lockfilename);
|
||||
#endif
|
||||
bool open_buffer(const char *filename, bool new_buffer);
|
||||
void set_modified(void);
|
||||
void prepare_for_display(void);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void mention_name_and_linecount(void);
|
||||
@@ -296,8 +298,6 @@ bool outside_of_confinement(const char *currpath, bool allow_tabcomp);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void init_backup_dir(void);
|
||||
int delete_lockfile(const char *lockfilename);
|
||||
int write_lockfile(const char *lockfilename, const char *origfilename, bool modified);
|
||||
#endif
|
||||
int copy_file(FILE *inn, FILE *out, bool close_out);
|
||||
bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
@@ -324,25 +324,20 @@ int the_code_for(void (*func)(void), int defaultval);
|
||||
size_t shown_entries_for(int menu);
|
||||
const keystruct *get_shortcut(int *kbinput);
|
||||
functionptrtype func_from_key(int *kbinput);
|
||||
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
||||
functionptrtype interpret(int *keycode);
|
||||
#endif
|
||||
int keycode_from_string(const char *keystring);
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode);
|
||||
void shortcut_init(void);
|
||||
const char *flagtostr(int flag);
|
||||
#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
|
||||
@@ -372,15 +367,15 @@ void do_page_down(void);
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
void do_para_begin(linestruct **line);
|
||||
void do_para_end(linestruct **line);
|
||||
void do_para_begin_void(void);
|
||||
void do_para_end_void(void);
|
||||
void to_para_begin(void);
|
||||
void to_para_end(void);
|
||||
#endif
|
||||
void do_prev_block(void);
|
||||
void do_next_block(void);
|
||||
void to_prev_block(void);
|
||||
void to_next_block(void);
|
||||
void do_prev_word(bool allow_punct);
|
||||
bool do_next_word(bool after_ends, bool allow_punct);
|
||||
void do_prev_word_void(void);
|
||||
void do_next_word_void(void);
|
||||
void to_prev_word(void);
|
||||
void to_next_word(void);
|
||||
void do_home(void);
|
||||
void do_end(void);
|
||||
void do_up(void);
|
||||
@@ -401,11 +396,8 @@ linestruct *copy_buffer(const linestruct *src);
|
||||
void free_lines(linestruct *src);
|
||||
void renumber_from(linestruct *line);
|
||||
void partition_buffer(linestruct *top, size_t top_x,
|
||||
linestruct *bot, size_t bot_x);
|
||||
linestruct *bot, size_t bot_x);
|
||||
void unpartition_buffer(void);
|
||||
void extract(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x);
|
||||
void ingraft_buffer(linestruct *somebuffer);
|
||||
void copy_from_buffer(linestruct *somebuffer);
|
||||
void print_view_warning(void);
|
||||
bool in_restricted_mode(void);
|
||||
#ifndef ENABLE_HELP
|
||||
@@ -444,23 +436,9 @@ void confirm_margin(void);
|
||||
#endif
|
||||
void unbound_key(int code);
|
||||
bool okay_for_view(const keystruct *shortcut);
|
||||
void do_output(char *output, size_t output_len, bool allow_cntrls);
|
||||
void inject(char *burst, size_t count);
|
||||
|
||||
/* Most functions in prompt.c. */
|
||||
void do_statusbar_output(int *the_input, size_t input_len, bool filtering);
|
||||
void do_statusbar_home(void);
|
||||
void do_statusbar_end(void);
|
||||
void do_statusbar_left(void);
|
||||
void do_statusbar_right(void);
|
||||
void do_statusbar_backspace(void);
|
||||
void do_statusbar_delete(void);
|
||||
void do_statusbar_cut_text(void);
|
||||
void do_statusbar_uncut_text(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_statusbar_prev_word(void);
|
||||
void do_statusbar_next_word(void);
|
||||
#endif
|
||||
void do_statusbar_verbatim_input(void);
|
||||
size_t get_statusbar_page_start(size_t start_col, size_t column);
|
||||
void put_cursor_at_end_of_answer(void);
|
||||
void add_or_remove_pipe_symbol_from_answer(void);
|
||||
@@ -524,9 +502,7 @@ void do_undo(void);
|
||||
void do_redo(void);
|
||||
void do_enter(void);
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE cancel_command(int signal);
|
||||
bool execute_command(const char *command);
|
||||
void discard_until(const undostruct *thisitem, openfilestruct *thefile, bool keep);
|
||||
void discard_until(const undostruct *thisitem);
|
||||
void add_undo(undo_type action, const char *message);
|
||||
void update_multiline_undo(ssize_t lineno, char *indentation);
|
||||
void update_undo(undo_type action);
|
||||
@@ -537,7 +513,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
|
||||
@@ -596,6 +572,7 @@ void new_magicline(void);
|
||||
void remove_magicline(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
bool mark_is_before_cursor(void);
|
||||
void get_region(const linestruct **top, size_t *top_x,
|
||||
const linestruct **bot, size_t *bot_x, bool *right_side_up);
|
||||
void get_range(const linestruct **top, const linestruct **bot);
|
||||
@@ -609,19 +586,14 @@ linestruct *line_from_number(ssize_t lineno);
|
||||
void record_macro(void);
|
||||
void run_macro(void);
|
||||
size_t get_key_buffer_len(void);
|
||||
void put_back(int keycode);
|
||||
void unget_kbinput(int kbinput, bool metakey);
|
||||
#ifdef ENABLE_NANORC
|
||||
void implant(const char *string);
|
||||
#endif
|
||||
int get_kbinput(WINDOW *win, bool showcursor);
|
||||
int parse_kbinput(WINDOW *win);
|
||||
int arrow_from_abcd(int kbinput);
|
||||
int parse_escape_sequence(WINDOW *win, int kbinput);
|
||||
int get_kbinput(WINDOW *win, bool showcursor);
|
||||
int get_byte_kbinput(int kbinput);
|
||||
int get_control_kbinput(int kbinput);
|
||||
int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
|
||||
int *parse_verbatim_kbinput(WINDOW *win, size_t *count);
|
||||
char *get_verbatim_kbinput(WINDOW *win, size_t *count);
|
||||
#ifdef ENABLE_MOUSE
|
||||
int get_mouseinput(int *mouse_row, int *mouse_col, bool allow_shortcuts);
|
||||
#endif
|
||||
@@ -683,10 +655,11 @@ void backwards_void(void);
|
||||
void flip_replace(void);
|
||||
void flip_goto(void);
|
||||
#ifdef ENABLE_BROWSER
|
||||
void to_files_void(void);
|
||||
void goto_dir_void(void);
|
||||
void to_files(void);
|
||||
void goto_dir(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_nothing(void);
|
||||
void do_toggle_void(void);
|
||||
void dos_format_void(void);
|
||||
void mac_format_void(void);
|
||||
|
||||
761
src/rcfile.c
761
src/rcfile.c
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* search.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2018 Benno Schulenberg *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -519,8 +519,6 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
linestruct *top, *bot;
|
||||
size_t top_x, bot_x;
|
||||
bool right_side_up = FALSE;
|
||||
/* TRUE if (mark_begin, mark_begin_x) is the top of the mark,
|
||||
* FALSE if (current, current_x) is. */
|
||||
|
||||
/* If the mark is on, frame the region, and turn the mark off. */
|
||||
if (openfile->mark) {
|
||||
|
||||
1482
src/text.c
1482
src/text.c
File diff suppressed because it is too large
Load Diff
28
src/utils.c
28
src/utils.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* utils.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2019 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2017, 2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -209,8 +209,8 @@ bool is_separate_word(size_t position, size_t length, const char *buf)
|
||||
/* If the word starts at the beginning of the line OR the character before
|
||||
* the word isn't a letter, and if the word ends at the end of the line OR
|
||||
* the character after the word isn't a letter, we have a whole word. */
|
||||
return ((position == 0 || !is_alpha_mbchar(before)) &&
|
||||
(buf[word_end] == '\0' || !is_alpha_mbchar(after)));
|
||||
return ((position == 0 || !is_alpha_char(before)) &&
|
||||
(buf[word_end] == '\0' || !is_alpha_char(after)));
|
||||
}
|
||||
#endif /* ENABLE_SPELLER */
|
||||
|
||||
@@ -324,12 +324,14 @@ char *mallocstrcpy(char *dest, const char *src)
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* Return an allocated copy of the first count characters of the given string. */
|
||||
/* Return an allocated copy of the first count characters
|
||||
* of the given string, and NUL-terminate the copy. */
|
||||
char *measured_copy(const char *string, size_t count)
|
||||
{
|
||||
char *thecopy = charalloc(count);
|
||||
char *thecopy = charalloc(count + 1);
|
||||
|
||||
strncpy(thecopy, string, count);
|
||||
thecopy[count] = '\0';
|
||||
|
||||
return thecopy;
|
||||
}
|
||||
@@ -337,7 +339,7 @@ char *measured_copy(const char *string, size_t count)
|
||||
/* Return an allocated copy of the given string. */
|
||||
char *copy_of(const char *string)
|
||||
{
|
||||
return measured_copy(string, strlen(string) + 1);
|
||||
return measured_copy(string, strlen(string));
|
||||
}
|
||||
|
||||
/* Free the string at dest and return the string at src. */
|
||||
@@ -448,15 +450,21 @@ void remove_magicline(void)
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Return TRUE when the mark is before or at the cursor, and FALSE otherwise. */
|
||||
bool mark_is_before_cursor(void)
|
||||
{
|
||||
return (openfile->mark->lineno < openfile->current->lineno ||
|
||||
(openfile->mark == openfile->current &&
|
||||
openfile->mark_x <= openfile->current_x));
|
||||
}
|
||||
|
||||
/* Return in (top, top_x) and (bot, bot_x) the start and end "coordinates"
|
||||
* of the marked region. If right_side_up isn't NULL, set it to TRUE when
|
||||
* the mark is at the top of the marked region, and to FALSE otherwise. */
|
||||
void get_region(const linestruct **top, size_t *top_x,
|
||||
const linestruct **bot, size_t *bot_x, bool *right_side_up)
|
||||
{
|
||||
if (openfile->mark->lineno < openfile->current->lineno ||
|
||||
(openfile->mark == openfile->current &&
|
||||
openfile->mark_x < openfile->current_x)) {
|
||||
if (mark_is_before_cursor()) {
|
||||
*top = openfile->mark;
|
||||
*top_x = openfile->mark_x;
|
||||
*bot = openfile->current;
|
||||
|
||||
1573
src/winio.c
1573
src/winio.c
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
syntax nanohelp
|
||||
|
||||
# Key combos:
|
||||
color cyan "\^[]4-8A-Z^\_◀▶▲▼]" "[◀▶▲▼]" "\<M-." "\<F1?[0-9]"
|
||||
color cyan "\^[]/4-8@A-Z\^_`◀▶▲▼]" "[◀▶▲▼]" "\<(M|S[Hh]-[Mm])-." "\<F([1-9]|1[0-9]|2[0-4])"
|
||||
color cyan "\<((Sh-)?Tab|Enter|Ins|(Sh-\^?)?Del|Space|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
|
||||
|
||||
# Quoted indicators:
|
||||
|
||||
@@ -7,12 +7,12 @@ comment "#"
|
||||
color brightred ".*"
|
||||
|
||||
# Keywords
|
||||
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 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|rawsequences|rebinddelete|regexp|showcursor|smarthome|smooth|softwrap|suspendable|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:]]*bind[[:space:]]+((\^([A-Za-z]|[]/@\^_`]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+([a-z]+|".*")[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
color brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([A-Za-z]|[]/@\^_`]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
color brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|formatter|linter|tabgives)[[:space:]]+.*"
|
||||
color brightgreen "^[[:space:]]*(syntax[[:space:]]+[^[:blank:]]+|(formatter|linter)[[:space:]]+.+)"
|
||||
color green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|formatter|linter|tabgives|extendsyntax)\>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## 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"
|
||||
comment "#"
|
||||
|
||||
@@ -4,20 +4,17 @@ syntax spec "\.spec(\.[^/]+)?$"
|
||||
comment "#"
|
||||
|
||||
# Main tags.
|
||||
color brightblue "((Icon|ExclusiveOs|ExcludeOs)[[:space:]]*:)"
|
||||
color brightblue "((BuildArch|BuildArchitectures|ExclusiveArch|ExcludeArch)[[:space:]]*:)"
|
||||
color brightblue "((Conflicts|Obsoletes|Provides|Requires|Requires\(.*\)|Enhances|Suggests|BuildConflicts|BuildRequires|Recommends|PreReq|Supplements)[[:space:]]*:)"
|
||||
color brightblue "((Epoch|Serial|Nosource|Nopatch)[[:space:]]*:)"
|
||||
color brightblue "((AutoReq|AutoProv|AutoReqProv)[[:space:]]*:)"
|
||||
color brightblue "((Copyright|License|Summary|Summary\(.*\)|Distribution|Vendor|Packager|Group|Source\d*|Patch\d*|BuildRoot|Prefix)[[:space:]]*:)"
|
||||
color brightblue "((Name|Version|Release|Url|URL)[[:space:]]*:)"
|
||||
color brightblue start="^Source" end=":" start="^Patch" end=":"
|
||||
color brightblue "\<(Name|Version|Release|Summary|Group|URL|Url|Epoch|Icon|Serial)[[:space:]]*:"
|
||||
color brightblue "\<(BuildArch(itectures)?|Exclusive(Arch|OS)|Exclude(Arch|OS))[[:space:]]*:"
|
||||
color brightblue "\<(Provides|Requires(\(.*\))?|Obsoletes|Conflicts|Recommends|Suggests|Supplements|Enhances|PreReq)[[:space:]]*:"
|
||||
color brightblue "\<(BuildRoot|BuildRequires|BuildConflicts|Prefix|RemovePathPostfixes)[[:space:]]*:"
|
||||
color brightblue "\<(AutoReq|AutoProv|AutoReqProv)[[:space:]]*:"
|
||||
color brightblue "\<(License|Copyright|Distribution|Vendor|Packager)[[:space:]]*:"
|
||||
color brightblue "\<((Source|Patch)[0-9]*|Nosource|Nopatch)[[:space:]]*:"
|
||||
# Architectures.
|
||||
color brightred "(i386|i486|i586|i686|athlon|ia64|alpha|alphaev5|alphaev56|alphapca56|alphaev6|alphaev67|sparc|sparcv9|sparc64armv3l|armv4b|armv4lm|ips|mipsel|ppc|ppc|iseries|ppcpseries|ppc64|m68k|m68kmint|Sgi|rs6000|i370|s390x|s390|noarch)"
|
||||
# Architecture conditionals.
|
||||
color brightred "(ifarch|ifnarch)"
|
||||
# OS conditionals.
|
||||
color brightred "(ifos|ifnos)"
|
||||
color brightred "\<(i386|i486|i586|i686|athlon|ia64|alpha|alphaev5|alphaev56|alphapca56|alphaev6|alphaev67|sparc|sparcv9|sparc64armv3l|armv4b|armv4lm|ips|mipsel|ppc|ppciseries|ppcpseries|ppc64|m68k|m68kmint|Sgi|rs6000|i370|s390x?|noarch)\>"
|
||||
# Architecture and OS conditionals.
|
||||
color brightred "%(ifarch|elifarch|ifnarch|ifos|elifos|ifnos)\>"
|
||||
# %* strings.
|
||||
color green "%([A-Z_a-z_0-9_]*)"
|
||||
color magenta "%_([A-Z_a-z_0-9_]*)"
|
||||
@@ -25,16 +22,20 @@ color yellow start="%__" end="\ "
|
||||
color magenta start="%\{" end="\}"
|
||||
color yellow start="%\{__" end="\}"
|
||||
# Sections.
|
||||
color red "^%(build$|changelog|check$|clean$|description|files|install$|package|pre|prep$|pretrans|preun)"
|
||||
color red "^%(post|posttrans|postun|trigger|triggerin|triggerpostun|triggerun|verifyscript)"
|
||||
color red "^%((prep|build|install|check|clean)$|(description|files|package|changelog)\>)"
|
||||
color red "^%((pre|post)(trans|un)?|trigger(prein|in|un|postun)?)\>"
|
||||
color red "^%(trans)?filetrigger(in|un|postun)\>"
|
||||
color red "^%(sourcelist|patchlist|generate_buildrequires|verifyscript)\>"
|
||||
# Conditionals and defines.
|
||||
color brightred "%(if|else|endif|define|global|undefine)"
|
||||
color brightred "%(if|elif|else|endif|define|global|undefine)\>"
|
||||
|
||||
# Comments.
|
||||
color cyan "#.*"
|
||||
color cyan "(#|%dnl[[:space:]]).*"
|
||||
# Special case: "# norootforbuild" is handled as main tag.
|
||||
color brightblue "^# norootforbuild"
|
||||
# %changelog date entries.
|
||||
color brightyellow "^\* .*\)$"
|
||||
# For %changelog entries: first the author, then just the date.
|
||||
color yellow "^\* .+>"
|
||||
color brightyellow "^\* [[:alnum:] ]+ [0-9]{4} "
|
||||
|
||||
# Trailing whitespace.
|
||||
color ,green "[[:space:]]+$"
|
||||
|
||||
Reference in New Issue
Block a user