Compare commits
350 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06c3e1acde | ||
|
|
09d8ee82b7 | ||
|
|
dac3b25d16 | ||
|
|
ca538e6f08 | ||
|
|
4b26308b6a | ||
|
|
f5eeb92f40 | ||
|
|
ae1ba5e259 | ||
|
|
cecf453b14 | ||
|
|
c3a02f8094 | ||
|
|
87283711ee | ||
|
|
123f77ff1a | ||
|
|
10c49edd3b | ||
|
|
2d5c917b1a | ||
|
|
95002da66c | ||
|
|
858663444e | ||
|
|
4046dfca63 | ||
|
|
c0b15c2982 | ||
|
|
e889c28a95 | ||
|
|
0da554e6d7 | ||
|
|
f1530c7ba0 | ||
|
|
0e46c0f4a5 | ||
|
|
6a064503e5 | ||
|
|
4d92dffb3a | ||
|
|
4c1c425bbb | ||
|
|
21a54a3cf6 | ||
|
|
a0147c5a72 | ||
|
|
553940760e | ||
|
|
faa0eb991e | ||
|
|
f54cd02652 | ||
|
|
6dd308d0fb | ||
|
|
4872f42cd2 | ||
|
|
62007c84c6 | ||
|
|
d0f37205af | ||
|
|
f05874ea23 | ||
|
|
0d9080a22c | ||
|
|
1ae90e205a | ||
|
|
d53086d38d | ||
|
|
0b6bb37c56 | ||
|
|
c43a6fdcc1 | ||
|
|
0c613cb1ac | ||
|
|
1e5064ef84 | ||
|
|
5b40bad629 | ||
|
|
45f8fc77e0 | ||
|
|
94347f0811 | ||
|
|
1a4a3de68b | ||
|
|
bf8bd02558 | ||
|
|
544d426d86 | ||
|
|
30a984661b | ||
|
|
7ab8a4d835 | ||
|
|
0353a24400 | ||
|
|
d4304ca88c | ||
|
|
02d8da3bdd | ||
|
|
7a09b655c1 | ||
|
|
c8b26baee8 | ||
|
|
bb394990cd | ||
|
|
7c5d099c6f | ||
|
|
152cc24d1f | ||
|
|
8965103a4d | ||
|
|
d0d293b8af | ||
|
|
839743fd24 | ||
|
|
0b30835dd0 | ||
|
|
a865c25eea | ||
|
|
cf1129a8b4 | ||
|
|
0cd833e64b | ||
|
|
cbf226476d | ||
|
|
9fcfee18e8 | ||
|
|
27eccbec23 | ||
|
|
0bce5ba4d9 | ||
|
|
f9415e347a | ||
|
|
f3c4dadcf6 | ||
|
|
20d1823d90 | ||
|
|
e01bcddf16 | ||
|
|
570fb6c606 | ||
|
|
1de3667555 | ||
|
|
5726514869 | ||
|
|
88234c90bc | ||
|
|
02719ec4bf | ||
|
|
415bf82690 | ||
|
|
9bce8bfeb3 | ||
|
|
2c024a74a9 | ||
|
|
ab8698df47 | ||
|
|
206d89b739 | ||
|
|
eff2e0e291 | ||
|
|
c5e20164c3 | ||
|
|
0f1f53a441 | ||
|
|
bf1a080923 | ||
|
|
b7f8d4819b | ||
|
|
30fc197b66 | ||
|
|
c88a2fd9ca | ||
|
|
b9de5525c4 | ||
|
|
f4d1ef1c4e | ||
|
|
dd157f1494 | ||
|
|
624918800b | ||
|
|
8b8c6bb818 | ||
|
|
b830a7dd38 | ||
|
|
3e5b0ea5fd | ||
|
|
a1132c81a1 | ||
|
|
0496aed4ab | ||
|
|
373e3b880f | ||
|
|
7b1f3f4fe7 | ||
|
|
9517972b58 | ||
|
|
95989e7dfe | ||
|
|
dcda98fb73 | ||
|
|
336fa40055 | ||
|
|
93318b972d | ||
|
|
8656f160d7 | ||
|
|
0e30177db7 | ||
|
|
3089a98169 | ||
|
|
1b704e7c8c | ||
|
|
efb9192ee5 | ||
|
|
f0734dae3e | ||
|
|
e8505b2d3e | ||
|
|
1ebb1da382 | ||
|
|
1fb3218a14 | ||
|
|
a7b1f0f03f | ||
|
|
c782b4cb72 | ||
|
|
5234475781 | ||
|
|
80605c3918 | ||
|
|
d3012be095 | ||
|
|
03bc19fd0c | ||
|
|
e4cef3086b | ||
|
|
9936a6357a | ||
|
|
899bf0ae3a | ||
|
|
1f7384ebd2 | ||
|
|
95fffa99aa | ||
|
|
22f7861694 | ||
|
|
ba96d507dd | ||
|
|
9bf57e5ca0 | ||
|
|
f9103a5cb5 | ||
|
|
e9eabdcdcb | ||
|
|
a1be8b6a19 | ||
|
|
de4fbadf20 | ||
|
|
bdd8920081 | ||
|
|
ae9ec6d4ad | ||
|
|
8f1a657a37 | ||
|
|
7f88eff96f | ||
|
|
3b8c898880 | ||
|
|
6f4f1878fc | ||
|
|
082e5db4b7 | ||
|
|
5eccaa7633 | ||
|
|
d9ac785a07 | ||
|
|
01457ae3d3 | ||
|
|
c757aee235 | ||
|
|
48749a9500 | ||
|
|
4cd3987791 | ||
|
|
aa41eb69c0 | ||
|
|
54103d8ed1 | ||
|
|
53a10ddcaf | ||
|
|
65bf04060b | ||
|
|
a95fb64dd6 | ||
|
|
b235404ade | ||
|
|
ffebd31cbb | ||
|
|
e55227f65f | ||
|
|
b77b54bf73 | ||
|
|
2428620b16 | ||
|
|
cb0289f0dc | ||
|
|
b027263a37 | ||
|
|
1a926d79c5 | ||
|
|
c79fe1a160 | ||
|
|
fef195bce9 | ||
|
|
dd9766c2e0 | ||
|
|
5b870a7632 | ||
|
|
0cf455bc48 | ||
|
|
3e1fc6385b | ||
|
|
544cda6a62 | ||
|
|
28933cf572 | ||
|
|
1635060ba6 | ||
|
|
7a038adfd4 | ||
|
|
f1b5be4bbf | ||
|
|
9ceeabda38 | ||
|
|
204e1b8353 | ||
|
|
d865d7ac8f | ||
|
|
16d237ba1b | ||
|
|
c3031b9b8f | ||
|
|
d289510724 | ||
|
|
60f1090da0 | ||
|
|
8f6ee22b41 | ||
|
|
a083d7f1e1 | ||
|
|
919df09ffa | ||
|
|
ddbff6dcb2 | ||
|
|
4295baa5fe | ||
|
|
467cc8edf3 | ||
|
|
6d111c9343 | ||
|
|
bb667beb5a | ||
|
|
eed765f4f7 | ||
|
|
361267cf25 | ||
|
|
ed493bb99b | ||
|
|
ae7366616f | ||
|
|
58ed3a8152 | ||
|
|
e11021a7a5 | ||
|
|
83c264939b | ||
|
|
d48f3e5e7b | ||
|
|
b18e76d4d8 | ||
|
|
f5c87a7fee | ||
|
|
90ebff00ca | ||
|
|
cdc9a29598 | ||
|
|
ddc1de1939 | ||
|
|
18bf2af9c1 | ||
|
|
452008c81d | ||
|
|
97cbbb0cc8 | ||
|
|
7b9bd65362 | ||
|
|
f72fecee9b | ||
|
|
97a8a62128 | ||
|
|
f095e20a86 | ||
|
|
fa7e9b11df | ||
|
|
838b175d4f | ||
|
|
ba1f990582 | ||
|
|
6795d079b1 | ||
|
|
e739448cd0 | ||
|
|
8e328e43c2 | ||
|
|
cb56a575fd | ||
|
|
a429dc4a76 | ||
|
|
91073be49c | ||
|
|
d5f9be7dc8 | ||
|
|
4ad0490ce4 | ||
|
|
d85098abda | ||
|
|
13f8ddcaf2 | ||
|
|
37e9ada964 | ||
|
|
a99158c7c0 | ||
|
|
3981217e5a | ||
|
|
96b47f2877 | ||
|
|
7da391beb7 | ||
|
|
90cf4838d2 | ||
|
|
4c7ec18a55 | ||
|
|
704a7d7b4f | ||
|
|
64366d9992 | ||
|
|
bd97ae7255 | ||
|
|
2ff398c685 | ||
|
|
4b24ce1c11 | ||
|
|
00c1105c1b | ||
|
|
6a4d88cb4c | ||
|
|
898c4c6fbb | ||
|
|
c1bb6485de | ||
|
|
4bcce96a4f | ||
|
|
caeed6821c | ||
|
|
eb1bf8f927 | ||
|
|
2c8b99d5e9 | ||
|
|
091dd71f08 | ||
|
|
837475519b | ||
|
|
31540e3e7e | ||
|
|
ae3b8579fa | ||
|
|
e1199cd94d | ||
|
|
45d2458b47 | ||
|
|
4c505e5127 | ||
|
|
e3b13ae124 | ||
|
|
e5440b390e | ||
|
|
2a17527381 | ||
|
|
8067efa6cc | ||
|
|
0bb6c0234f | ||
|
|
7947d9d2a5 | ||
|
|
c9ccb39752 | ||
|
|
ada78dc89d | ||
|
|
c6f367268b | ||
|
|
084dda3837 | ||
|
|
30f367e0db | ||
|
|
5965e80a38 | ||
|
|
a794c3318b | ||
|
|
d04b0c123e | ||
|
|
21cd953e85 | ||
|
|
058b9da9b9 | ||
|
|
38a10a62d0 | ||
|
|
091e8faf6d | ||
|
|
d8ea89f6a6 | ||
|
|
1f48ed0412 | ||
|
|
b18bcbbe9f | ||
|
|
920730f1aa | ||
|
|
9506b51101 | ||
|
|
918d0e71ab | ||
|
|
484a199175 | ||
|
|
17429d7f38 | ||
|
|
87206c0607 | ||
|
|
b574f73e60 | ||
|
|
eac90c3eff | ||
|
|
440a128d25 | ||
|
|
4f2b01c7e5 | ||
|
|
12073001c2 | ||
|
|
4c20135749 | ||
|
|
f9ebf038e0 | ||
|
|
62ebd93579 | ||
|
|
a10fdc3fb1 | ||
|
|
8581e702d6 | ||
|
|
bdbd5ff0e7 | ||
|
|
f769465284 | ||
|
|
1b5b52d2e4 | ||
|
|
ab62d28817 | ||
|
|
8e0a7ec20d | ||
|
|
23d66949e1 | ||
|
|
184bb11fd9 | ||
|
|
a70db34fc9 | ||
|
|
fbde1b2d71 | ||
|
|
c22fef18e4 | ||
|
|
ee5b250b66 | ||
|
|
fb85c05594 | ||
|
|
25b1114e03 | ||
|
|
4b8a387529 | ||
|
|
df41114e0e | ||
|
|
dc3618a127 | ||
|
|
31fe0753e3 | ||
|
|
7ad5afb935 | ||
|
|
e1b0f2b275 | ||
|
|
0e0fb452a3 | ||
|
|
f66432e999 | ||
|
|
08e9d30fa2 | ||
|
|
d2270e514b | ||
|
|
031305c205 | ||
|
|
e2843ede7e | ||
|
|
09958ebdff | ||
|
|
53fc9a66a6 | ||
|
|
a95c6c5fe8 | ||
|
|
bcd187d7d6 | ||
|
|
03783a7d1b | ||
|
|
f2fb8c01f4 | ||
|
|
ddb8e95d39 | ||
|
|
fbac4505ce | ||
|
|
eb937f81fa | ||
|
|
5144162a2d | ||
|
|
b4411b4f28 | ||
|
|
29f7654ab1 | ||
|
|
66fd6a5ab1 | ||
|
|
c30d3d8010 | ||
|
|
0c40f87b55 | ||
|
|
4761e00852 | ||
|
|
0133d5cba8 | ||
|
|
9066a96dde | ||
|
|
6abb551fdd | ||
|
|
97bdf13b59 | ||
|
|
dae88f8dc7 | ||
|
|
64d1711a24 | ||
|
|
b9638cb7cc | ||
|
|
d646a3b97b | ||
|
|
800a997008 | ||
|
|
c17a8a9836 | ||
|
|
20aa167c14 | ||
|
|
0c9905dbd0 | ||
|
|
73c7f1cbdc | ||
|
|
4200ed3003 | ||
|
|
2b314ed18f | ||
|
|
88a0bb9685 | ||
|
|
1e718cec35 | ||
|
|
5487551ce9 | ||
|
|
763bf2ed26 | ||
|
|
cf63a2910a | ||
|
|
7c3c942097 | ||
|
|
77d24300f3 | ||
|
|
d33b5f3dab | ||
|
|
c24e95e3d6 | ||
|
|
c42489d946 | ||
|
|
2b438e6ef4 | ||
|
|
8165b20fc1 | ||
|
|
bacb0f717d |
416
ChangeLog
416
ChangeLog
@@ -1,3 +1,419 @@
|
||||
Changes between v2.9.6 and v2.9.7:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (21):
|
||||
bindings: add the 'linenumbers' bindable function
|
||||
bindings: rename constupdate to constantshow, cuttoend to cutfromcursor
|
||||
bump version numbers and add a news item for the 2.9.7 release
|
||||
docs: add notes about deprecated options and function names
|
||||
docs: break down some old improvements further per version
|
||||
docs: note a small difference with Pico in the default hard-wrapping
|
||||
docs: say thanks to three recent translators, and re-sort two others
|
||||
docs: slightly improve the description of the file browser in the manual
|
||||
main: clear a spurious error number, to avoid irrelevant messages later
|
||||
prompt: when asking for Yes/No/All, recognize also UTF-8 letters
|
||||
scrolling: only do a scroll when the edit window has more than one row
|
||||
signals: don't trap segfault/abort when envvar NANO_NOCATCH is defined
|
||||
signals: exclude the crash handler from the tiny version
|
||||
startup: suggest using ^D to finish reading from standard input
|
||||
tweaks: improve a couple of comments
|
||||
tweaks: normalize indentation and whitespace after previous changes
|
||||
tweaks: put check for -h and -l options in their alphabetical positions
|
||||
tweaks: put Yes/No/All in a consistent order (for the translators)
|
||||
tweaks: rename two variables, to be more descriptive
|
||||
tweaks: sort an option better, and reschedule a removal
|
||||
tweaks: use symbolic names instead of puzzling TRUE and FALSE
|
||||
|
||||
Devin Hussey (1):
|
||||
signals: upon a crash, save changed buffers and reset terminal state
|
||||
|
||||
Mark-Weston (1):
|
||||
new feature: an option to make the 'nextword' function stop at word ends
|
||||
|
||||
|
||||
Changes between v2.9.5 and v2.9.6:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (39):
|
||||
build: do not prefix an alternative rcfilename with a dot
|
||||
build: fix compilation when configured with --disable-help
|
||||
bump version numbers and add a news item for the 2.9.6 release
|
||||
command-execution: do not crash when opening the pipe would fail
|
||||
completion: correctly do a signed comparison, to avoid a segfault
|
||||
files: prevent a hang when a call to sigaction() would fail
|
||||
formatting, linting: redetermine the argument list for every run
|
||||
gnulib: update to its current upstream state
|
||||
memory: use a reallocation to reduce the amount of leakage
|
||||
prompt: recognize Yes/No/All in English when the locale gives no match
|
||||
rcfile: skip color commands where some color name is invalid
|
||||
scrolling: don't redraw entire edit window when cursor goes offscreen
|
||||
search: always go forward by default, also when coming from Goto-Line
|
||||
search: use a better value to mean "nothing was typed"
|
||||
speller: don't add an extra newline when saving the text to a tempfile
|
||||
syntax: po: highlight also other escaped characters, not just \n
|
||||
syntax: sh: colorize options only when they are preceded by whitespace
|
||||
tweaks: adjust the translator hint about Yes/No/All
|
||||
tweaks: correct or improve a couple of comments
|
||||
tweaks: elide a function that is called just once
|
||||
tweaks: fix a typo, remove a blank line, and improve some comments
|
||||
tweaks: frob a couple of comments
|
||||
tweaks: group some more of the empty functions together
|
||||
tweaks: improve some comments, and exit with nonzero status upon error
|
||||
tweaks: improve the ordering of a couple of functions
|
||||
tweaks: invert two conditions and reshuffle, to reduce duplication
|
||||
tweaks: move a function to its proper location
|
||||
tweaks: move a function to its proper location
|
||||
tweaks: rearrange a few if statements more symmetrically
|
||||
tweaks: remove the group handling for undoing/redoing (un)indents
|
||||
tweaks: rename a function, to be more distinct from its caller
|
||||
tweaks: rename a function, to be more fitting and descriptive
|
||||
tweaks: rename a variable, for clarity
|
||||
tweaks: rename a variable, to be a bit more fitting
|
||||
tweaks: rename a variable, to be more clear and to match another
|
||||
tweaks: rename a variable, to match another and to be more visible
|
||||
tweaks: reshuffle two declarations
|
||||
tweaks: set the correct flags just once for each spell-fixing session
|
||||
tweaks: use meaningful names instead of puzzling values
|
||||
|
||||
Liu Hao (1):
|
||||
replacing: always clear the backwards flag for ^\, just like for ^W
|
||||
|
||||
|
||||
Changes between v2.9.4 and v2.9.5:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (45):
|
||||
build: exclude more things when configured with --disable-multibuffer
|
||||
build: fix compilation again when configured with --enable-tiny
|
||||
build: fix compilation when configured with --disable-multibuffer
|
||||
build: fix compilation with --enable-{tiny,help,multibuffer}
|
||||
bump version numbers and add a news item for the 2.9.5 release
|
||||
cut: avoid calling renumber() on what might be NULL
|
||||
docs: clarify how the Linux console is deficient: in the arrow keys
|
||||
docs: clarify what the scrollup and scrolldown bindable functions do
|
||||
docs: document the newly added color name "normal"
|
||||
docs: mention in the FAQ that <Shift+Insert> pastes from the clipboard
|
||||
files: prevent an infinite loop when reading from standard input fails
|
||||
files: prevent the undo of reading a file into a new buffer
|
||||
help: describe the Scroll-Up and Scroll-Down commands more precisely
|
||||
help: do not reserve space for line numbers, as they are absent
|
||||
linting: drop messages for other files when configured for one buffer
|
||||
memory: plug a leak, by actually freeing a discarded undo struct
|
||||
scrolling: first move the cursor before pushing current chunk offscreen
|
||||
scrolling: let Scroll-Up/Down keep the cursor in the same text position
|
||||
selecting: don't cancel a softmark when just scrolling the screen
|
||||
small addition: understand color name "normal" to mean the default color
|
||||
syntax: sh: color also the 'cut', 'head', 'tail', and 'sort' commands
|
||||
syntax: sh: color options distinctively, and color also long options
|
||||
syntax: sh: uncolor "tar" when it's part of a filename
|
||||
tweaks: adjust a couple of types, to reduce the number of warnings
|
||||
tweaks: adjust or correct some comments, and rename a function
|
||||
tweaks: adjust the indentation after the previous changes
|
||||
tweaks: bundle some settings for a new buffer
|
||||
tweaks: change a parameter of open_buffer() and invert its logic
|
||||
tweaks: condense some code, to remove a bit of duplication
|
||||
tweaks: drop a handful of unhelpful asserts
|
||||
tweaks: elide an unneeded and shadowing variable
|
||||
tweaks: elide a parameter, as it's always the inverse of another
|
||||
tweaks: elide a parameter that is always 1
|
||||
tweaks: elide two parameters and thus a pair of wrapper functions
|
||||
tweaks: factor out the check for 'viewok' into its own function
|
||||
tweaks: fix a typo and adjust some wording and formatting in the FAQ
|
||||
tweaks: frob some comments plus miscellaneous other stuff
|
||||
tweaks: fuse two ifs into one
|
||||
tweaks: move an 'if' and then remove an unneeded label
|
||||
tweaks: reduce the font size of the questions in the FAQ
|
||||
tweaks: remove an inconsistent space from two pointer declarations
|
||||
tweaks: remove unneeded settings and unsettings of MULTIBUFFER
|
||||
tweaks: reshuffle some movement code, to reduce the number of conditions
|
||||
tweaks: revert commit c88a2fd9 -- the extra variable is needed
|
||||
tweaks: rewrap and amend some lines in the NEWS file
|
||||
|
||||
David Lawrence Ramsey (1):
|
||||
tweaks: correct several parameter types
|
||||
|
||||
Kamil Dudka (1):
|
||||
input: do not crash if sctofunc() returns NULL
|
||||
|
||||
Liu Hao (1):
|
||||
build: fix compilation error when configured with --disable-justify
|
||||
|
||||
|
||||
Changes between v2.9.3 and v2.9.4:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (65):
|
||||
bindings: make a key defined as string work also in browser and viewer
|
||||
bindings: rename the bindable function 'gototext' to 'flipgoto'
|
||||
bindings: revert the ^/ changes, as ^/ is not always Go-To-Line
|
||||
bindings: show ^/ instead of ^_ for Go-To-Line
|
||||
build: fix compilation when configured with --enable-tiny
|
||||
bump version numbers and add a news item for the 2.9.4 release
|
||||
docs: mention that a key can be bound to a string
|
||||
docs: note also in the Info manual that text can be selected with Shift
|
||||
editing: when --smooth is used, make <Enter>-at-bottom scroll one row
|
||||
general: detect in a better way whether we're running on a Linux console
|
||||
gnulib: update to its current upstream state
|
||||
goto: avoid a segfault, by initializing 'answer' when it is NULL
|
||||
help: mention that some keys work on a region when the mark is on
|
||||
help: tweak the descriptions of ^X and ^R
|
||||
input: handle the implant() function separately also for the prompt
|
||||
input: handle the implant() function separately, as it is special
|
||||
memory: avoid a leak when toggling from Search to Goto
|
||||
memory: squeal when there is something wrong, instead of stumbling on
|
||||
new feature: allow binding a key to a string (in a nanorc file)
|
||||
prompt: disallow pasting when in restricted mode
|
||||
rcfile: allow a syntax name to be unquoted
|
||||
search: clear the existing answer when starting a new search
|
||||
search: get rid of some unneeded recursion when just toggling things
|
||||
selecting: cancel the softmark upon any attempt to move the cursor
|
||||
small addition: allow customizing the color of an error message
|
||||
syntax: color also ^/ in nano's help texts and in nanorc files
|
||||
syntaxes: remove quotes from each syntax name, and color it differently
|
||||
syntax: nanorc: color also bindings to a string as valid
|
||||
tweaks: adjust comments and indentation after the previous change
|
||||
tweaks: adjust two comments, move two declarations, rewrap three lines
|
||||
tweaks: appease valgrind concerning syscalls with uninitialized values
|
||||
tweaks: condense a comment and elide an 'if'
|
||||
tweaks: correct a typo in NEWS
|
||||
tweaks: correct a typo that broke binding a key to a string
|
||||
tweaks: do not needlessly renumber the lines in the buffer
|
||||
tweaks: don't call strcmp() to determine whether a string is empty
|
||||
tweaks: drop an assert, add a warning, and change a 'for' to a 'while'
|
||||
tweaks: drop some debugging stuff, and adjust what remains of it
|
||||
tweaks: elide another variable, to call a function less often
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: elide an unused variable and parameter
|
||||
tweaks: elide two unneeded booleans
|
||||
tweaks: exclude an unlikely error message from the tiny version
|
||||
tweaks: exclude an unlikely warning from the tiny version
|
||||
tweaks: fix a copy-and-paste error
|
||||
tweaks: make the fsfromline() call only for the undo types that need it
|
||||
tweaks: plug a memory leak when using Verbatim Input at a prompt
|
||||
tweaks: refactor the implanting of a key expansion
|
||||
tweaks: remove another superfluous check
|
||||
tweaks: remove a superfluous check
|
||||
tweaks: remove two deprecated options and six rebindable function names
|
||||
tweaks: remove two superfluous checks, and restrict two others
|
||||
tweaks: rename a parameter and a variable, to be more fitting
|
||||
tweaks: rename a variable to be more distinct and greppable
|
||||
tweaks: rename two variables, to be more meaningful
|
||||
tweaks: reshuffle some code, to be slightly less ugly
|
||||
tweaks: reshuffle some of the search-and-replace cleanup calls
|
||||
tweaks: reshuffle the undo types into mostly the same order everywhere
|
||||
tweaks: shorten the name of two record elements
|
||||
tweaks: slightly rewrap the FAQ's table of contents
|
||||
tweaks: transform a 'do' to a 'while', and reshuffle a comment
|
||||
tweaks: unabbreviate two variable names
|
||||
undo: when redoing, don't try to find a line number that might not exist
|
||||
|
||||
Brand Huntsman (1):
|
||||
color: remove unneeded bright comparision to prevent duplicate pairs
|
||||
|
||||
David Lawrence Ramsey (3):
|
||||
docs: mention that errorcolor does have default colors
|
||||
input: don't stop prepending when the user adds text via a shortcut
|
||||
tweaks: fix typo in rebindable function name
|
||||
|
||||
Tom Levy (1):
|
||||
syntax: go: highlight also floats with leading zeroes as valid
|
||||
|
||||
|
||||
Changes between v2.9.2 and v2.9.3:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (65):
|
||||
build: fix compilation when configured with --enable(tiny,color,nanorc}
|
||||
build: fix compilation with --enable-tiny --enable-justify
|
||||
build: let ./configure fail (not just warn) when curses.h is missing
|
||||
bump version numbers and add a news item for the 2.9.3 release
|
||||
copyright: update the years for the FSF
|
||||
display: wipe the status bar when doing a total refresh
|
||||
docs: remove the note about needing a recent ncurses for macros to work
|
||||
docs: update the FAQ for the changed default location of history files
|
||||
docs: update the TODO file to the current state of affairs
|
||||
gnulib: update to its current upstream state
|
||||
help: don't get stuck when there is an unwrappable piece of text
|
||||
input: consume only the actual length of an escape sequence
|
||||
input: fully reset state when a three-digit character code is cut short
|
||||
input: make <Shift+Tab> do an unindent also on a Manjaro console
|
||||
input: recognize escape sequences for <Shift+PageUp> and <Shift+PageDown>
|
||||
input: recognize more escape sequences for <Shift+Home> and <Shift+End>
|
||||
input: recognize the deviant keycode for <Ctrl+End> in urxvt
|
||||
options: recognize -M and --trimblanks on the command line
|
||||
painting: look for an end match only after a start match, if any
|
||||
prompt: show whitespace only in the filename, not in the whole line
|
||||
replacing: don't skip the first character of a backwards-marked region
|
||||
search: suppress the occurrence at the cursor only when replacing
|
||||
startup: allow a named pipe as file argument when --noread is used
|
||||
startup: make an error message succinct and to the point
|
||||
startup: move the initialization of colors, so any error gets printed
|
||||
syntax: go: colorize only valid octal numbers
|
||||
syntax: lua: do not color debug.setinfo as it doesn't exist
|
||||
syntax: nanohelp: color also the Sh-Tab key combo
|
||||
tweaks: change a 'do' to a 'while', and return early to elide an 'if'
|
||||
tweaks: check for the type of terminal far earlier
|
||||
tweaks: condense a condition and a comment, and reshuffle a line
|
||||
tweaks: condense and rewrap some comments, and reindent two lines
|
||||
tweaks: condense the conditional compilation of shortcut reassignments
|
||||
tweaks: don't bother freeing the key buffer, just reallocate it
|
||||
tweaks: don't bother to reallocate when the keybuffer size decreases
|
||||
tweaks: drop a superfluous parameter, as it is always 1
|
||||
tweaks: drop a useless assert, and don't abort over an unhandled option
|
||||
tweaks: drop two unneeded initializations, and trim a comment
|
||||
tweaks: elide a tiny intermediate buffer, and rename two variables
|
||||
tweaks: exclude --trimblanks when no wrapping or justifying is configured
|
||||
tweaks: fully include Savefile and Wherewas in the tiny version
|
||||
tweaks: indenting text files with tabs is not a good idea
|
||||
tweaks: mark the two blocks that have a deviant indentation
|
||||
tweaks: move a bunch of comments to the lines that they refer to
|
||||
tweaks: move two functions to their proper place, orderingwise
|
||||
tweaks: remove a fragment of dead code
|
||||
tweaks: remove a handful of redundant (because always true) asserts
|
||||
tweaks: remove a superfluous case -- there can never be four digits
|
||||
tweaks: remove a superfluous check, as we insert always one code
|
||||
tweaks: rename a function, for aptness, and drop a superfluous check
|
||||
tweaks: rename a function, to be more distinct
|
||||
tweaks: rename a variable, and further condense some comments
|
||||
tweaks: rename a variable, for more contrast
|
||||
tweaks: rename a variable, to better fit its usage
|
||||
tweaks: rename two variables, and swap their declaration order
|
||||
tweaks: rename two variables, for preciseness and shortness
|
||||
tweaks: reshuffle a couple of lines
|
||||
tweaks: reshuffle a couple of lines, to make a bit more sense
|
||||
tweaks: reshuffle some stuff, and avoid a memory leak
|
||||
tweaks: reshuffle two condition series, to look better
|
||||
tweaks: rewrap a bunch of lines in the NEWS file
|
||||
tweaks: set a modifier in a single place, for conciseness
|
||||
tweaks: swap the row and col parameters to a more consistent order
|
||||
tweaks: transform a parameter, from a pointer to the value itself
|
||||
wrapping: don't trim a blank character that the user just typed
|
||||
|
||||
Brand Huntsman (1):
|
||||
startup: parse interface colors when they are read, not when initialized
|
||||
|
||||
|
||||
Changes between v2.9.1 and v2.9.2:
|
||||
----------------------------------
|
||||
|
||||
Benjamin Mintz (1):
|
||||
syntax: python: add 'async', 'await', and 'nonlocal' as keywords
|
||||
|
||||
Benno Schulenberg (62):
|
||||
bump version numbers and add a news item for the 2.9.2 release
|
||||
display: ensure that cursor is visible when compiled with --with-slang
|
||||
docs: mention that the source code is best viewed with a tab size of 4
|
||||
docs: say thanks to some fairly recent translators, and rename one
|
||||
gnulib: pull in the fix for the missing stat include
|
||||
gnulib: update to its current upstream state
|
||||
help: show that "Tab" will indent, just like "Sh-Tab" will unindent
|
||||
help: swap the order of the Complete and Comment functions
|
||||
indenting: don't exclude last line of region when region is empty
|
||||
indenting: keep affecting last line of marked region if it was at first
|
||||
input: allow using <Tab> and <Shift+Tab> to (un)indent selected region
|
||||
input: make <Ctrl+Shift+Arrow> work also when using --rebindkeypad
|
||||
input: optimize a bit for non-shortcut keys, as they are most frequent
|
||||
options: rename 'justifytrim' to 'trimblanks', because it has morphed
|
||||
prompt: blank the bar when a "continue?" is answered with No or ^C
|
||||
syntaxes: remove redundant word-boundary markers
|
||||
syntax: javascript: add some comments, and color explicit numbers too
|
||||
syntax: javascript: add some keywords, and sort them more logically
|
||||
syntax: javascript: color strings differently from major keywords
|
||||
syntax: javascript: require that a comment is preceded by whitespace
|
||||
syntax: lua: condense some regexes, tweak comments, reorder things
|
||||
syntax: nanorc: don't color parts of valid strings as if invalid
|
||||
syntax: python: color also the special values 'False', 'None', 'True'
|
||||
text: allow unindenting when not all lines are indented
|
||||
text: keep cursor at left edge when it IS there when indenting/commenting
|
||||
text: let a Shift-selection persist when indenting and commenting
|
||||
text: let indenting/commenting skip the last line if its x is zero
|
||||
text: set and reset the Modified state correctly when undoing/redoing
|
||||
tweaks: add a separate function that actually wipes the status bar
|
||||
tweaks: avoid incrementing a variable that won't be used again later
|
||||
tweaks: condense or rewrap a bunch of repetitious comments
|
||||
tweaks: condense, reword, and rewrap a bunch of comments
|
||||
tweaks: condense some debugging code, and rewrap a line
|
||||
tweaks: convert the indentation of the NEWS file too
|
||||
tweaks: convert the indentation to use only tabs
|
||||
tweaks: drop some old debugging code plus a superfluous comment
|
||||
tweaks: elide two parameters from the get_region() function
|
||||
tweaks: elide two variables that are used just once
|
||||
tweaks: factor out a piece of common code
|
||||
tweaks: fix some whitespace errors, and convert alignment tabs to spaces
|
||||
tweaks: fold some regexes into one another, for conciseness
|
||||
tweaks: frob four comments, and rewrap two lines
|
||||
tweaks: invert the logic of a variable, and rename it
|
||||
tweaks: limit the resetting of "Modified" to writing a full buffer
|
||||
tweaks: move some frequently-used keystrokes to the top of the list
|
||||
tweaks: remove a redundant call of renumber()
|
||||
tweaks: remove a superfluous condition
|
||||
tweaks: remove a superfluous placing of a terminating nul byte
|
||||
tweaks: remove some unneeded parentheses, and shorten two function calls
|
||||
tweaks: remove two irrelevant conditions
|
||||
tweaks: rename three variables, for more contrast and variety
|
||||
tweaks: reshuffle a bit of common code, moving it to an existing function
|
||||
tweaks: reshuffle another bit of code, for conciseness
|
||||
tweaks: rewrap some lines and some comments, and trim two others
|
||||
tweaks: slightly rename four functions, for aptness and variety
|
||||
tweaks: strip some debugging stuff, and condense a bit of code
|
||||
tweaks: trim another placing of a terminating nul byte
|
||||
tweaks: use for git the more faithful "less -x1,5" suggested by Brand
|
||||
tweaks: use spaces for alignment also in the THANKS file
|
||||
wrapping: delete trailing blanks upon hardwrapping, when requested
|
||||
wrapping: keep prepending to the same next line as long as possible
|
||||
wrapping: we're still on the same line if the next line has not changed
|
||||
|
||||
David Lawrence Ramsey (3):
|
||||
input: support backtab when Slang and/or --rebindkeypad is used
|
||||
tweaks: use printf's z modifier for (s)size_t, instead of casting
|
||||
undo: when adding text adds a magicline, an undo should remove both
|
||||
|
||||
Liu Hao (1):
|
||||
syntax: c: increase the color contrast of reminders like FIXME
|
||||
|
||||
Michael Francis (1):
|
||||
syntax: php: function and variable names can contain uppercase and digits
|
||||
|
||||
Mike Frysinger (1):
|
||||
syntax: javascript: add newer keywords and string syntax
|
||||
|
||||
Tom Levy (6):
|
||||
syntax: go: fix word boundary before dot in number literal
|
||||
syntax: go: sign of exponent in number literal is optional
|
||||
syntax: lua: add new and missing standard library functions
|
||||
syntax: lua: correct the word boundaries on standard library functions
|
||||
syntax: lua: require at least one digit for hexadecimal numbers
|
||||
syntax: lua: support fractional part and exponent for decimal and hex
|
||||
|
||||
|
||||
Changes between v2.9.0 and v2.9.1:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (20):
|
||||
build: fix compilation with --disable-browser --disable-tabcomp
|
||||
bump version numbers and add a news item for the 2.9.1 release
|
||||
files: always update the stat info when the entire file is written
|
||||
files: save the marked region only when we've prompted for a file name
|
||||
gnulib: update to its current upstream state
|
||||
history: create the path '~/.local/share/' when it is needed
|
||||
history: make nano's state directory accessible for the user only
|
||||
history: save the positions file also when a record was deleted
|
||||
input: make the macro key discoverable by giving feedback when undefined
|
||||
linting: switch the mark off when the linter starts
|
||||
selecting: do not cancel the softmark when the cursor is not moved
|
||||
selecting: let a justification cancel a softmark
|
||||
syntax: adjust the magic strings for the changes since file-5.10
|
||||
tweaks: adjust indentation after previous change
|
||||
tweaks: elide the 'mark_set' boolean -- the 'mark' pointer is enough
|
||||
tweaks: rename, rewrap, and reshuffle some stuff, and frob some comments
|
||||
tweaks: reshuffle a couple of lines, and frob a comment or two
|
||||
tweaks: reshuffle a couple of lines, to put similar things together
|
||||
undo: clear the Modified state when the very first edit is undone
|
||||
undo: discarding the stack does not always lose information
|
||||
|
||||
|
||||
Changes between v2.8.7 and v2.9.0:
|
||||
----------------------------------
|
||||
|
||||
|
||||
24
IMPROVEMENTS
24
IMPROVEMENTS
@@ -2,6 +2,13 @@ Improvements in GNU nano
|
||||
========================
|
||||
|
||||
Since 2.9.0:
|
||||
- Option 'set afterends' for making Ctrl+Right stop at word ends.
|
||||
- A crash handler that saves changed buffers in case of a crash.
|
||||
- Addition of the color name "normal", meaning the default color.
|
||||
- A key can be bound to a string -- any mix of text and commands.
|
||||
- Error messages are shown by default in bright white on red.
|
||||
- <Tab> and <Shift+Tab> can be used to indent/unindent a marked region.
|
||||
- Can snip trailing whitespace while typing, with 'set trimblanks'.
|
||||
- The ability to record and replay a series of keystrokes (a macro).
|
||||
- Assigned functions to ^S (save file) and ^Q (start backward search).
|
||||
- Indenting and unindenting have been integrated into the undo system.
|
||||
@@ -29,24 +36,25 @@ Since 2.6.0:
|
||||
- The option 'wordchars' for specifying extra word characters.
|
||||
- Hi-bit control characters are shown in a more readable manner.
|
||||
- The ability to use negative numbers at the Go To Line prompt.
|
||||
|
||||
Noteworthy changes since 2.2
|
||||
----------------------------
|
||||
- The ability to comment/uncomment lines with a single keystroke (M-3).
|
||||
- The ability to refresh the file list in the browser (^L).
|
||||
- The ability to abort re-searches (^C after an M-W).
|
||||
- Better feedback at startup when opening large or multiple files.
|
||||
|
||||
Since 2.5.0:
|
||||
- The option 'justifytrim' for snipping whitespace from justified lines.
|
||||
- The ability to discard a buffer (^O ^Q) when --tempfile is used.
|
||||
- Replacing things in a marked region now takes place in situ, in context,
|
||||
instead of changing the view to only the marked text.
|
||||
- On some terminals Ctrl+Left / Ctrl+Right now work for PrevWord/NextWord.
|
||||
- On most terminals Ctrl+Left / Ctrl+Right now work for PrevWord/NextWord.
|
||||
- When in the middle of a word, PrevWord now jumps to the start of this
|
||||
word (like Pico does) instead of to the start of the preceding word.
|
||||
|
||||
Since 2.4.0:
|
||||
- Replacing things in a marked region now takes place in situ, in context,
|
||||
instead of changing the view to only the marked text.
|
||||
- Invalid byte sequences are properly displayed and not mistakenly found.
|
||||
- Resizing the window does not exit from help viewer nor file browser.
|
||||
- Improved arrangement of the shortcuts in the two help lines.
|
||||
- Several small bug fixes in the syntax highlighting.
|
||||
|
||||
Since 2.3.0:
|
||||
- System syntaxes can be improved upon with the 'extendsyntax' command.
|
||||
- The ability to delete whole words with 'cutwordleft' and 'cutwordright'.
|
||||
- The ability to save a file without prompting for its name ('savefile').
|
||||
|
||||
92
README
92
README
@@ -1,76 +1,76 @@
|
||||
|
||||
GNU nano -- an enhanced clone of the Pico text editor
|
||||
GNU nano -- an enhanced clone of the Pico text editor
|
||||
|
||||
Overview
|
||||
|
||||
The nano project was started because of a few "problems" with the
|
||||
wonderfully easy-to-use and friendly Pico text editor.
|
||||
The nano project was started because of a few "problems" with the
|
||||
wonderfully easy-to-use and friendly Pico text editor.
|
||||
|
||||
First and foremost was its license: the Pine suite does not use
|
||||
the GPL or a GPL-friendly license, and has unclear restrictions on
|
||||
redistribution. Because of this, Pine and Pico are not included
|
||||
with many GNU/Linux distributions. Also, other features (like
|
||||
go-to-line-number or search-and-replace) were unavailable until
|
||||
recently or require a command-line flag. Yuck.
|
||||
First and foremost was its license: the Pine suite does not use
|
||||
the GPL or a GPL-friendly license, and has unclear restrictions on
|
||||
redistribution. Because of this, Pine and Pico are not included
|
||||
with many GNU/Linux distributions. Also, other features (like
|
||||
go-to-line-number or search-and-replace) were unavailable until
|
||||
recently or require a command-line flag. Yuck.
|
||||
|
||||
nano aims to solve these problems by emulating the functionality of
|
||||
Pico as closely as possible while addressing the problems above and
|
||||
providing other extra functionality.
|
||||
nano aims to solve these problems by emulating the functionality of
|
||||
Pico as closely as possible while addressing the problems above and
|
||||
providing other extra functionality.
|
||||
|
||||
The nano editor is an official GNU package. For more information on
|
||||
GNU and the Free Software Foundation, please see http://www.gnu.org/.
|
||||
The nano editor is an official GNU package. For more information on
|
||||
GNU and the Free Software Foundation, please see http://www.gnu.org/.
|
||||
|
||||
How to compile and install nano
|
||||
|
||||
Download the nano source code, then:
|
||||
Download the nano source code, then:
|
||||
|
||||
tar xvzf nano-x.y.z.tar.gz
|
||||
cd nano-x.y.z
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
tar xvzf nano-x.y.z.tar.gz
|
||||
cd nano-x.y.z
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
It's that simple. Use --prefix with configure to override the
|
||||
default installation directory of /usr/local.
|
||||
It's that simple. Use --prefix with configure to override the
|
||||
default installation directory of /usr/local.
|
||||
|
||||
If you haven't configured with the --disable-nanorc option, after
|
||||
installation you may want to copy the doc/sample.nanorc file to
|
||||
your home directory, rename it to ".nanorc", and then edit it
|
||||
according to your taste.
|
||||
If you haven't configured with the --disable-nanorc option, after
|
||||
installation you may want to copy the doc/sample.nanorc file to
|
||||
your home directory, rename it to ".nanorc", and then edit it
|
||||
according to your taste.
|
||||
|
||||
Web Page
|
||||
|
||||
https://nano-editor.org/
|
||||
https://nano-editor.org/
|
||||
|
||||
Mailing Lists
|
||||
|
||||
There are three nano-related mailing-lists.
|
||||
There are three nano-related mailing-lists.
|
||||
|
||||
+ info-nano@gnu.org is a very low traffic list used to announce
|
||||
new nano versions or other important info about the project.
|
||||
+ help-nano@gnu.org is for those seeking to get help without
|
||||
wanting to hear about the technical details of its development.
|
||||
+ nano-devel@gnu.org is the list used by the people that make nano
|
||||
and a general development discussion list, with moderate traffic.
|
||||
+ info-nano@gnu.org is a very low traffic list used to announce
|
||||
new nano versions or other important info about the project.
|
||||
+ help-nano@gnu.org is for those seeking to get help without
|
||||
wanting to hear about the technical details of its development.
|
||||
+ nano-devel@gnu.org is the list used by the people that make nano
|
||||
and a general development discussion list, with moderate traffic.
|
||||
|
||||
To subscribe, send email to <name>-request@gnu.org with a subject
|
||||
of "subscribe", where <name> is the list you want to subscribe to.
|
||||
To subscribe, send email to <name>-request@gnu.org with a subject
|
||||
of "subscribe", where <name> is the list you want to subscribe to.
|
||||
|
||||
Bug Reports
|
||||
|
||||
To report a bug, please file a description of the problem on nano's
|
||||
bug tracker (https://savannah.gnu.org/bugs/?group=nano -- hover on
|
||||
"Bugs", then click "Submit new"). The issue may have already been
|
||||
reported, so please look first.
|
||||
To report a bug, please file a description of the problem on nano's
|
||||
bug tracker (https://savannah.gnu.org/bugs/?group=nano -- hover on
|
||||
"Bugs", then click "Submit new"). The issue may have already been
|
||||
reported, so please look first.
|
||||
|
||||
Current Status
|
||||
|
||||
Since version 2.5.0, GNU nano has abandoned the distinction between
|
||||
a stable and a development branch: it is now on a "rolling" release
|
||||
-- fixing bugs and adding new features go hand in hand.
|
||||
Since version 2.5.0, GNU nano has abandoned the distinction between
|
||||
a stable and a development branch: it is now on a "rolling" release
|
||||
-- fixing bugs and adding new features go hand in hand.
|
||||
|
||||
Copyright Years
|
||||
|
||||
When in any file of this package a copyright notice mentions a
|
||||
year range (such as 1999-2011), it is a shorthand for a list of
|
||||
all the years in that interval.
|
||||
When in any file of this package a copyright notice mentions a
|
||||
year range (such as 1999-2011), it is a shorthand for a list of
|
||||
all the years in that interval.
|
||||
|
||||
@@ -107,3 +107,10 @@ the license that covers nano. Then create a patch (or patches):
|
||||
|
||||
Send that patch (or patches) to <nano-devel@gnu.org>, as an attachment
|
||||
or with git send-email.
|
||||
|
||||
To keep most lines of nano's source code within a width of 80 characters,
|
||||
a tab size of four should be used. So in your nanorc file you may want
|
||||
to include 'set tabsize 4', or you could use -T4 on the command line.
|
||||
To make git display things as intended, you can do:
|
||||
|
||||
$ git config --local core.pager "less -x1,5"
|
||||
|
||||
171
THANKS
171
THANKS
@@ -4,90 +4,97 @@ If we missed you here, let us know!
|
||||
|
||||
Translations:
|
||||
============
|
||||
Sharuzzaman Ahmat Raslan <sharuzzaman@excite.com> Malay
|
||||
Josef Andersson <josef.andersson@fripost.org> Swedish
|
||||
Laurentiu Buzdugan <buzdugan@voyager.net> Romanian
|
||||
Mario Blättermann <mario.blaettermann@gmail.com> German
|
||||
Ricardo Cárdenes Medina <ricardo@conisys.com> Spanish
|
||||
Antonio Ceballos <aceballos@gmail.com> Spanish
|
||||
Wei-Lun CHAO <chaoweilun@pcmail.com.tw> Chinese (traditional)
|
||||
Yuri Chornoivan <yurchor@ukr.net> Ukrainian
|
||||
Marco Colombo <magicdice@inwind.it> Italian
|
||||
Mihai Cristescu <mihai.cristescu@archlinux.info> Romanian
|
||||
Yavor Doganov <yavor@doganov.org> Bulgarian
|
||||
Karl Eichwalder <keichwa@gmx.net> German
|
||||
A. Murat EREN <meren@comu.edu.tr> Turkish
|
||||
Rafael Ferreira <rafael.f.f1@gmail.com> Brazilian Portuguese
|
||||
Doruk Fisek <dfisek@fisek.com.tr> Turkish
|
||||
Pavel Fric <pavelfric@seznam.cz> Czech
|
||||
Jorge González <aloriel@gmail.com> Spanish
|
||||
Pedro Albuquerque <palbuquerque73@gmail.com> Portuguese
|
||||
Josef Andersson <josef.andersson@fripost.org> Swedish
|
||||
Laurentiu Buzdugan <buzdugan@voyager.net> Romanian
|
||||
Mario Blättermann <mario.blaettermann@gmail.com> German
|
||||
Ricardo Cárdenes Medina <ricardo@conisys.com> Spanish
|
||||
Antonio Ceballos <aceballos@gmail.com> Spanish
|
||||
Wei-Lun CHAO <chaoweilun@pcmail.com.tw> Chinese (traditional)
|
||||
Yuri Chornoivan <yurchor@ukr.net> Ukrainian
|
||||
Marco Colombo <magicdice@inwind.it> Italian
|
||||
Mihai Cristescu <mihai.cristescu@archlinux.info> Romanian
|
||||
Yavor Doganov <yavor@doganov.org> Bulgarian
|
||||
Karl Eichwalder <keichwa@gmx.net> German
|
||||
A. Murat EREN <meren@comu.edu.tr> Turkish
|
||||
Doruk Fisek <dfisek@fisek.com.tr> Turkish
|
||||
Rafael Fontenelle <rffontenelle@gmail.com> Brazilian Portuguese
|
||||
Pavel Fric <pavelfric@seznam.cz> Czech
|
||||
Jorge González <aloriel@gmail.com> Spanish
|
||||
Jean-Philippe Guérard <jean-philippe.guerard@laposte.net> French
|
||||
Geir Helland <pjallabais@users.sourceforge.net> Norwegian Bokmål
|
||||
Tedi Heriyanto <tedi_h@gmx.net> Indonesian
|
||||
Václav Haisman <V.Haisman@sh.cvut.cz> Czech
|
||||
Kjetil Torgrim Homme <kjetilho@linpro.no> Norwegian Nynorsk
|
||||
Szabolcs Horvath <horvaths@janus.gimsz.sulinet.hu> Hungarian
|
||||
Jorma Karvonen <karvonen.jorma@gmail.com> Finnish
|
||||
Gabor Kelemen <kelemeng@gnome.hu> Hungarian
|
||||
Kalle Kivimaa <kalle.kivimaa@iki.fi> Finnish
|
||||
Eivind Kjørstad <ekj@vestdata.no> Norwegian Nynorsk
|
||||
Florian König <floki@bigfoot.com> German
|
||||
Klemen Košir <klemen913@gmail.com> Slovenian
|
||||
Wojciech Kotwica <wkotwica@post.pl> Polish
|
||||
Ask Hjorth Larsen <asklarsen@gmail.com> Danish
|
||||
Clement Laforet <clem_laf@wanadoo.fr> French
|
||||
LI Daobing <lidaobing@gmail.com> Chinese (simplified)
|
||||
Jordi Mallach <jordi@gnu.org> Catalan
|
||||
João Victor Duarte Martins <jvdm@sdf.lonestar.org> Brazilian Portuguese
|
||||
Pavel Maryanov <acid@jack.kiev.ua> Russian
|
||||
Daniele Medri <madrid@linux.it> Italian
|
||||
Gergely Nagy <algernon@debian.org> Hungarian
|
||||
Kalle Olavi Niemitalo <kon@iki.fi> Finnish
|
||||
Мирослав Николић <miroslavnikolic@rocketmail.com> Serbian
|
||||
Claudio Neves <cneves@nextis.com> Brazilian Portuguese
|
||||
Daniel Nylander <po@danielnylander.se> Swedish
|
||||
Mikel Olasagasti <hey_neken@mundurat.net> Basque
|
||||
Michael Piefel <piefel@informatik.hu-berlin.de> German
|
||||
Sergey Poznyakoff <gray@gnu.org> Polish
|
||||
Božidar Putanec <bozidarp@yahoo.com> Croatian
|
||||
Trần Ngọc Quân <vnwildman@gmail.com> Vietnamese
|
||||
Sergey A. Ribalchenko <fisher@obu.ck.ua> Ukrainian and Russian
|
||||
Michel Robitaille <robitail@IRO.UMontreal.CA> French
|
||||
Christian Rose <menthos@menthos.com> Swedish
|
||||
Dimitriy Ryazantcev <DJm00n@mail.ru> Russian
|
||||
Stig E Sandø <stig@ii.uib.no> Norwegian Bokmål
|
||||
Kevin Patrick Scannell <kscanne@gmail.com> Irish
|
||||
Benno Schulenberg <benno@vertaalt.nl> Dutch and Esperanto
|
||||
Danilo Segan <dsegan@gmx.net> Serbian
|
||||
Clytie Siddall <clytie@riverland.net.au> Vietnamese
|
||||
Keld Simonsen <keld@dkuug.dk> Danish
|
||||
Guus Sliepen <guus@nl.linux.org> Dutch
|
||||
Cezary Sliwa <sliwa@cft.edu.pl> Polish
|
||||
Johnny A. Solbu <johnny@solbu.net> Norwegian Bokmål
|
||||
Pierre Tane <tanep@bigfoot.com> French
|
||||
Yasuaki Taniguchi <yasuakit@gmail.com> Japanese
|
||||
Jacobo Tarrío <jtarrio@trasno.net> Galician
|
||||
Francisco Javier Tsao Santín <tsao@members.fsf.org> Galician
|
||||
Miquel Vidal <miquel@sindominio.net> Catalan
|
||||
Phan Vinh Thinh <teppi82@gmail.com> Vietnamese
|
||||
Pauli Virtanen <pauli.virtanen@saunalahti.fi> Finnish
|
||||
Aron Xu <happyaron.xu@gmail.com> Chinese (simplified)
|
||||
Peio Ziarsolo <peio@sindominio.net> Basque
|
||||
Anton Zinoviev <zinoviev@debian.org> Bulgarian
|
||||
Geir Helland <pjallabais@users.sourceforge.net> Norwegian Bokmål
|
||||
Tedi Heriyanto <tedi_h@gmx.net> Indonesian
|
||||
Václav Haisman <V.Haisman@sh.cvut.cz> Czech
|
||||
Takeshi Hamasaki <hmatrjp@users.sourceforge.jp> Japanese
|
||||
Kjetil Torgrim Homme <kjetilho@linpro.no> Norwegian Nynorsk
|
||||
Szabolcs Horvath <horvaths@janus.gimsz.sulinet.hu> Hungarian
|
||||
Jorma Karvonen <karvonen.jorma@gmail.com> Finnish
|
||||
Mehmet Kececi <mkececi@mehmetkececi.com> Turkish
|
||||
Gabor Kelemen <kelemeng@gnome.hu> Hungarian
|
||||
Kalle Kivimaa <kalle.kivimaa@iki.fi> Finnish
|
||||
Eivind Kjørstad <ekj@vestdata.no> Norwegian Nynorsk
|
||||
Florian König <floki@bigfoot.com> German
|
||||
Klemen Košir <klemen913@gmail.com> Slovenian
|
||||
Wojciech Kotwica <wkotwica@post.pl> Polish
|
||||
Ask Hjorth Larsen <asklarsen@gmail.com> Danish
|
||||
Clement Laforet <clem_laf@wanadoo.fr> French
|
||||
LI Daobing <lidaobing@gmail.com> Chinese (simplified)
|
||||
Jordi Mallach <jordi@gnu.org> Catalan
|
||||
João Victor Duarte Martins <jvdm@sdf.lonestar.org> Brazilian Portuguese
|
||||
Pavel Maryanov <acid@jack.kiev.ua> Russian
|
||||
Daniele Medri <madrid@linux.it> Italian
|
||||
Gergely Nagy <algernon@debian.org> Hungarian
|
||||
Claudio Neves <cneves@nextis.com> Brazilian Portuguese
|
||||
Kalle Olavi Niemitalo <kon@iki.fi> Finnish
|
||||
Мирослав Николић <miroslavnikolic@rocketmail.com> Serbian
|
||||
Lauri Nurmi <lanurmi@iki.fi> Finnish
|
||||
Daniel Nylander <po@danielnylander.se> Swedish
|
||||
Mikel Olasagasti <hey_neken@mundurat.net> Basque
|
||||
Yi-Jyun Pan <pan93412@gmail.com> Chinese (traditional)
|
||||
Michael Piefel <piefel@informatik.hu-berlin.de> German
|
||||
Sergey Poznyakoff <gray@gnu.org> Polish
|
||||
Božidar Putanec <bozidarp@yahoo.com> Croatian
|
||||
Trần Ngọc Quân <vnwildman@gmail.com> Vietnamese
|
||||
Sharuzzaman Ahmat Raslan <sharuzzaman@excite.com> Malay
|
||||
Sergey A. Ribalchenko <fisher@obu.ck.ua> Ukrainian and Russian
|
||||
Michel Robitaille <robitail@IRO.UMontreal.CA> French
|
||||
Christian Rose <menthos@menthos.com> Swedish
|
||||
Dimitriy Ryazantcev <DJm00n@mail.ru> Russian
|
||||
Stig E Sandø <stig@ii.uib.no> Norwegian Bokmål
|
||||
Kevin Patrick Scannell <kscanne@gmail.com> Irish
|
||||
Benno Schulenberg <benno@vertaalt.nl> Dutch and Esperanto
|
||||
Danilo Segan <dsegan@gmx.net> Serbian
|
||||
Clytie Siddall <clytie@riverland.net.au> Vietnamese
|
||||
Keld Simonsen <keld@dkuug.dk> Danish
|
||||
Guus Sliepen <guus@nl.linux.org> Dutch
|
||||
Cezary Sliwa <sliwa@cft.edu.pl> Polish
|
||||
Johnny A. Solbu <johnny@solbu.net> Norwegian Bokmål
|
||||
Pierre Tane <tanep@bigfoot.com> French
|
||||
Yasuaki Taniguchi <yasuakit@gmail.com> Japanese
|
||||
Jacobo Tarrío <jtarrio@trasno.net> Galician
|
||||
Francisco Javier Tsao Santín <tsao@members.fsf.org> Galician
|
||||
Balázs Úr <urbalazs@gmail.com> Hungarian
|
||||
Miquel Vidal <miquel@sindominio.net> Catalan
|
||||
Phan Vinh Thinh <teppi82@gmail.com> Vietnamese
|
||||
Pauli Virtanen <pauli.virtanen@saunalahti.fi> Finnish
|
||||
Aron Xu <happyaron.xu@gmail.com> Chinese (simplified)
|
||||
Boyuan Yang <073plan@gmail.com> Chinese (simplified)
|
||||
Peio Ziarsolo <peio@sindominio.net> Basque
|
||||
Anton Zinoviev <zinoviev@debian.org> Bulgarian
|
||||
|
||||
|
||||
Other stuff:
|
||||
===========
|
||||
Ben Armstrong <synrg@sanctuary.nslug.ns.ca> Negative -r value idea, code
|
||||
Thomas Dickey <dickey@herndon4.his.com> Curses help and advice
|
||||
Sven Guckes <guckes@math.fu-berlin.de> Advice and advocacy
|
||||
Thijs Kinkhorst <thijs@kinkhorst.com> rnano.1 manpage
|
||||
Jim Knoble <jmknoble@pobox.com> Pico compat for browser
|
||||
Ryan Krebs <fluffy@highwire.stanford.edu> Many bug fixes and testing
|
||||
Roy Lanek <lanek@ranahminang.net> Advice and advocacy
|
||||
Chuck Mead <csm@MoonGroup.com> Feedback and RPM stuff
|
||||
Mike Melanson <melanson@pcisys.net> Bugs
|
||||
Neil Parks <nparks@acsmail.com> Bug reports and fixes
|
||||
Jeremy Robichaud <robicj@yahoo.com> Beta tester
|
||||
Bill Soudan <wes0472@rit.edu> Regex code, etc
|
||||
Ken Tyler <kent@werple.net.au> Search fixes and more
|
||||
Ben Armstrong <synrg@sanctuary.nslug.ns.ca> Negative -r value idea, code
|
||||
Thomas Dickey <dickey@herndon4.his.com> Curses help and advice
|
||||
Sven Guckes <guckes@math.fu-berlin.de> Advice and advocacy
|
||||
Thijs Kinkhorst <thijs@kinkhorst.com> rnano.1 manpage
|
||||
Jim Knoble <jmknoble@pobox.com> Pico compat for browser
|
||||
Ryan Krebs <fluffy@highwire.stanford.edu> Many bug fixes and testing
|
||||
Roy Lanek <lanek@ranahminang.net> Advice and advocacy
|
||||
Chuck Mead <csm@MoonGroup.com> Feedback and RPM stuff
|
||||
Mike Melanson <melanson@pcisys.net> Bug reports
|
||||
Neil Parks <nparks@acsmail.com> Bug reports and fixes
|
||||
Jeremy Robichaud <robicj@yahoo.com> Beta tester
|
||||
Bill Soudan <wes0472@rit.edu> Regex code, etc
|
||||
Ken Tyler <kent@werple.net.au> Search fixes and more
|
||||
|
||||
16
TODO
16
TODO
@@ -2,11 +2,9 @@ A list of desired features
|
||||
--------------------------
|
||||
|
||||
Somewhat urgent:
|
||||
- Make undo/redo work also for justifying and indenting.
|
||||
- Make undo/redo work also for justifying.
|
||||
- Detect when text is being pasted, so that we can handle it faster.
|
||||
See https://savannah.gnu.org/bugs/?40060.
|
||||
- Allow to define and execute a macro: a stored sequence of keystrokes.
|
||||
See https://savannah.gnu.org/bugs/?50314.
|
||||
- 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.
|
||||
@@ -15,15 +13,16 @@ Somewhat urgent:
|
||||
See also https://savannah.gnu.org/bugs/?28993.
|
||||
|
||||
Vague musings:
|
||||
- FriBidi support?
|
||||
- Add support for right-to-left text (RTL), through FriBidi?
|
||||
- Allow setting marks (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?
|
||||
- Allow indentation of marked text by spaces as well as tabs?
|
||||
- Allow indentation to add just enough columns to reach the nearest
|
||||
multiple of tabsize, rather than always adding tabsize columns?
|
||||
|
||||
For version 2.9:
|
||||
- Make undo/redo work also for indenting. [DONE]
|
||||
- Allow to record and replay a macro: a stored series of keystrokes. [DONE]
|
||||
|
||||
For version 2.8:
|
||||
- Allow text searches in the help viewer. [DONE]
|
||||
@@ -41,8 +40,7 @@ For version 2.2:
|
||||
- Undo/Redo keys (M-U and M-E)? [DONE]
|
||||
- Fix problems with color syntaxes highlighting lines too aggressively. [DONE]
|
||||
- Allow nano to work like a pager (reading from stdin). [DONE]
|
||||
- Allow color syntaxes to be selected based on more than just filename
|
||||
extension. [DONE]
|
||||
- Select a color syntax based on more than just the filename extension. [DONE]
|
||||
- Allow soft wrapping as well as hard wrapping? [DONE]
|
||||
|
||||
For version 2.0:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="7f2c4e91361c28b8a6744a8b47f1d8d847c61d55"
|
||||
gnulib_hash="214bf852d8dab02bf62900e61facef2c9f48f2f4"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
750
configure.ac
750
configure.ac
File diff suppressed because it is too large
Load Diff
150
doc/faq.html
150
doc/faq.html
@@ -7,21 +7,23 @@
|
||||
<body text="#330000" bgcolor="#ffffff" link="#0000ef" vlink="#51188e" alink="#ff0000">
|
||||
|
||||
<h1>The GNU nano editor FAQ</h1>
|
||||
<h2>Table of Contents</h2>
|
||||
<h2><a href="#1">1. General</a></h2>
|
||||
<h3>Table of Contents</h3>
|
||||
<h3><a href="#1">1. General</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#1.1">1.1. What is GNU nano?</a><br>
|
||||
<a href="#1.2">1.2. What is the history behind nano?</a><br>
|
||||
<a href="#1.3">1.3. Why the name change from TIP?</a><br>
|
||||
<a href="#1.4">1.4. What is the current version of nano?</a><br>
|
||||
<a href="#1.5">1.5. I want to read the manpage without having to download the program!</a></p></blockquote>
|
||||
<h2><a href="#2">2. Where to get GNU nano.</a></h2>
|
||||
<a href="#1.5">1.5. I want to read the manpage without having to download the program!</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#2">2. Where to get GNU nano.</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#2.1">2.1. FTP and WWW sites that carry nano.</a><br>
|
||||
<a href="#2.2">2.2. RedHat and derivatives (.rpm) packages.</a><br>
|
||||
<a href="#2.3">2.3. Debian (.deb) packages.</a><br>
|
||||
<a href="#2.4">2.4. By GIT (for the brave).</a></p></blockquote>
|
||||
<h2><a href="#3">3. Installation and Configuration</a></h2>
|
||||
<a href="#2.4">2.4. By GIT (for the brave).</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#3">3. Installation and Configuration</a></h3>
|
||||
<blockquote><p>
|
||||
<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>
|
||||
@@ -31,46 +33,52 @@
|
||||
<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.9a">3.9a. How do I make a .nanorc file that nano will read when I start it?</a><br>
|
||||
<a href="#3.9b">3.9b. How about in Win32?</a></p></blockquote>
|
||||
<h2><a href="#4">4. Running</a></h2>
|
||||
<a href="#3.9b">3.9b. How about in Win32?</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#4">4. Running</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#4.1">4.1. How do I open a file with a name beginning with '+' from the command line?</a><br>
|
||||
<a href="#4.2">4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</a><br>
|
||||
<a href="#4.3">4.3. Ack! My numeric keypad's keys don't work properly when NumLock is off! What can I do?</a><br>
|
||||
<a href="#4.4">4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</a><br>
|
||||
<a href="#4.5">4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</a><br>
|
||||
<a href="#4.6">4.6. nano crashes when I type <insert keystroke here>!</a><br>
|
||||
<a href="#4.6">4.6. nano crashes when I type <insert keystrokes here>!</a><br>
|
||||
<a href="#4.7">4.7. nano crashes when I resize my window. How can I fix that?</a><br>
|
||||
<a href="#4.8a">4.8a. When I paste text into a document, each line gets indented further than the last. Why does nano do this, and how can I avoid it?</a><br>
|
||||
<a href="#4.8b">4.8b. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?<a><br>
|
||||
<a href="#4.8a">4.8a. With what keystroke can I paste text from the clipboard into nano?</a><br>
|
||||
<a href="#4.8b">4.8b. When I paste text into a document, each line gets indented further than the last. Why? And how can I stop this?</a><br>
|
||||
<a href="#4.8c">4.8c. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?<a><br>
|
||||
<a href="#4.9">4.9. I've compiled nano with color support, but I don't see any color when I run it!</a><br>
|
||||
<a href="#4.10">4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</a><br>
|
||||
<a href="#4.11">4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and nano's mouse support is turned on?</a><br>
|
||||
<a href="#4.12">4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</a></p></blockquote>
|
||||
<h2><a href="#5">5. Internationalization</a></h2>
|
||||
<a href="#4.12">4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#5">5. Internationalization</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#5.1">5.1. There's no translation for my language!</a><br>
|
||||
<a href="#5.2">5.2. I don't like the translation for <x> in my language. How can I fix it?</a><br>
|
||||
<a href="#5.3">5.3. What is the status of Unicode support?</a></p></blockquote>
|
||||
<h2><a href="#6">6. Advocacy and Licensing</a></h2>
|
||||
<a href="#5.3">5.3. What is the status of Unicode support?</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#6">6. Advocacy and Licensing</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#6.1">6.1. Why should I use nano instead of Pico?</a><br>
|
||||
<a href="#6.2">6.2. Why should I use Pico instead of nano?</a><br>
|
||||
<a href="#6.3">6.3. What is so bad about the older Pine license?</a><br>
|
||||
<a href="#6.4">6.4. Okay, well, what mail program should I use then?</a></p></blockquote>
|
||||
<h2><a href="#7">7. Miscellaneous</a></h2>
|
||||
<a href="#6.4">6.4. Okay, well, what mail program should I use then?</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#7">7. Miscellaneous</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#7.1">7.1. Where can I ask questions or send suggestions?</a><br>
|
||||
<a href="#7.2">7.2. How do I submit a bug report or patch?</a><br>
|
||||
<a href="#7.3">7.3. I want to send the development team a big load of cash (or just a thank you).</a><br>
|
||||
<a href="#7.4">7.4. How do I join the development team?</a><br>
|
||||
<a href="#7.5">7.5. Can I have write access to the GIT tree?</a></p></blockquote>
|
||||
<a href="#7.5">7.5. Can I have write access to the GIT tree?</a>
|
||||
</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="1"></a>1. General</h1>
|
||||
<h2><a name="1.1"></a>1.1. What is GNU nano?</h2>
|
||||
<h3><a name="1.1"></a>1.1. What is GNU nano?</h3>
|
||||
<blockquote><p>GNU nano is designed to be a free replacement for the Pico text editor, part of the Pine email suite from <a href="http://www.washington.edu/pine/">The University of Washington</a>. It aims to "emulate Pico as closely as possible and then include extra functionality".</p></blockquote>
|
||||
<h2><a name="1.2"></a>1.2. What is the history behind nano?</h2>
|
||||
<h3><a name="1.2"></a>1.2. What is the history behind nano?</h3>
|
||||
<blockquote><p>Funny you should ask!</p>
|
||||
<p><b>In the beginning...</b></p>
|
||||
<p>For years Pine was THE program used to read email on a Unix system. The Pico text editor is the portion of the program one would use to compose his or her mail messages. Many beginners to Unix flocked to Pico and Pine because of their well organized, easy to use interfaces. With the proliferation of GNU/Linux in the mid to late 90's, many University students became intimately familiar with the strengths (and weaknesses) of Pine and Pico.</p>
|
||||
@@ -80,30 +88,30 @@
|
||||
<p>It was in late 1999 when Chris Allegretta (our hero) was yet again complaining to himself about the less-than-perfect license Pico was distributed under, the 1000 makefiles that came with it and how just a few small improvements could make it the Best Editor in the World (TM). Having been a convert from Slackware to Debian, he missed having a simple binary package that included Pine and Pico, and had grown tired of downloading them himself.</p>
|
||||
<p>Finally something snapped inside and Chris coded and hacked like a madman for many hours straight one weekend to make a (barely usable) Pico clone, at the time called TIP (Tip Isn't Pico). The program could not be invoked without a filename, could not save files, had no help text display, spell checker, and so forth. But over time it improved, and with the help of a few great coders it matured to the (hopefully) stable state it is in today.</p>
|
||||
<p>In February 2001, nano was declared an official GNU program by Richard Stallman. nano also reached its first production release on March 22, 2001.</p></blockquote>
|
||||
<h2><a name="1.3"></a>1.3. Why the name change from TIP?</h2>
|
||||
<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>
|
||||
<h2><a name="1.4"></a>1.4. What is the current version of nano?</h2>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>2.9.0</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<h2><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h2>
|
||||
<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>2.9.7</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<h3><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h3>
|
||||
<blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/latest/nano.1.html">here</a>.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="2"></a>2. Where to get GNU nano.</h1>
|
||||
<h2><a name="2.1"></a>2.1. Web sites that carry nano.</h2>
|
||||
<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>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<h2><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h2>
|
||||
<h3><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h3>
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li><a href="https://kojipkgs.fedoraproject.org//packages/nano/">https://kojipkgs.fedoraproject.org//packages/nano/</a></li>
|
||||
<li><a href="https://software.opensuse.org/package/nano">https://software.opensuse.org/package/nano</a></li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<h2><a name="2.3"></a>2.3. Deb packages (Debian and derivatives):</h2>
|
||||
<h3><a name="2.3"></a>2.3. Deb packages (Debian and derivatives):</h3>
|
||||
<blockquote><p>Debian users can check out the current nano packages for:</p>
|
||||
<ul>
|
||||
<li><a href="http://packages.debian.org/stable/editors/nano">stable</a></li>
|
||||
@@ -112,14 +120,14 @@
|
||||
</ul>
|
||||
<p>You can also have a look at the <a href="ftp://ftp.debian.org/debian/pool/main/n/nano/">Package Pool</a> to see all the available binary and source packages.</p>
|
||||
</blockquote>
|
||||
<h2><a name="2.4"></a>2.4. By GIT (for the brave).</h2>
|
||||
<h3><a name="2.4"></a>2.4. By GIT (for the brave).</h3>
|
||||
<blockquote><p>For the 'bleeding edge' current version of nano, you can use GIT to download the current source code. <b>Note:</b> believe it or not, by downloading code that has not yet stabilized into an official release, there could quite possibly be bugs, in fact the code may not even compile! Anyway, see <a href="http://git.savannah.gnu.org/cgit/nano.git/tree/README.GIT">the nano GIT document</a> for info on anonymous GIT access to the nano source.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="3"></a>3. Installation and Configuration</h1>
|
||||
<h2><a name="3.1"></a>3.1. How do I install the RPM or DEB package?</h2>
|
||||
<h3><a name="3.1"></a>3.1. How do I install the RPM or DEB package?</h3>
|
||||
<blockquote><p>It's simple really! As root, type <b>rpm -Uvh nano-x.y.z-1.i386.rpm</b> if you have a RedHat-ish system or <b>dpkg -i nano_x.y.z-1.deb</b> if you have a Debian-ish system, where <b>x.y.z</b> is the release of nano. There are other programs to install packages, and if you wish to use those, knock yourself out.</p></blockquote>
|
||||
<h2><a name="3.2"></a>3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h2>
|
||||
<h3><a name="3.2"></a>3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h3>
|
||||
<blockquote><p>Okay, take a deep breath, this really isn't hard. Unpack the nano source with a command like:</p>
|
||||
<p><b>tar -xvf nano-x.y.z.tar.gz</b></p>
|
||||
<p>Then you need to run <b>configure</b> with any options you might want (if any).</p>
|
||||
@@ -128,13 +136,13 @@
|
||||
<b>./configure</b><br>
|
||||
<b>make</b><br>
|
||||
<b>make install</b> (as root, of course)</p></blockquote>
|
||||
<h2><a name="3.3"></a>3.3. Why does everything go into /usr/local?</h2>
|
||||
<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>
|
||||
<h2><a name="3.5"></a>3.5. nano should automatically run strip on the binary when installing it!</h2>
|
||||
<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>
|
||||
<h2><a name="3.6"></a>3.6. How can I make the executable smaller? This is too bloated!</h2>
|
||||
<h3><a name="3.6"></a>3.6. 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
|
||||
@@ -157,49 +165,51 @@
|
||||
<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>With <b>--disable-wrapping-as-root</b> you can disable any hard-wrapping by default when the user is root, useful to prevent accidentally changing long lines in system configuration files.</p>
|
||||
</blockquote>
|
||||
<h2><a name="3.7"></a>3.7. Tell me more about this multibuffer stuff!</h2>
|
||||
<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>--multibuffer</b> or <b>-F</b> flag when you invoke nano.</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 file buffer open, the ^X shortcut will say "Close", instead of the normal "Exit" when only one buffer is open.</p></blockquote>
|
||||
<h2><a name="3.8"></a>3.8. Tell me more about this verbatim input stuff!</h2>
|
||||
<h3><a name="3.7"></a>3.7. 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>
|
||||
<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 you've enabled Unicode support (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 statubar will change to "Unicode Input: ......" when you do this.</p></blockquote>
|
||||
<h2><a name="3.9a"></a>3.9a. How do I make a .nanorc file that will be read when I start nano?</h2>
|
||||
<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.9a"></a>3.9a. 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>
|
||||
<h2><a name="3.9b"></a>3.9b. How about in Win32?</h2>
|
||||
<h3><a name="3.9b"></a>3.9b. How about in Win32?</h3>
|
||||
<blockquote><p>If you're using the official nano .zip file and have extracted all the files, you should take the file nano.rc and place it somewhere on your Win32 system (for example, if you have write permission to do so, at the top of C:\). Then you must create an Environment variable called HOME which points to the directory where you put nano.rc. In Windows XP, you can get to Environment variables by right-clicking "My Computer" either on the desktop or in the Start Menu, and selecting Properties. This should bring up the System Properties panel. Then click the Advanced Tab, and there should be a button called Environment Variables. Click that to bring up the Environment Variables section. Now, under User Variables you should be able to click the New button, and make a new Variables Name called HOME, with the Variable Value of whatever path you copied nano.rc into (just the directory name; don't add nano.rc onto the end).</p>
|
||||
<p>We're still working on documentation for enabling syntax highlighting on Win32; please bear with us.</p>
|
||||
<p>Note that the nano.rc file must remain Unix-formatted in order for nano to understand it. In other words, you should probably use only nano to edit its config file. Other programs like Wordpad and Notepad will convert the file to DOS format when saving, and the latter does not even properly read Unix-formatted files to begin with.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="4"></a>4. Running</h1>
|
||||
<h2><a name="4.1"></a>4.1. How do I open a file with a name beginning with '+' from the command line?</h2>
|
||||
<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>
|
||||
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>
|
||||
<h2><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?</h2>
|
||||
<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>
|
||||
C Shell users (tcsh and csh): <b>setenv TERM vt100</b></p></blockquote>
|
||||
<h2><a name="4.3"></a>4.3. Ack! My numeric keypad's keys don't work properly when NumLock is off! What can I do?</h2>
|
||||
<h3><a name="4.3"></a>4.3. Ack! My numeric keypad's keys don't work properly when NumLock is off! What can I do?</h3>
|
||||
<blockquote><p>You can use the <b>-K</b> or <b>--rebindkeypad</b> option on the command line, or add the line <b>set rebindkeypad</b> to your .nanorc. However, nano's mouse support won't work properly if you do any of these things.</p></blockquote>
|
||||
<h2><a name="4.4"></a>4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</h2>
|
||||
<h3><a name="4.4"></a>4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</h3>
|
||||
<blockquote><p>This was a bug in how nano handled consecutive escape sequences. It should be fixed since version 2.6.0.</p></blockquote>
|
||||
<h2><a name="4.5"></a>4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</h2>
|
||||
<h3><a name="4.5"></a>4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</h3>
|
||||
<blockquote><p>It depends on the terminal type you're using. On some terminals, such as the FreeBSD console, xterm, konsole, and gnome-terminal, Shift-F1 to Shift-F4 will generate F13 to F16. On other terminals, such as the Linux console, rxvt, and Eterm, Shift-F3 to Shift-F6 will generate F13 to F16.</p></blockquote>
|
||||
<h2><a name="4.6"></a>4.6. nano crashes when I type <insert keystroke here>!</h2>
|
||||
<h3><a name="4.6"></a>4.6. nano crashes when I type <insert keystrokes here>!</h3>
|
||||
<blockquote><p>If you aren't trying some bizarre keystroke combination with some bizarre $TERM entry, chances are you have found a bug. You are welcome to submit it to the <a href="mailto:nano-devel@gnu.org">nano-devel</a> list or in the <a href="https://savannah.gnu.org/bugs/?group=nano">bug tracker</a> on Savannah.</p></blockquote>
|
||||
<h2><a name="4.7"></a>4.7. nano crashes when I resize my window. How can I fix that?</h2>
|
||||
<h3><a name="4.7"></a>4.7. nano crashes when I resize my window. How can I fix that?</h3>
|
||||
<blockquote><p>Older versions of nano had this problem. Please upgrade to version 2.7.0 or newer.</p></blockquote>
|
||||
<h2><a name="4.8a"></a>4.8a. When I paste text into a document, each line gets indented further than the last. Why does nano do this, and how can I avoid it?</h2>
|
||||
<blockquote><p>You have the autoindent feature turned on. Hit Meta-I to turn it off, paste your text, and then hit Meta-I again to turn it back on.</p></blockquote>
|
||||
<h2><a name="4.8b"></a>4.8b. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</h2>
|
||||
<h3><a name="4.8a"></a>4.8a. With what keystroke can I paste text from the clipboard into nano?</h3>
|
||||
<blockquote><p>In most desktop environments <b>Shift+Insert</b> will paste the contents of the clipboard.</p></blockquote>
|
||||
<h3><a name="4.8b"></a>4.8b. 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>
|
||||
<h3><a name="4.8c"></a>4.8c. 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>
|
||||
<h2><a name="4.9"></a>4.9. I've compiled nano with color support, but I don't see any color when I run it!</h2>
|
||||
<h3><a name="4.9"></a>4.9. 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.9a">3.9a</a>.</p></blockquote>
|
||||
<h2><a name="4.10"></a>4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</h2>
|
||||
<h3><a name="4.10"></a>4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</h3>
|
||||
<blockquote><p>You need to make nano your $EDITOR. If you want this to be saved, you should put a line like this in your <b>.bashrc</b> if you use bash (or <b>.zshrc</b> if you believe in zsh):</p>
|
||||
<p><b>export EDITOR=/usr/local/bin/nano</b></p>
|
||||
<p>or, if you use tcsh, put this in your <b>.cshrc</b> file:</p>
|
||||
@@ -212,53 +222,53 @@
|
||||
<p>If you're a mutt user, you should see an effect immediately the next time you log in. No further configuration is needed. However, if you want to let people know you use nano to compose your email messages, you can put a line like this in your <b>.muttrc</b>:</p>
|
||||
<p><b>my_hdr X-Composer: nano x.y.z</b></p>
|
||||
<p>Again, replace x.y.z with the version of nano you use.</p></blockquote>
|
||||
<h2><a name="4.11"></a>4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and nano's mouse support is turned on?</h2>
|
||||
<h3><a name="4.11"></a>4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and 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>
|
||||
<h2><a name="4.12"></a>4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</h2>
|
||||
<h3><a name="4.12"></a>4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</h3>
|
||||
<blockquote><p>In nano 2.3.0, cursor-position history was introduced, and both history files now reside in a .nano subdirectory in your home directory. A newer nano will move an existing search-history file to this new location so it can continue to be used. This means that if you then try and use an earlier version of nano, it will be unable to see your current search history. To fix this, run the following command:</p>
|
||||
<p><b>ln -sf ~/.nano/search_history ~/.nano_history</b></p>
|
||||
<p>The "migration service" (moving the search-history file to its new location) will be deleted from nano in early 2018.</p></blockquote>
|
||||
<p>The "migration service" (moving the search-history file to its new location) has been deleted from nano in late 2017, since version 2.9.0. The search-history and position-history files will now be looked for first in ~/.nano/ and, when not found there, then in ~/.local/share/nano/.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="5"></a>5. Internationalization</h1>
|
||||
<h2><a name="5.1"></a>5.1. There's no translation for my language!</h2>
|
||||
<h3><a name="5.1"></a>5.1. There's no translation for my language!</h3>
|
||||
<blockquote><p>In June 2001, GNU nano entered the <a href="http://translationproject.org/html/welcome.html">Translation Project</a> and since then, translations should be managed from there.</p>
|
||||
<p>If there isn't a translation for your language, you could ask <a href="http://translationproject.org/team/">your language team</a> to translate nano, or better still, join that team and do it yourself. Joining a team is easy. You just need to ask the team leader to add you, and then send a <a href="http://translationproject.org/disclaim.txt">translation disclaimer to the FSF</a> (this is necessary as nano is an official GNU package, but it does <b>not</b> mean that you transfer the rights of your work to the FSF, it's just so the FSF can legally manage them).</p>
|
||||
<p>In any case, translating nano is very easy. Just grab the latest <b>nano.pot</b> file listed on <a href="http://translationproject.org/domain/nano.html">nano's page</a> at the TP, and translate each <b>msgid</b> line into your native language on the <b>msgstr</b> line. When you're done, you should send it to the TP's central po repository.</p></blockquote>
|
||||
<h2><a name="5.2"></a>5.2. I don't like the translation for <x> in my language. How can I fix it?</h2>
|
||||
<blockquote><p>The best way would probably be to send an e-mail to the team's mailing listed mentione in the <code>Language-Team:</code> field in the <b><your_language>.po</b> file with your suggested corrections, and then they can make the changes reach the nano-devel list.</p></blockquote>
|
||||
<h2><a name="5.3"></a>5.3. What is the status of Unicode support?</h2>
|
||||
<blockquote><p>Since versions 1.3.12, Unicode should be usable. With your terminal, locale (LC_ALL and similar environment variables), and encoding configured to properly support UTF-8, you should be able to enter and save Unicode text.</p></blockquote>
|
||||
<p>In any case, translating nano is easy. Just grab the latest <b>nano.pot</b> file listed on <a href="http://translationproject.org/domain/nano.html">nano's page</a> at the TP, and translate each <b>msgid</b> line into your native language on the <b>msgstr</b> line. When you're done, you should send it to the TP's central PO-file repository.</p></blockquote>
|
||||
<h3><a name="5.2"></a>5.2. I don't like the translation for <x> in my language. How can I fix it?</h3>
|
||||
<blockquote><p>The best way is to send an e-mail with your suggested corrections to the team's mailing list. The address is mentioned in the <code>Language-Team:</code> field in the relevant PO file. The team leader or the assigned translator can then make the changes reach the nano-devel list.</p></blockquote>
|
||||
<h3><a name="5.3"></a>5.3. What is the status of Unicode support?</h3>
|
||||
<blockquote><p>Unicode should be fully usable nowadays. When the encoding of your terminal is set to UTF-8, and your locale (mainly the LANG environment variable) is UTF-8 too, then you should be able to read, enter and save Unicode text.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="6"></a>6. Advocacy and Licensing</h1>
|
||||
<h2><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h2>
|
||||
<h3><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h3>
|
||||
<blockquote><p>There are many reasons to use nano instead of Pico. A more complete list can be found at the <a href="https://nano-editor.org/">nano homepage</a>.</p></blockquote>
|
||||
<h2><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h2>
|
||||
<h3><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h3>
|
||||
<blockquote><p>Again, check out the <a href="https://nano-editor.org/">nano homepage</a> for a good summary of reasons. It really is a matter of personal preference as to which editor you should use. If you're the type of person who likes using the original version of a program, then Pico is the editor for you. If you don't mind sacrificing mailer integration with Pine, and are looking for a few more features, as well as a 'better' license in terms of adding your own changes, nano is the way to go.</p>
|
||||
<p>Note that the last of these no longer applies to the new version of Pine, <a href="http://www.washington.edu/alpine/">Alpine</a>, which is under the Apache License, version 2.0.</p></blockquote>
|
||||
<h2><a name="6.3"></a>6.3. What is so bad about the older Pine license?</h2>
|
||||
<h3><a name="6.3"></a>6.3. What is so bad about the older Pine license?</h3>
|
||||
<blockquote><p>The U of W license for older versions of Pine and Pico is not considered truly Free Software according to both the Free Software Foundation and the <a href="http://www.debian.org/social_contract#guidelines">Debian Free Software Guidelines</a>. The main problem regards the limitations on distributing derived works: according to UW, you can distribute their software, and you can modify it, but you can not do both, i.e. distribute modified binaries.</p></blockquote>
|
||||
<h2><a name="6.4"></a>6.4. Okay, well, what mail program should I use then?</h2>
|
||||
<h3><a name="6.4"></a>6.4. Okay, well, what mail program should I use then?</h3>
|
||||
<blockquote><p>If you are looking to use a Free Software program similar to Pine, and Emacs is not your thing, you should definitely take a look at <a href="http://www.mutt.org/">mutt</a>. It is a full-screen, console based mail program that actually has a lot more flexibility than Pine, but has a keymap included in the distribution that allows you to use the same keystrokes as Pine would to send and receive mail. It's also under the GNU General Public License, version 2.0.</p>
|
||||
<p>Of course, due to the license change you can now use the <a href="http://www.washington.edu/alpine/">Alpine distribution</a> of PINE as it is now considered Free Software, but you would be sacrificing many of nano's features to do so.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="7"></a>7. Miscellaneous</h1>
|
||||
<h2><a name="7.1"></a>7.1. Where can I ask questions or send suggestions?</h2>
|
||||
<h3><a name="7.1"></a>7.1. Where can I ask questions or send suggestions?</h3>
|
||||
<blockquote><p>There are three mailing lists for nano hosted at <a href="http://savannah.gnu.org/">Savannah</a>: info-nano, help-nano and nano-devel. info-nano is a very low traffic list where new versions of nano are announced (surprise!). help-nano is for getting help with the editor without needing to hear all of the development issues surrounding it. nano-devel is a normally low, sometimes high traffic list for discussing the present and future development of nano. Here are links to where you can sign up for a given list:</p>
|
||||
<p>info-nano - <a href="http://mail.gnu.org/mailman/listinfo/info-nano/">http://mail.gnu.org/mailman/listinfo/info-nano/</a><br>
|
||||
help-nano - <a href="http://mail.gnu.org/mailman/listinfo/help-nano/">http://mail.gnu.org/mailman/listinfo/help-nano/</a><br>
|
||||
nano-devel - <a href="http://mail.gnu.org/mailman/listinfo/nano-devel/">http://mail.gnu.org/mailman/listinfo/nano-devel/</a></p></blockquote>
|
||||
<h2><a name="7.2"></a>7.3. How do I submit a bug report or patch?</h2>
|
||||
<h3><a name="7.2"></a>7.3. How do I submit a bug report or patch?</h3>
|
||||
<blockquote>
|
||||
<p>The best way to submit bugs is through the <a href="https://savannah.gnu.org/bugs/?group=nano">Savannah bug tracker</a>, as you can check whether the bug you are reporting has already been submitted, and it makes it easier for the maintainers to keep track of them.
|
||||
<p>You can submit patches for nano via <a href="https://savannah.gnu.org/patch/?group=nano">Savannah's patch manager</a>.</p></blockquote>
|
||||
<h2><a name="7.3"></a>7.3. I want to send the development team a big load of cash (or just a thank you).</h2>
|
||||
<h3><a name="7.3"></a>7.3. I want to send the development team a big load of cash (or just a thank you).</h3>
|
||||
<blockquote><p>That's fine. Send it <a href="mailto:nano-devel@gnu.org">our way</a>! Better yet, fix a <a href="https://savannah.gnu.org/bugs/?group=nano">bug</a> in the program or implement a <a href="https://nano-editor.org/dist/latest/TODO">cool feature</a> and send us that instead (though cash is fine too).</p></blockquote>
|
||||
<h2><a name="7.4"></a>7.4. How do I join the development team?</h2>
|
||||
<h3><a name="7.4"></a>7.4. How do I join the development team?</h3>
|
||||
<blockquote><p>The easiest way is to consistently send in good patches that add some needed functionality, fix a bug or two, and/or make the program more optimized/efficient. Then ask nicely and you will probably be added to the Savannah development list and be given write access after a while. There is a lot of responsibility that goes along with being a team member, so don't think it's just something to add to your resume.</p></blockquote>
|
||||
<h2><a name="7.5"></a>7.5. Can I have write access to the git tree?</h2>
|
||||
<h3><a name="7.5"></a>7.5. Can I have write access to the git tree?</h3>
|
||||
<blockquote><p>Re-read section <a href="#7.4">7.4</a> and you should know the answer.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
|
||||
24
doc/nano.1
24
doc/nano.1
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <http://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 2.9.0" "November 2017"
|
||||
.TH NANO 1 "version 2.9.7" "May 2018"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, an enhanced free Pico clone
|
||||
@@ -54,9 +54,9 @@ highlighted), and then use \fB^K\fR to cut it, or \fBM\-6\fR to copy it to the
|
||||
cutbuffer. One can also save the marked text to a file with \fB^O\fR, or
|
||||
spell check it with \fB^T\fR.
|
||||
.PP
|
||||
Since nano-2.7.0, text can also be selected by holding Shift and moving the
|
||||
cursor with the arrow keys. Holding down the Alt key too will increase the
|
||||
stride.
|
||||
On some terminals, text can be selected also by holding down Shift while
|
||||
using the arrow keys. Holding down the Alt key too will increase the stride.
|
||||
Any cursor movement without Shift being held will cancel such a selection.
|
||||
.PP
|
||||
The two lines at the bottom of the screen show some important commands;
|
||||
the built-in help (\fB^G\fR) lists all the available ones.
|
||||
@@ -108,6 +108,10 @@ won't work properly with this option enabled.
|
||||
.BR \-L ", " \-\-nonewlines
|
||||
Don't add newlines to the ends of files.
|
||||
.TP
|
||||
.BR \-M ", " \-\-trimblanks
|
||||
Snip trailing whitespace from the wrapped line when automatic
|
||||
hard-wrapping occurs or when text is justified.
|
||||
.TP
|
||||
.BR \-N ", " \-\-noconvert
|
||||
Disable automatic conversion of files from DOS/Mac format.
|
||||
.TP
|
||||
@@ -117,7 +121,6 @@ Use the blank line below the title bar as extra editing space.
|
||||
.BR \-P ", " \-\-positionlog
|
||||
For the 200 most recent files, log the last position of the cursor,
|
||||
and place it at that position again upon reopening such a file.
|
||||
(The old form of this option, \fB\-\-poslog\fR, is deprecated.)
|
||||
.TP
|
||||
.BR "\-Q ""\fIcharacters\fB""" ", " "\-\-quotestr=""" \fIcharacters """
|
||||
Set the quoting string for justifying. The default is
|
||||
@@ -247,6 +250,9 @@ Disable the hard-wrapping of long lines. This option conflicts with
|
||||
.BR \-x ", " \-\-nohelp
|
||||
Don't show the two help lines at the bottom of the screen.
|
||||
.TP
|
||||
.BR \-y ", " \-\-afterends
|
||||
Make Ctrl+Right stop at word ends instead of beginnings.
|
||||
.TP
|
||||
.BR \-z ", " \-\-suspend
|
||||
Enable the suspend ability.
|
||||
.TP
|
||||
@@ -300,12 +306,16 @@ cannot be undone any more. The workaround is, of course, to exit without
|
||||
saving.
|
||||
.sp
|
||||
The recording and playback of keyboard macros works correctly only on a
|
||||
terminal emulator, not on a Linux console (VT), because the latter is a
|
||||
deficient terminal. And it works only with recent versions of ncurses.
|
||||
terminal emulator, not on a Linux console (VT), because the latter does
|
||||
not by default distinguish modified from unmodified arrow keys.
|
||||
.sp
|
||||
Please report any other bugs that you encounter via:
|
||||
.br
|
||||
\fIhttps://savannah.gnu.org/bugs/?group=nano\fR.
|
||||
.sp
|
||||
When nano crashes, it will save any modified buffers to emergency .save files.
|
||||
If you are able to reproduce the crash and you want to get a backtrace, define
|
||||
the environment variable \fBNANO_NOCATCH\fR.
|
||||
|
||||
.SH HOMEPAGE
|
||||
\fIhttps://nano-editor.org/\fR
|
||||
|
||||
104
doc/nano.texi
104
doc/nano.texi
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 2.9.0
|
||||
@set UPDATED November 2017
|
||||
@set VERSION 2.9.7
|
||||
@set UPDATED May 2018
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 2.9.0
|
||||
@subtitle version 2.9.7
|
||||
|
||||
@author Chris Allegretta
|
||||
@page
|
||||
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
|
||||
@node Top
|
||||
@top
|
||||
|
||||
This manual documents the GNU @command{nano} editor, version 2.9.0.
|
||||
This manual documents the GNU @command{nano} editor, version 2.9.7.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@@ -200,6 +200,11 @@ won't work properly with this option enabled.
|
||||
@itemx --nonewlines
|
||||
Don't add newlines to the ends of files.
|
||||
|
||||
@item -M
|
||||
@itemx --trimblanks
|
||||
Snip trailing whitespace from the wrapped line when automatic
|
||||
hard-wrapping occurs or when text is justified.
|
||||
|
||||
@item -N
|
||||
@itemx --noconvert
|
||||
Disable automatic conversion of files from DOS/Mac format.
|
||||
@@ -212,7 +217,6 @@ Use the blank line below the title bar as extra editing space.
|
||||
@itemx --positionlog
|
||||
For the 200 most recent files, log the last position of the cursor,
|
||||
and place it at that position again upon reopening such a file.
|
||||
(The old form of this option, @option{--poslog}, is deprecated.)
|
||||
|
||||
@item -Q "@var{characters}"
|
||||
@itemx --quotestr="@var{characters}"
|
||||
@@ -388,6 +392,10 @@ is located at the very bottom of the editor.
|
||||
Note: When accessing the help system, Expert Mode is temporarily
|
||||
disabled to display the help-system navigation keys.
|
||||
|
||||
@item -y
|
||||
@itemx --afterends
|
||||
Make Ctrl+Right stop at word ends instead of beginnings.
|
||||
|
||||
@item -z
|
||||
@itemx --suspend
|
||||
Enable the ability to suspend @command{nano} using the system's suspend
|
||||
@@ -493,12 +501,15 @@ the 'Copy Text' command (default key binding: @kbd{M-6}).
|
||||
|
||||
Text can be selected by first 'setting the Mark' (default key bindings:
|
||||
@kbd{^6} and @kbd{M-A}) and then moving the cursor to the other end of the portion
|
||||
to be selected. The selected portion of text will be highlighted in
|
||||
reverse video (or in bold if you set the boldtext option).
|
||||
to be selected. The selected portion of text will be highlighted.
|
||||
This selection can now be cut or copied in its entirety with a single
|
||||
@kbd{^K} or @kbd{M-6}. Or the selection can be used to limit the scope of
|
||||
a search-and-replace (@kbd{^\}) or spell-checking session (@kbd{^T}).
|
||||
|
||||
On some terminals, it is also possible to select text by holding down
|
||||
@kbd{Shift} together with the cursor keys. Such a selection is cancelled
|
||||
upon any cursor movement where @kbd{Shift} isn't held.
|
||||
|
||||
Cutting or copying selected text will toggle the mark off automatically.
|
||||
If necessary, it can be toggled off manually with another @kbd{^6} or @kbd{M-A}.
|
||||
|
||||
@@ -562,8 +573,8 @@ cannot be undone any more. The workaround is, of course, to exit without
|
||||
saving.
|
||||
|
||||
The recording and playback of keyboard macros works correctly only on a
|
||||
terminal emulator, not on a Linux console (VT), because the latter is a
|
||||
deficient terminal. And it works only with recent versions of ncurses.
|
||||
terminal emulator, not on a Linux console (VT), because the latter does
|
||||
not by default distinguish modified from unmodified arrow keys.
|
||||
|
||||
@node Built-in Help
|
||||
@chapter Built-in Help
|
||||
@@ -682,6 +693,9 @@ The supported settings in a nanorc file are:
|
||||
|
||||
@table @code
|
||||
|
||||
@item set afterends
|
||||
Make Ctrl+Right stop at word ends instead of beginnings.
|
||||
|
||||
@item set allow_insecure_backup
|
||||
When backing up files, allow the backup to succeed even if its
|
||||
permissions can't be (re)set due to special OS considerations.
|
||||
@@ -726,13 +740,16 @@ Do case-sensitive searches by default.
|
||||
|
||||
@item set constantshow
|
||||
Constantly display the cursor position on the status bar.
|
||||
(The old form of this option, @code{set const}, is deprecated.)
|
||||
Note that this overrides @option{quickblank}.
|
||||
|
||||
@item set cutfromcursor
|
||||
Use cut-from-cursor-to-end-of-line by default, instead of cutting the whole line.
|
||||
(The old form of this option, @code{set cut}, is deprecated.)
|
||||
|
||||
@item set errorcolor @var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for the status bar when an error message is displayed.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set fill @var{number}
|
||||
Hard-wrap lines at column number @var{number}. If @var{number} is 0 or less,
|
||||
the maximum line length will be the screen width less @var{number} columns.
|
||||
@@ -745,7 +762,8 @@ Use this color combination for the concise function descriptions
|
||||
in the two help lines at the bottom of the screen.
|
||||
Valid names for foreground and background color are:
|
||||
@code{white}, @code{black}, @code{blue}, @code{green},
|
||||
@code{red}, @code{cyan}, @code{yellow}, and @code{magenta}.
|
||||
@code{red}, @code{cyan}, @code{yellow}, @code{magenta}, and @code{normal}
|
||||
--- where @code{normal} means the default foreground or background color.
|
||||
The name of the foreground color may be prefixed with @code{bright}.
|
||||
And either @var{fgcolor} or ,@var{bgcolor} may be left out.
|
||||
|
||||
@@ -753,9 +771,6 @@ And either @var{fgcolor} or ,@var{bgcolor} may be left out.
|
||||
Save the last hundred search strings and replacement strings and
|
||||
executed commands, so they can be easily reused in later sessions.
|
||||
|
||||
@item set justifytrim
|
||||
When justifying text, trailing whitespace will automatically be removed.
|
||||
|
||||
@item set keycolor @var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for the shortcut key combos
|
||||
in the two help lines at the bottom of the screen.
|
||||
@@ -813,7 +828,6 @@ directory feature is turned off.
|
||||
@item set positionlog
|
||||
Save the cursor position of files between editing sessions.
|
||||
The cursor position is remembered for the 200 most-recently edited files.
|
||||
(The old form of this option, @code{set poslog}, is deprecated.)
|
||||
|
||||
@item set preserve
|
||||
Preserve the XON and XOFF keys (@kbd{^Q} and @kbd{^S}).
|
||||
@@ -899,6 +913,11 @@ Save automatically on exit, don't prompt.
|
||||
Use this color combination for the title bar.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set trimblanks
|
||||
Remove trailing whitespace from wrapped lines when automatic
|
||||
hard-wrapping occurs or when text is justified.
|
||||
(The old form of this option, @code{set justifytrim}, is deprecated.)
|
||||
|
||||
@item set unix
|
||||
Save a file by default in Unix format. This overrides nano's
|
||||
default behavior of saving a file in the format that it had.
|
||||
@@ -1031,7 +1050,7 @@ in one of the system-installed files (which normally are not writable).
|
||||
@node Rebinding Keys
|
||||
@section Rebinding Keys
|
||||
|
||||
Key bindings can be changed via the following two commands in a
|
||||
Key bindings can be changed via the following three commands in a
|
||||
nanorc file:
|
||||
|
||||
@table @code
|
||||
@@ -1040,6 +1059,13 @@ nanorc file:
|
||||
Rebinds @code{key} to @code{function} in the context of @code{menu}
|
||||
(or in all menus where the function exists by using @code{all}).
|
||||
|
||||
@item bind key "string" menu
|
||||
Makes @code{key} produce @code{string} in the context of @code{menu}
|
||||
(or in all menus where the key exists when @code{all} is used).
|
||||
The @code{string} can consist of text or commands or a mix of them.
|
||||
(To enter a command into the @code{string}, precede its keystroke
|
||||
with @kbd{M-V}.)
|
||||
|
||||
@item unbind key menu
|
||||
Unbinds @code{key} from @code{menu}
|
||||
(or from all menus where it exists by using @code{all}).
|
||||
@@ -1096,7 +1122,6 @@ Starts a backward search for text in the current buffer.
|
||||
|
||||
@item searchagain
|
||||
Repeats the last search command without prompting.
|
||||
(The form @code{research} is deprecated.)
|
||||
|
||||
@item findprevious
|
||||
As @code{searchagain}, but always in the backward direction.
|
||||
@@ -1131,7 +1156,6 @@ Cuts all text from the cursor position till the end of the buffer.
|
||||
|
||||
@item curpos
|
||||
Shows the current cursor position: the line, column, and character positions.
|
||||
(The form @code{cursorpos} is deprecated.)
|
||||
|
||||
@item wordcount
|
||||
Counts the number of words, lines and characters in the current buffer.
|
||||
@@ -1173,10 +1197,12 @@ Goes one line up (in the editor or browser).
|
||||
Goes one line down (in the editor or browser).
|
||||
|
||||
@item scrollup
|
||||
Scrolls up one line of text from the current position.
|
||||
Scrolls the viewport up one row (meaning that the text slides down)
|
||||
while keeping the cursor in the same text position, if possible.
|
||||
|
||||
@item scrolldown
|
||||
Scrolls down one line of text from the current position.
|
||||
Scrolls the viewport down one row (meaning that the text slides up)
|
||||
while keeping the cursor in the same text position, if possible.
|
||||
|
||||
@item prevword
|
||||
Moves the cursor to the beginning of the previous word.
|
||||
@@ -1219,9 +1245,6 @@ Goes to the last line of the file.
|
||||
Goes to a specific line (and column if specified). Negative numbers count
|
||||
from the end of the file (and end of the line).
|
||||
|
||||
@item gototext
|
||||
Switches from targeting a line number to searching for text.
|
||||
|
||||
@item findbracket
|
||||
Moves the cursor to the bracket (brace, parenthesis, etc.) that matches
|
||||
(pairs) with the one under the cursor.
|
||||
@@ -1272,7 +1295,6 @@ Toggles case sensitivity in searching (search/replace menus only).
|
||||
|
||||
@item regexp
|
||||
Toggles whether searching/replacing is based on literal strings or regular expressions.
|
||||
(The form @code{regex} is deprecated.)
|
||||
|
||||
@item backwards
|
||||
Toggles whether searching/replacing goes forward or backward.
|
||||
@@ -1285,7 +1307,10 @@ Shows the next history entry in the prompt menus (e.g.@: search).
|
||||
|
||||
@item flipreplace
|
||||
Toggles between searching for something and replacing something.
|
||||
(The form @code{dontreplace} is deprecated.)
|
||||
|
||||
@item flipgoto
|
||||
Toggles between searching for text and targeting a line number.
|
||||
(The form @code{gototext} is deprecated.)
|
||||
|
||||
@item flipexecute
|
||||
Toggles between inserting a file and executing a command.
|
||||
@@ -1293,7 +1318,6 @@ Toggles between inserting a file and executing a command.
|
||||
@item flipnewbuffer
|
||||
Toggles between inserting into the current buffer and into a new
|
||||
empty buffer.
|
||||
(The form @code{newbuffer} is deprecated.)
|
||||
|
||||
@item dosformat
|
||||
When writing a file, switches to writing a DOS format (CR/LF).
|
||||
@@ -1331,8 +1355,9 @@ Goes to the last file when using the file browser (reading or writing files).
|
||||
@item nohelp
|
||||
Toggles the presence of the two-line list of key bindings at the bottom of the screen.
|
||||
|
||||
@item constupdate
|
||||
@item constantshow
|
||||
Toggles the constant display of the current line, column, and character positions.
|
||||
(The form @code{constupdate} is deprecated.)
|
||||
|
||||
@item morespace
|
||||
Toggles the presence of the blank line that 'separates' the title bar from the file text.
|
||||
@@ -1343,6 +1368,9 @@ Toggles smooth scrolling (when moving around with the arrow keys).
|
||||
@item softwrap
|
||||
Toggles the displaying of overlong lines on multiple screen lines.
|
||||
|
||||
@item linenumbers
|
||||
Toggles the display of line numbers in front of the text.
|
||||
|
||||
@item whitespacedisplay
|
||||
Toggles the showing of whitespace.
|
||||
|
||||
@@ -1355,9 +1383,10 @@ Toggles the smartness of the Home key.
|
||||
@item autoindent
|
||||
Toggles whether new lines will contain the same amount of whitespace as the preceding line.
|
||||
|
||||
@item cuttoend
|
||||
@item cutfromcursor
|
||||
Toggles whether cutting text will cut the whole line or just from the current cursor
|
||||
position to the end of the line.
|
||||
(The form @code{cuttoend} is deprecated.)
|
||||
|
||||
@item nowrap
|
||||
Toggles whether long lines will be hard-wrapped to the next line.
|
||||
@@ -1399,7 +1428,6 @@ The 'search to replace' menu.
|
||||
|
||||
@item replacewith
|
||||
The 'replace with' menu, which comes up after 'search to replace'.
|
||||
(The form @code{replace2} is deprecated.)
|
||||
|
||||
@item gotoline
|
||||
The 'goto line (and column)' menu.
|
||||
@@ -1423,7 +1451,7 @@ The interactive spell checker Yes/no menu.
|
||||
The linter menu.
|
||||
|
||||
@item browser
|
||||
The file browser for inserting or writing a file.
|
||||
The file browser, for choosing a file to read from or write to.
|
||||
|
||||
@item whereisfile
|
||||
The 'search for a file' menu in the file browser.
|
||||
@@ -1442,14 +1470,15 @@ it means all menus where the specified @code{key} exists.
|
||||
@node The File Browser
|
||||
@chapter The File Browser
|
||||
|
||||
When reading or writing files, pressing @kbd{^T} will invoke the file browser.
|
||||
When in the Read-File (@kbd{^R}) or Write-Out menu (@kbd{^O}),
|
||||
pressing @kbd{^T} will invoke the file browser.
|
||||
Here, one can navigate directories in a graphical manner in order to
|
||||
find the desired file.
|
||||
|
||||
Basic movement in the file browser is accomplished with the arrow keys,
|
||||
page up, and page down. More advanced movement is accomplished by
|
||||
searching via @kbd{^W} (or @kbd{w'} and changing directories via
|
||||
@kbd{^_} (or @kbd{g}). The behavior of the @kbd{Enter} key (or @kbd{s})
|
||||
Basic movement in the file browser is accomplished with the arrow and
|
||||
other cursor-movement keys. More targeted movement is accomplished by
|
||||
searching, via @kbd{^W} or @kbd{w'}, or by changing directory, via
|
||||
@kbd{^_} or @kbd{g}. The behavior of the @kbd{Enter} key (or @kbd{s})
|
||||
varies by what is currently selected.
|
||||
If the currently selected object is a directory, the file browser will
|
||||
enter and display the contents of the directory. If the object is a
|
||||
@@ -1490,6 +1519,11 @@ The output of the "Display Cursor Position" command (@kbd{^C}) displays
|
||||
not only the current line and character position of the cursor,
|
||||
but also (between the two) the current column position.
|
||||
|
||||
@item Hard-Wrapping
|
||||
By default, @command{nano} hard-wraps lines at screen width minus eight
|
||||
columns, whereas Pico does it at screen width minus six columns. You can
|
||||
make @command{nano} do the same as Pico by using @option{--fill=-6}.
|
||||
|
||||
@item Spell Checking
|
||||
In the internal spell checker misspelled words are sorted alphabetically
|
||||
and trimmed for uniqueness, such that the words 'apple' and 'Apple' will
|
||||
|
||||
63
doc/nanorc.5
63
doc/nanorc.5
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <http://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 2.9.0" "November 2017"
|
||||
.TH NANORC 5 "version 2.9.7" "May 2018"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
@@ -53,6 +53,9 @@ match \fB"\fP, \fB'\fP, \fB)\fP, \fB>\fP, \fB]\fP, and \fB}\fP.
|
||||
The supported commands and arguments are:
|
||||
|
||||
.TP 3
|
||||
.B set afterends
|
||||
Make Ctrl+Right stop at word ends instead of beginnings.
|
||||
.TP
|
||||
.B set allow_insecure_backup
|
||||
When backing up files, allow the backup to succeed even if its permissions
|
||||
can't be (re)set due to special OS considerations. You should
|
||||
@@ -96,13 +99,16 @@ Do case-sensitive searches by default.
|
||||
.TP
|
||||
.B set constantshow
|
||||
Constantly display the cursor position in the status bar.
|
||||
(The old form of this option, '\fBset const\fR', is deprecated.)
|
||||
This overrides the option \fBquickblank\fR.
|
||||
.TP
|
||||
.B set cutfromcursor
|
||||
Use cut-from-cursor-to-end-of-line by default, instead of cutting the whole line.
|
||||
(The old form of this option, '\fBset cut\fR', is deprecated.)
|
||||
.TP
|
||||
.B set errorcolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Use this color combination for the status bar when an error message is displayed.
|
||||
See \fBset titlecolor\fR for valid color names.
|
||||
.TP
|
||||
.B set fill \fInumber\fR
|
||||
Hard-wrap lines at column number \fInumber\fR. If \fInumber\fR is 0 or less,
|
||||
the maximum line length will be the screen width less \fInumber\fP columns.
|
||||
@@ -118,9 +124,6 @@ See \fBset titlecolor\fR for more details.
|
||||
Save the last hundred search strings and replacement strings and
|
||||
executed commands, so they can be easily reused in later sessions.
|
||||
.TP
|
||||
.B set justifytrim
|
||||
When justifying text, trailing whitespace will automatically be removed.
|
||||
.TP
|
||||
.B set keycolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Specify the color combination to use for the shortcut key combos
|
||||
in the two help lines at the bottom of the screen.
|
||||
@@ -181,7 +184,6 @@ directory feature is turned off.
|
||||
.B set positionlog
|
||||
Save the cursor position of files between editing sessions.
|
||||
The cursor position is remembered for the 200 most-recently edited files.
|
||||
(The old form of this option, '\fBset poslog\fR', is deprecated.)
|
||||
.TP
|
||||
.B set preserve
|
||||
Preserve the XON and XOFF keys (^Q and ^S).
|
||||
@@ -265,10 +267,17 @@ Save automatically on exit, don't prompt.
|
||||
.B set titlecolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Specify the color combination to use for the title bar.
|
||||
Valid names for the foreground and background colors are:
|
||||
.BR white ", " black ", " blue ", " green ", " red ", " cyan ", " yellow ", and " magenta .
|
||||
.BR white ", " black ", " blue ", " green ", " red ", "
|
||||
.BR cyan ", " yellow ", " magenta ", and " normal
|
||||
-- where \fBnormal\fR means the default foreground or background color.
|
||||
The name of the foreground color may be prefixed with \fBbright\fR.
|
||||
And either "\fIfgcolor\fR" or ",\fIbgcolor\fR" may be left out.
|
||||
.TP
|
||||
.B set trimblanks
|
||||
Remove trailing whitespace from wrapped lines when automatic
|
||||
hard-wrapping occurs or when text is justified.
|
||||
(The old form of this option, '\fBset justifytrim\fR', is deprecated.)
|
||||
.TP
|
||||
.B set unix
|
||||
Save a file by default in Unix format. This overrides nano's
|
||||
default behavior of saving a file in the format that it had.
|
||||
@@ -392,16 +401,26 @@ slightly improve a syntax defined in one of the system-installed
|
||||
files (which normally are not writable).
|
||||
|
||||
.SH REBINDING KEYS
|
||||
Key bindings can be changed via the following two commands:
|
||||
Key bindings can be changed via the following three commands:
|
||||
.RS 3
|
||||
.TP
|
||||
.BI bind " key function menu"
|
||||
Rebinds the key \fIkey\fP to a new function named \fIfunction\fP in the
|
||||
context of menu \fImenu\fP (or in all menus where the function exists
|
||||
by using \fBall\fP).
|
||||
.TP
|
||||
.BI bind " key " """" string """" " menu"
|
||||
Makes the given \fIkey\fR produce the given \fIstring\fR in the given
|
||||
\fImenu\fR (or in all menus where the key exists when \fBall\fR is used).
|
||||
The \fIstring\fR can consist of text or commands or a mix of them.
|
||||
(To enter a command into the \fIstring\fR, precede its keystroke
|
||||
with \fBM-V\fR.)
|
||||
|
||||
.TP
|
||||
.BI unbind " key menu"
|
||||
Unbinds the key \fIkey\fP from the menu named \fImenu\fP (or from all
|
||||
menus where it exists by using \fBall\fP).
|
||||
.RE
|
||||
|
||||
.TP
|
||||
The format of \fIkey\fP should be one of:
|
||||
@@ -452,7 +471,6 @@ Starts a backward search for text in the current buffer.
|
||||
.TP
|
||||
.B searchagain
|
||||
Repeats the last search command without prompting.
|
||||
(The form 'research' is deprecated.)
|
||||
.TP
|
||||
.B findprevious
|
||||
As \fBsearchagain\fR, but always in the backward direction.
|
||||
@@ -487,7 +505,6 @@ Cuts all text from the cursor position till the end of the buffer.
|
||||
.TP
|
||||
.B curpos
|
||||
Shows the current cursor position: the line, column, and character positions.
|
||||
(The form 'cursorpos' is deprecated.)
|
||||
.TP
|
||||
.B wordcount
|
||||
Counts the number of words, lines and characters in the current buffer.
|
||||
@@ -532,10 +549,12 @@ Goes one line up (in the editor or browser).
|
||||
Goes one line down (in the editor or browser).
|
||||
.TP
|
||||
.B scrollup
|
||||
Scrolls up one line of text from the current position.
|
||||
Scrolls the viewport up one row (meaning that the text slides down)
|
||||
while keeping the cursor in the same text position, if possible.
|
||||
.TP
|
||||
.B scrolldown
|
||||
Scrolls down one line of text from the current position.
|
||||
Scrolls the viewport down one row (meaning that the text slides up)
|
||||
while keeping the cursor in the same text position, if possible.
|
||||
.TP
|
||||
.B prevword
|
||||
Moves the cursor to the beginning of the previous word.
|
||||
@@ -578,9 +597,6 @@ Goes to the last line of the file.
|
||||
Goes to a specific line (and column if specified). Negative numbers count
|
||||
from the end of the file (and end of the line).
|
||||
.TP
|
||||
.B gototext
|
||||
Switches from targeting a line number to searching for text.
|
||||
.TP
|
||||
.B findbracket
|
||||
Moves the cursor to the bracket (brace, parenthesis, etc.) that matches
|
||||
(pairs) with the one under the cursor.
|
||||
@@ -631,7 +647,6 @@ Toggles case sensitivity in searching (search/replace menus only).
|
||||
.TP
|
||||
.B regexp
|
||||
Toggles whether searching/replacing is based on literal strings or regular expressions.
|
||||
(The form 'regex' is deprecated.)
|
||||
.TP
|
||||
.B backwards
|
||||
Toggles whether searching/replacing goes forward or backward.
|
||||
@@ -644,7 +659,10 @@ Shows the next history entry in the prompt menus (e.g. search).
|
||||
.TP
|
||||
.B flipreplace
|
||||
Toggles between searching for something and replacing something.
|
||||
(The form 'dontreplace' is deprecated.)
|
||||
.TP
|
||||
.B flipgoto
|
||||
Toggles between searching for text and targeting a line number.
|
||||
(The form 'gototext' is deprecated.)
|
||||
.TP
|
||||
.B flipexecute
|
||||
Toggles between inserting a file and executing a command.
|
||||
@@ -652,7 +670,6 @@ Toggles between inserting a file and executing a command.
|
||||
.B flipnewbuffer
|
||||
Toggles between inserting into the current buffer and into a new
|
||||
empty buffer.
|
||||
(The form 'newbuffer' is deprecated.)
|
||||
.TP
|
||||
.B dosformat
|
||||
When writing a file, switches to writing a DOS format (CR/LF).
|
||||
@@ -690,8 +707,9 @@ Goes to the last file when using the file browser (reading or writing files).
|
||||
.B nohelp
|
||||
Toggles the presence of the two-line list of key bindings at the bottom of the screen.
|
||||
.TP
|
||||
.B constupdate
|
||||
.B constantshow
|
||||
Toggles the constant display of the current line, column, and character positions.
|
||||
(The form 'constupdate' is deprecated.)
|
||||
.TP
|
||||
.B morespace
|
||||
Toggles the presence of the blank line that 'separates' the title bar from the file text.
|
||||
@@ -702,6 +720,9 @@ Toggles smooth scrolling (when moving around with the arrow keys).
|
||||
.B softwrap
|
||||
Toggles the displaying of overlong lines on multiple screen lines.
|
||||
.TP
|
||||
.B linenumbers
|
||||
Toggles the display of line numbers in front of the text.
|
||||
.TP
|
||||
.B whitespacedisplay
|
||||
Toggles the showing of whitespace.
|
||||
.TP
|
||||
@@ -714,9 +735,10 @@ Toggles the smartness of the Home key.
|
||||
.B autoindent
|
||||
Toggles whether new lines will contain the same amount of whitespace as the preceding line.
|
||||
.TP
|
||||
.B cuttoend
|
||||
.B cutfromcursor
|
||||
Toggles whether cutting text will cut the whole line or just from the current cursor
|
||||
position to the end of the line.
|
||||
(The form 'cuttoend' is deprecated.)
|
||||
.TP
|
||||
.B nowrap
|
||||
Toggles whether long lines will be hard-wrapped to the next line.
|
||||
@@ -756,7 +778,6 @@ The 'search to replace' menu.
|
||||
.TP
|
||||
.B replacewith
|
||||
The 'replace with' menu, which comes up after 'search to replace'.
|
||||
(The form 'replace2' is deprecated.)
|
||||
.TP
|
||||
.B gotoline
|
||||
The 'goto line (and column)' menu.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <http://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 2.9.0" "November 2017"
|
||||
.TH RNANO 1 "version 2.9.7" "May 2018"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
## its end. For example, for the "brackets" option, ""')>]}" will match
|
||||
## ", ', ), >, ], and }.
|
||||
|
||||
## Make the 'nextword' function (Ctrl+Right) stop at word ends
|
||||
## instead of at beginnings.
|
||||
# set afterends
|
||||
|
||||
## When soft line wrapping is enabled, make it wrap lines at blanks
|
||||
## (tabs and spaces) instead of always at the edge of the screen.
|
||||
# set atblanks
|
||||
@@ -43,7 +47,6 @@
|
||||
## Constantly display the cursor position in the status bar. Note that
|
||||
## this overrides "quickblank".
|
||||
# set constantshow
|
||||
## (The old form, 'const', is deprecated.)
|
||||
|
||||
## Use cut-from-cursor-to-end-of-line by default.
|
||||
# set cutfromcursor
|
||||
@@ -57,9 +60,6 @@
|
||||
## Remember the used search/replace strings for the next session.
|
||||
# set historylog
|
||||
|
||||
## Make the justify command kill whitespace at the end of lines.
|
||||
# set justifytrim
|
||||
|
||||
## Display line numbers to the left of the text.
|
||||
# set linenumbers
|
||||
|
||||
@@ -110,7 +110,6 @@
|
||||
|
||||
## Remember the cursor position in each file for the next editing session.
|
||||
# set positionlog
|
||||
## (The old form, 'poslog', is deprecated.)
|
||||
|
||||
## Preserve the XON and XOFF keys (^Q and ^S).
|
||||
# set preserve
|
||||
@@ -175,6 +174,10 @@
|
||||
## Save automatically on exit; don't prompt.
|
||||
# set tempfile
|
||||
|
||||
## Snip whitespace at the end of lines when justifying or hard-wrapping.
|
||||
# set trimblanks
|
||||
## (The old form, 'justifytrim', is deprecated.)
|
||||
|
||||
## Disallow file modification. Why would you want this in an rcfile? ;)
|
||||
# set view
|
||||
|
||||
@@ -196,17 +199,19 @@
|
||||
# set wordchars "<_>."
|
||||
|
||||
|
||||
## Paint the interface elements of nano.
|
||||
## These are examples; by default there are no colors.
|
||||
## Paint the interface elements of nano. These are examples;
|
||||
## by default there are no colors, except for errorcolor.
|
||||
# set titlecolor brightwhite,blue
|
||||
# set statuscolor brightwhite,green
|
||||
# set errorcolor brightwhite,red
|
||||
# set selectedcolor brightwhite,magenta
|
||||
# set numbercolor cyan
|
||||
# set keycolor cyan
|
||||
# set functioncolor green
|
||||
## In root's .nanorc you might want to use:
|
||||
# set titlecolor brightwhite,red
|
||||
# set statuscolor brightwhite,red
|
||||
# set titlecolor brightwhite,magenta
|
||||
# set statuscolor brightwhite,magenta
|
||||
# set errorcolor brightwhite,red
|
||||
# set selectedcolor brightwhite,cyan
|
||||
# set numbercolor magenta
|
||||
# set keycolor brightmagenta
|
||||
|
||||
@@ -10,7 +10,7 @@ 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/v2.6/%{name}-%{version}.tar.gz
|
||||
Source : https://nano-editor.org/dist/latest/%{name}-%{version}.tar.gz
|
||||
|
||||
BuildRoot : %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires : autoconf, automake, gettext-devel, ncurses-devel, texinfo
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# List of available languages.
|
||||
bg ca cs da de eo es eu fi fr ga gl hr hu id it ja ms nb nl nn pl pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
|
||||
bg ca cs da de eo es eu fi fr ga gl hr hu id it ja ms nb nl nn pl pt pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
|
||||
|
||||
1197
po/nano.pot
1197
po/nano.pot
File diff suppressed because it is too large
Load Diff
1285
po/pt_BR.po
1285
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1901
po/zh_CN.po
1901
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1807
po/zh_TW.po
1807
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
1158
src/browser.c
1158
src/browser.c
File diff suppressed because it is too large
Load Diff
764
src/chars.c
764
src/chars.c
File diff suppressed because it is too large
Load Diff
578
src/color.c
578
src/color.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* color.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -33,7 +33,7 @@
|
||||
/* For early versions of ncurses-6.0, use an additional A_PROTECT attribute
|
||||
* for all colors, in order to work around an ncurses miscoloring bug. */
|
||||
#if defined(NCURSES_VERSION_MAJOR) && (NCURSES_VERSION_MAJOR == 6) && \
|
||||
(NCURSES_VERSION_MINOR == 0) && (NCURSES_VERSION_PATCH < 20151017)
|
||||
(NCURSES_VERSION_MINOR == 0) && (NCURSES_VERSION_PATCH < 20151017)
|
||||
#define A_BANDAID A_PROTECT
|
||||
#else
|
||||
#define A_BANDAID A_NORMAL
|
||||
@@ -43,394 +43,394 @@
|
||||
* for the colors in each syntax. */
|
||||
void set_colorpairs(void)
|
||||
{
|
||||
const syntaxtype *sint;
|
||||
bool using_defaults = FALSE;
|
||||
short foreground, background;
|
||||
size_t i;
|
||||
const syntaxtype *sint;
|
||||
bool using_defaults = FALSE;
|
||||
size_t i;
|
||||
|
||||
/* Tell ncurses to enable colors. */
|
||||
start_color();
|
||||
/* Tell ncurses to enable colors. */
|
||||
start_color();
|
||||
|
||||
#ifdef HAVE_USE_DEFAULT_COLORS
|
||||
/* Allow using the default colors, if available. */
|
||||
using_defaults = (use_default_colors() != ERR);
|
||||
/* Allow using the default colors, if available. */
|
||||
using_defaults = (use_default_colors() != ERR);
|
||||
#endif
|
||||
|
||||
/* Initialize the color pairs for nano's interface elements. */
|
||||
for (i = 0; i < NUMBER_OF_ELEMENTS; i++) {
|
||||
bool bright = FALSE;
|
||||
/* Initialize the color pairs for nano's interface elements. */
|
||||
for (i = 0; i < NUMBER_OF_ELEMENTS; i++) {
|
||||
colortype *combo = color_combo[i];
|
||||
|
||||
if (specified_color_combo[i] != NULL &&
|
||||
parse_color_names(specified_color_combo[i],
|
||||
&foreground, &background, &bright)) {
|
||||
if (foreground == -1 && !using_defaults)
|
||||
foreground = COLOR_WHITE;
|
||||
if (background == -1 && !using_defaults)
|
||||
background = COLOR_BLACK;
|
||||
init_pair(i + 1, foreground, background);
|
||||
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BANDAID |
|
||||
(bright ? A_BOLD : A_NORMAL);
|
||||
} else {
|
||||
if (i != FUNCTION_TAG)
|
||||
interface_color_pair[i] = hilite_attribute;
|
||||
else
|
||||
interface_color_pair[i] = A_NORMAL;
|
||||
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->bright ? A_BOLD : A_NORMAL);
|
||||
} else {
|
||||
if (i == FUNCTION_TAG)
|
||||
interface_color_pair[i] = A_NORMAL;
|
||||
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;
|
||||
} else
|
||||
interface_color_pair[i] = hilite_attribute;
|
||||
}
|
||||
|
||||
free(color_combo[i]);
|
||||
}
|
||||
|
||||
free(specified_color_combo[i]);
|
||||
specified_color_combo[i] = NULL;
|
||||
}
|
||||
/* For each syntax, go through its list of colors and assign each
|
||||
* its pair number, giving identical color pairs the same number. */
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
colortype *ink;
|
||||
int new_number = NUMBER_OF_ELEMENTS + 1;
|
||||
|
||||
/* For each syntax, go through its list of colors and assign each
|
||||
* its pair number, giving identical color pairs the same number. */
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
colortype *ink;
|
||||
int new_number = NUMBER_OF_ELEMENTS + 1;
|
||||
for (ink = sint->color; ink != NULL; ink = ink->next) {
|
||||
const colortype *beforenow = sint->color;
|
||||
|
||||
for (ink = sint->color; ink != NULL; ink = ink->next) {
|
||||
const colortype *beforenow = sint->color;
|
||||
while (beforenow != ink && (beforenow->fg != ink->fg ||
|
||||
beforenow->bg != ink->bg))
|
||||
beforenow = beforenow->next;
|
||||
|
||||
while (beforenow != ink && (beforenow->fg != ink->fg ||
|
||||
beforenow->bg != ink->bg ||
|
||||
beforenow->bright != ink->bright))
|
||||
beforenow = beforenow->next;
|
||||
if (beforenow != ink)
|
||||
ink->pairnum = beforenow->pairnum;
|
||||
else
|
||||
ink->pairnum = new_number++;
|
||||
|
||||
if (beforenow != ink)
|
||||
ink->pairnum = beforenow->pairnum;
|
||||
else
|
||||
ink->pairnum = new_number++;
|
||||
|
||||
ink->attributes = COLOR_PAIR(ink->pairnum) | A_BANDAID |
|
||||
(ink->bright ? A_BOLD : A_NORMAL);
|
||||
ink->attributes = COLOR_PAIR(ink->pairnum) | A_BANDAID |
|
||||
(ink->bright ? A_BOLD : A_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the color information. */
|
||||
void color_init(void)
|
||||
{
|
||||
const colortype *ink;
|
||||
bool using_defaults = FALSE;
|
||||
short foreground, background;
|
||||
const colortype *ink;
|
||||
bool using_defaults = FALSE;
|
||||
short foreground, background;
|
||||
|
||||
/* If the terminal is not capable of colors, forget it. */
|
||||
if (!has_colors())
|
||||
return;
|
||||
/* If the terminal is not capable of colors, forget it. */
|
||||
if (!has_colors())
|
||||
return;
|
||||
|
||||
#ifdef HAVE_USE_DEFAULT_COLORS
|
||||
/* Allow using the default colors, if available. */
|
||||
using_defaults = (use_default_colors() != ERR);
|
||||
/* Allow using the default colors, if available. */
|
||||
using_defaults = (use_default_colors() != ERR);
|
||||
#endif
|
||||
|
||||
/* For each coloring expression, initialize the color pair. */
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
foreground = ink->fg;
|
||||
background = ink->bg;
|
||||
/* For each coloring expression, initialize the color pair. */
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
foreground = ink->fg;
|
||||
background = ink->bg;
|
||||
|
||||
if (foreground == -1 && !using_defaults)
|
||||
foreground = COLOR_WHITE;
|
||||
if (foreground == USE_THE_DEFAULT && !using_defaults)
|
||||
foreground = COLOR_WHITE;
|
||||
|
||||
if (background == -1 && !using_defaults)
|
||||
background = COLOR_BLACK;
|
||||
if (background == USE_THE_DEFAULT && !using_defaults)
|
||||
background = COLOR_BLACK;
|
||||
|
||||
init_pair(ink->pairnum, foreground, background);
|
||||
}
|
||||
init_pair(ink->pairnum, foreground, background);
|
||||
}
|
||||
|
||||
have_palette = TRUE;
|
||||
have_palette = TRUE;
|
||||
}
|
||||
|
||||
/* Try to match the given shibboleth string with one of the regexes in
|
||||
* the list starting at head. Return TRUE upon success. */
|
||||
bool found_in_list(regexlisttype *head, const char *shibboleth)
|
||||
{
|
||||
regexlisttype *item;
|
||||
regex_t rgx;
|
||||
regexlisttype *item;
|
||||
regex_t rgx;
|
||||
|
||||
for (item = head; item != NULL; item = item->next) {
|
||||
regcomp(&rgx, fixbounds(item->full_regex), NANO_REG_EXTENDED);
|
||||
for (item = head; item != NULL; item = item->next) {
|
||||
regcomp(&rgx, fixbounds(item->full_regex), NANO_REG_EXTENDED);
|
||||
|
||||
if (regexec(&rgx, shibboleth, 0, NULL, 0) == 0) {
|
||||
regfree(&rgx);
|
||||
return TRUE;
|
||||
if (regexec(&rgx, shibboleth, 0, NULL, 0) == 0) {
|
||||
regfree(&rgx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
regfree(&rgx);
|
||||
}
|
||||
|
||||
regfree(&rgx);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update the color information based on the current filename and content. */
|
||||
void color_update(void)
|
||||
{
|
||||
syntaxtype *sint = NULL;
|
||||
colortype *ink;
|
||||
syntaxtype *sint = NULL;
|
||||
colortype *ink;
|
||||
|
||||
/* If the rcfiles were not read, or contained no syntaxes, get out. */
|
||||
if (syntaxes == NULL)
|
||||
return;
|
||||
/* If the rcfiles were not read, or contained no syntaxes, get out. */
|
||||
if (syntaxes == NULL)
|
||||
return;
|
||||
|
||||
/* If we specified a syntax-override string, use it. */
|
||||
if (syntaxstr != NULL) {
|
||||
/* An override of "none" is like having no syntax at all. */
|
||||
if (strcmp(syntaxstr, "none") == 0)
|
||||
return;
|
||||
/* If we specified a syntax-override string, use it. */
|
||||
if (syntaxstr != NULL) {
|
||||
/* An override of "none" is like having no syntax at all. */
|
||||
if (strcmp(syntaxstr, "none") == 0)
|
||||
return;
|
||||
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (strcmp(sint->name, syntaxstr) == 0)
|
||||
break;
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (strcmp(sint->name, syntaxstr) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (sint == NULL && !inhelp)
|
||||
statusline(ALERT, _("Unknown syntax name: %s"), syntaxstr);
|
||||
}
|
||||
|
||||
if (sint == NULL && !inhelp)
|
||||
statusline(ALERT, _("Unknown syntax name: %s"), syntaxstr);
|
||||
}
|
||||
/* If no syntax-override string was specified, or it didn't match,
|
||||
* try finding a syntax based on the filename (extension). */
|
||||
if (sint == NULL && !inhelp) {
|
||||
char *reserved = charalloc(PATH_MAX + 1);
|
||||
char *currentdir = getcwd(reserved, PATH_MAX + 1);
|
||||
char *joinednames = charalloc(PATH_MAX + 1);
|
||||
char *fullname = NULL;
|
||||
|
||||
/* 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) {
|
||||
char *reserved = charalloc(PATH_MAX + 1);
|
||||
char *currentdir = getcwd(reserved, PATH_MAX + 1);
|
||||
char *joinednames = charalloc(PATH_MAX + 1);
|
||||
char *fullname = NULL;
|
||||
if (currentdir == NULL)
|
||||
free(reserved);
|
||||
else {
|
||||
/* Concatenate the current working directory with the
|
||||
* specified filename, and canonicalize the result. */
|
||||
sprintf(joinednames, "%s/%s", currentdir, openfile->filename);
|
||||
fullname = get_full_path(joinednames);
|
||||
free(currentdir);
|
||||
}
|
||||
|
||||
if (currentdir == NULL)
|
||||
free(reserved);
|
||||
else {
|
||||
/* Concatenate the current working directory with the
|
||||
* specified filename, and canonicalize the result. */
|
||||
sprintf(joinednames, "%s/%s", currentdir, openfile->filename);
|
||||
fullname = get_full_path(joinednames);
|
||||
free(currentdir);
|
||||
if (fullname == NULL)
|
||||
fullname = mallocstrcpy(fullname, openfile->filename);
|
||||
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (found_in_list(sint->extensions, fullname))
|
||||
break;
|
||||
}
|
||||
|
||||
free(joinednames);
|
||||
free(fullname);
|
||||
}
|
||||
|
||||
if (fullname == NULL)
|
||||
fullname = mallocstrcpy(fullname, openfile->filename);
|
||||
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
if (found_in_list(sint->extensions, fullname))
|
||||
break;
|
||||
/* 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->fileage->data))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(joinednames);
|
||||
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->fileage->data))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBMAGIC
|
||||
/* If we still don't have an answer, try using magic. */
|
||||
if (sint == NULL && !inhelp) {
|
||||
struct stat fileinfo;
|
||||
magic_t cookie = NULL;
|
||||
const char *magicstring = NULL;
|
||||
/* If we still don't have an answer, try using magic. */
|
||||
if (sint == NULL && !inhelp) {
|
||||
struct stat fileinfo;
|
||||
magic_t cookie = NULL;
|
||||
const char *magicstring = NULL;
|
||||
|
||||
if (stat(openfile->filename, &fileinfo) == 0) {
|
||||
/* Open the magic database and get a diagnosis of the file. */
|
||||
cookie = magic_open(MAGIC_SYMLINK |
|
||||
if (stat(openfile->filename, &fileinfo) == 0) {
|
||||
/* Open the magic database and get a diagnosis of the file. */
|
||||
cookie = magic_open(MAGIC_SYMLINK |
|
||||
#ifdef DEBUG
|
||||
MAGIC_DEBUG | MAGIC_CHECK |
|
||||
MAGIC_DEBUG | MAGIC_CHECK |
|
||||
#endif
|
||||
MAGIC_ERROR);
|
||||
if (cookie == NULL || magic_load(cookie, NULL) < 0)
|
||||
statusline(ALERT, _("magic_load() failed: %s"), strerror(errno));
|
||||
else {
|
||||
magicstring = magic_file(cookie, openfile->filename);
|
||||
if (magicstring == NULL)
|
||||
statusline(ALERT, _("magic_file(%s) failed: %s"),
|
||||
openfile->filename, magic_error(cookie));
|
||||
}
|
||||
}
|
||||
MAGIC_ERROR);
|
||||
if (cookie == NULL || magic_load(cookie, NULL) < 0)
|
||||
statusline(ALERT, _("magic_load() failed: %s"), strerror(errno));
|
||||
else {
|
||||
magicstring = magic_file(cookie, openfile->filename);
|
||||
if (magicstring == NULL)
|
||||
statusline(ALERT, _("magic_file(%s) failed: %s"),
|
||||
openfile->filename, magic_error(cookie));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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))
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* 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))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stat(openfile->filename, &fileinfo) == 0)
|
||||
magic_close(cookie);
|
||||
}
|
||||
if (stat(openfile->filename, &fileinfo) == 0)
|
||||
magic_close(cookie);
|
||||
}
|
||||
#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)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
openfile->syntax = sint;
|
||||
openfile->colorstrings = (sint == NULL ? NULL : sint->color);
|
||||
|
||||
/* If a syntax was found, compile its specified regexes (which have
|
||||
* already been checked for validity when they were read in). */
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
if (ink->start == NULL) {
|
||||
ink->start = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(ink->start, fixbounds(ink->start_regex), ink->rex_flags);
|
||||
/* 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)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ink->end_regex != NULL && ink->end == NULL) {
|
||||
ink->end = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(ink->end, fixbounds(ink->end_regex), ink->rex_flags);
|
||||
openfile->syntax = sint;
|
||||
openfile->colorstrings = (sint == NULL ? NULL : sint->color);
|
||||
|
||||
/* If a syntax was found, compile its specified regexes (which have
|
||||
* already been checked for validity when they were read in). */
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
if (ink->start == NULL) {
|
||||
ink->start = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(ink->start, fixbounds(ink->start_regex), ink->rex_flags);
|
||||
}
|
||||
|
||||
if (ink->end_regex != NULL && ink->end == NULL) {
|
||||
ink->end = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(ink->end, fixbounds(ink->end_regex), ink->rex_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine whether the matches of multiline regexes are still the same,
|
||||
* and if not, schedule a screen refresh, so things will be repainted. */
|
||||
void check_the_multis(filestruct *line)
|
||||
{
|
||||
const colortype *ink;
|
||||
bool astart, anend;
|
||||
regmatch_t startmatch, endmatch;
|
||||
const colortype *ink;
|
||||
bool astart, anend;
|
||||
regmatch_t startmatch, endmatch;
|
||||
char *afterstart;
|
||||
|
||||
/* If there is no syntax or no multiline regex, there is nothing to do. */
|
||||
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0)
|
||||
return;
|
||||
/* If there is no syntax or no multiline regex, there is nothing to do. */
|
||||
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0)
|
||||
return;
|
||||
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
/* If it's not a multiline regex, skip. */
|
||||
if (ink->end == NULL)
|
||||
continue;
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
/* If it's not a multiline regex, skip. */
|
||||
if (ink->end == NULL)
|
||||
continue;
|
||||
|
||||
alloc_multidata_if_needed(line);
|
||||
alloc_multidata_if_needed(line);
|
||||
|
||||
astart = (regexec(ink->start, line->data, 1, &startmatch, 0) == 0);
|
||||
anend = (regexec(ink->end, line->data, 1, &endmatch, 0) == 0);
|
||||
astart = (regexec(ink->start, line->data, 1, &startmatch, 0) == 0);
|
||||
afterstart = line->data + (astart ? startmatch.rm_eo : 0);
|
||||
anend = (regexec(ink->end, afterstart, 1, &endmatch, 0) == 0);
|
||||
|
||||
/* Check whether the multidata still matches the current situation. */
|
||||
if (line->multidata[ink->id] == CNONE ||
|
||||
line->multidata[ink->id] == CWHOLELINE) {
|
||||
if (!astart && !anend)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CSTARTENDHERE) {
|
||||
if (astart && anend && startmatch.rm_so < endmatch.rm_so)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CBEGINBEFORE) {
|
||||
if (!astart && anend)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CENDAFTER) {
|
||||
if (astart && !anend)
|
||||
continue;
|
||||
/* Check whether the multidata still matches the current situation. */
|
||||
if (line->multidata[ink->id] == CNONE ||
|
||||
line->multidata[ink->id] == CWHOLELINE) {
|
||||
if (!astart && !anend)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CSTARTENDHERE) {
|
||||
if (astart && anend && startmatch.rm_so < endmatch.rm_so)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CBEGINBEFORE) {
|
||||
if (!astart && anend)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CENDAFTER) {
|
||||
if (astart && !anend)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* There is a mismatch, so something changed: repaint. */
|
||||
refresh_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* There is a mismatch, so something changed: repaint. */
|
||||
refresh_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate (for one line) the cache space for multiline color regexes. */
|
||||
void alloc_multidata_if_needed(filestruct *fileptr)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (fileptr->multidata == NULL) {
|
||||
fileptr->multidata = (short *)nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
if (fileptr->multidata == NULL) {
|
||||
fileptr->multidata = (short *)nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
|
||||
for (i = 0; i < openfile->syntax->nmultis; i++)
|
||||
fileptr->multidata[i] = -1;
|
||||
}
|
||||
for (i = 0; i < openfile->syntax->nmultis; i++)
|
||||
fileptr->multidata[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Precalculate the multi-line start and end regex info so we can
|
||||
* speed up rendering (with any hope at all...). */
|
||||
void precalc_multicolorinfo(void)
|
||||
{
|
||||
const colortype *ink;
|
||||
regmatch_t startmatch, endmatch;
|
||||
filestruct *line, *tailline;
|
||||
const colortype *ink;
|
||||
regmatch_t startmatch, endmatch;
|
||||
filestruct *line, *tailline;
|
||||
|
||||
if (openfile->colorstrings == NULL || ISSET(NO_COLOR_SYNTAX))
|
||||
return;
|
||||
if (openfile->colorstrings == NULL || ISSET(NO_COLOR_SYNTAX))
|
||||
return;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Precalculating the multiline color info...\n");
|
||||
fprintf(stderr, "Precalculating the multiline color info...\n");
|
||||
#endif
|
||||
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
/* If this is not a multi-line regex, skip it. */
|
||||
if (ink->end == NULL)
|
||||
continue;
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
/* If this is not a multi-line regex, skip it. */
|
||||
if (ink->end == NULL)
|
||||
continue;
|
||||
|
||||
for (line = openfile->fileage; line != NULL; line = line->next) {
|
||||
int index = 0;
|
||||
for (line = openfile->fileage; line != NULL; line = line->next) {
|
||||
int index = 0;
|
||||
|
||||
alloc_multidata_if_needed(line);
|
||||
/* Assume nothing applies until proven otherwise below. */
|
||||
line->multidata[ink->id] = CNONE;
|
||||
alloc_multidata_if_needed(line);
|
||||
/* Assume nothing applies until proven otherwise below. */
|
||||
line->multidata[ink->id] = CNONE;
|
||||
|
||||
/* For an unpaired start match, mark all remaining lines. */
|
||||
if (line->prev && line->prev->multidata[ink->id] == CWOULDBE) {
|
||||
line->multidata[ink->id] = CWOULDBE;
|
||||
continue;
|
||||
}
|
||||
/* For an unpaired start match, mark all remaining lines. */
|
||||
if (line->prev && line->prev->multidata[ink->id] == CWOULDBE) {
|
||||
line->multidata[ink->id] = CWOULDBE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* When the line contains a start match, look for an end, and if
|
||||
* found, mark all the lines that are affected. */
|
||||
while (regexec(ink->start, line->data + index, 1,
|
||||
&startmatch, (index == 0) ? 0 : REG_NOTBOL) == 0) {
|
||||
/* Begin looking for an end match after the start match. */
|
||||
index += startmatch.rm_eo;
|
||||
/* When the line contains a start match, look for an end, and if
|
||||
* found, mark all the lines that are affected. */
|
||||
while (regexec(ink->start, line->data + index, 1,
|
||||
&startmatch, (index == 0) ? 0 : REG_NOTBOL) == 0) {
|
||||
/* Begin looking for an end match after the start match. */
|
||||
index += startmatch.rm_eo;
|
||||
|
||||
/* If there is an end match on this line, mark the line, but
|
||||
* continue looking for other starts after it. */
|
||||
if (regexec(ink->end, line->data + index, 1,
|
||||
&endmatch, (index == 0) ? 0 : REG_NOTBOL) == 0) {
|
||||
line->multidata[ink->id] = CSTARTENDHERE;
|
||||
index += endmatch.rm_eo;
|
||||
/* If both start and end are mere anchors, step ahead. */
|
||||
if (startmatch.rm_so == startmatch.rm_eo &&
|
||||
endmatch.rm_so == endmatch.rm_eo) {
|
||||
/* When at end-of-line, we're done. */
|
||||
if (line->data[index] == '\0')
|
||||
break;
|
||||
index = move_mbright(line->data, index);
|
||||
}
|
||||
continue;
|
||||
/* If there is an end match on this line, mark the line, but
|
||||
* continue looking for other starts after it. */
|
||||
if (regexec(ink->end, line->data + index, 1,
|
||||
&endmatch, (index == 0) ? 0 : REG_NOTBOL) == 0) {
|
||||
line->multidata[ink->id] = CSTARTENDHERE;
|
||||
index += endmatch.rm_eo;
|
||||
/* If both start and end are mere anchors, step ahead. */
|
||||
if (startmatch.rm_so == startmatch.rm_eo &&
|
||||
endmatch.rm_so == endmatch.rm_eo) {
|
||||
/* When at end-of-line, we're done. */
|
||||
if (line->data[index] == '\0')
|
||||
break;
|
||||
index = move_mbright(line->data, index);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Look for an end match on later lines. */
|
||||
tailline = line->next;
|
||||
|
||||
while (tailline != NULL) {
|
||||
if (regexec(ink->end, tailline->data, 1, &endmatch, 0) == 0)
|
||||
break;
|
||||
tailline = tailline->next;
|
||||
}
|
||||
|
||||
if (tailline == NULL) {
|
||||
line->multidata[ink->id] = CWOULDBE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We found it, we found it, la la la la la. Mark all
|
||||
* the lines in between and the end properly. */
|
||||
line->multidata[ink->id] = CENDAFTER;
|
||||
|
||||
for (line = line->next; line != tailline; line = line->next) {
|
||||
alloc_multidata_if_needed(line);
|
||||
line->multidata[ink->id] = CWHOLELINE;
|
||||
}
|
||||
|
||||
alloc_multidata_if_needed(tailline);
|
||||
tailline->multidata[ink->id] = CBEGINBEFORE;
|
||||
|
||||
/* Begin looking for a new start after the end match. */
|
||||
index = endmatch.rm_eo;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for an end match on later lines. */
|
||||
tailline = line->next;
|
||||
|
||||
while (tailline != NULL) {
|
||||
if (regexec(ink->end, tailline->data, 1, &endmatch, 0) == 0)
|
||||
break;
|
||||
tailline = tailline->next;
|
||||
}
|
||||
|
||||
if (tailline == NULL) {
|
||||
line->multidata[ink->id] = CWOULDBE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We found it, we found it, la la la la la. Mark all
|
||||
* the lines in between and the end properly. */
|
||||
line->multidata[ink->id] = CENDAFTER;
|
||||
|
||||
for (line = line->next; line != tailline; line = line->next) {
|
||||
alloc_multidata_if_needed(line);
|
||||
line->multidata[ink->id] = CWHOLELINE;
|
||||
}
|
||||
|
||||
alloc_multidata_if_needed(tailline);
|
||||
tailline->multidata[ink->id] = CBEGINBEFORE;
|
||||
|
||||
/* Begin looking for a new start after the end match. */
|
||||
index = endmatch.rm_eo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
302
src/cut.c
302
src/cut.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* cut.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014 Mark Majeres *
|
||||
* Copyright (C) 2016 Benno Schulenberg *
|
||||
* *
|
||||
@@ -25,18 +25,18 @@
|
||||
#include <string.h>
|
||||
|
||||
static bool keep_cutbuffer = FALSE;
|
||||
/* Should we keep the contents of the cutbuffer? */
|
||||
/* Should we keep the contents of the cutbuffer? */
|
||||
|
||||
/* Indicate that we should no longer keep the contents of the cutbuffer. */
|
||||
void cutbuffer_reset(void)
|
||||
{
|
||||
keep_cutbuffer = FALSE;
|
||||
keep_cutbuffer = FALSE;
|
||||
}
|
||||
|
||||
/* Return the status of cutbuffer preservation. */
|
||||
inline bool keeping_cutbuffer(void)
|
||||
{
|
||||
return keep_cutbuffer;
|
||||
return keep_cutbuffer;
|
||||
}
|
||||
|
||||
/* If we aren't on the last line of the file, move all the text of the
|
||||
@@ -46,13 +46,13 @@ inline bool keeping_cutbuffer(void)
|
||||
* current line. */
|
||||
void cut_line(void)
|
||||
{
|
||||
if (openfile->current != openfile->filebot)
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current, 0,
|
||||
openfile->current->next, 0);
|
||||
else
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current, 0,
|
||||
openfile->current, strlen(openfile->current->data));
|
||||
openfile->placewewant = 0;
|
||||
if (openfile->current != openfile->filebot)
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current, 0,
|
||||
openfile->current->next, 0);
|
||||
else
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current, 0,
|
||||
openfile->current, strlen(openfile->current->data));
|
||||
openfile->placewewant = 0;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -60,14 +60,14 @@ void cut_line(void)
|
||||
* current place we want to where the text used to start. */
|
||||
void cut_marked(bool *right_side_up)
|
||||
{
|
||||
filestruct *top, *bot;
|
||||
size_t top_x, bot_x;
|
||||
filestruct *top, *bot;
|
||||
size_t top_x, bot_x;
|
||||
|
||||
mark_order((const filestruct **)&top, &top_x,
|
||||
(const filestruct **)&bot, &bot_x, right_side_up);
|
||||
mark_order((const filestruct **)&top, &top_x,
|
||||
(const filestruct **)&bot, &bot_x, right_side_up);
|
||||
|
||||
extract_buffer(&cutbuffer, &cutbottom, top, top_x, bot, bot_x);
|
||||
openfile->placewewant = xplustabs();
|
||||
extract_buffer(&cutbuffer, &cutbottom, top, top_x, bot, bot_x);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
/* If we aren't at the end of the current line, move all the text from
|
||||
@@ -78,32 +78,32 @@ void cut_marked(bool *right_side_up)
|
||||
* newline used to be. */
|
||||
void cut_to_eol(void)
|
||||
{
|
||||
size_t data_len = strlen(openfile->current->data);
|
||||
size_t data_len = strlen(openfile->current->data);
|
||||
|
||||
if (openfile->current_x < data_len)
|
||||
/* If we're not at the end of the line, move all the text from
|
||||
* the current position up to it, not counting the newline at
|
||||
* the end, into the cutbuffer. */
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->current, data_len);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
/* If we're at the end of the line, and it isn't the last line
|
||||
* of the file, move all the text from the current position up
|
||||
* to the beginning of the next line, i.e. the newline at the
|
||||
* end, into the cutbuffer. */
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->current->next, 0);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
if (openfile->current_x < data_len)
|
||||
/* If we're not at the end of the line, move all the text from
|
||||
* the current position up to it, not counting the newline at
|
||||
* the end, into the cutbuffer. */
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->current, data_len);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
/* If we're at the end of the line, and it isn't the last line
|
||||
* of the file, move all the text from the current position up
|
||||
* to the beginning of the next line, i.e. the newline at the
|
||||
* end, into the cutbuffer. */
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->current->next, 0);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
}
|
||||
|
||||
/* Move all the text from the current cursor position to the end of the
|
||||
* file into the cutbuffer. */
|
||||
void cut_to_eof(void)
|
||||
{
|
||||
extract_buffer(&cutbuffer, &cutbottom,
|
||||
openfile->current, openfile->current_x,
|
||||
openfile->filebot, strlen(openfile->filebot->data));
|
||||
extract_buffer(&cutbuffer, &cutbottom,
|
||||
openfile->current, openfile->current_x,
|
||||
openfile->filebot, strlen(openfile->filebot->data));
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
@@ -114,86 +114,82 @@ void cut_to_eof(void)
|
||||
void do_cut_text(bool copy_text, bool cut_till_eof)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
filestruct *cb_save = NULL;
|
||||
/* The current end of the cutbuffer, before we add text to it. */
|
||||
size_t cb_save_len = 0;
|
||||
/* The length of the string at the current end of the cutbuffer,
|
||||
* before we add text to it. */
|
||||
bool old_no_newlines = ISSET(NO_NEWLINES);
|
||||
bool right_side_up = TRUE;
|
||||
/* There *is* no region, *or* it is marked forward. */
|
||||
filestruct *cb_save = NULL;
|
||||
/* The current end of the cutbuffer, before we add text to it. */
|
||||
size_t cb_save_len = 0;
|
||||
/* The length of the string at the current end of the cutbuffer,
|
||||
* before we add text to it. */
|
||||
bool old_no_newlines = ISSET(NO_NEWLINES);
|
||||
bool right_side_up = TRUE;
|
||||
/* There *is* no region, *or* it is marked forward. */
|
||||
#endif
|
||||
size_t was_totsize = openfile->totsize;
|
||||
size_t was_totsize = openfile->totsize;
|
||||
|
||||
/* If a chain of cuts was broken, empty the cutbuffer. */
|
||||
if (!keep_cutbuffer) {
|
||||
free_filestruct(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
/* Indicate that future cuts should add to the cutbuffer. */
|
||||
keep_cutbuffer = TRUE;
|
||||
}
|
||||
/* If a chain of cuts was broken, empty the cutbuffer. */
|
||||
if (!keep_cutbuffer) {
|
||||
free_filestruct(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
/* Indicate that future cuts should add to the cutbuffer. */
|
||||
keep_cutbuffer = TRUE;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (copy_text) {
|
||||
/* If the cutbuffer isn't empty, remember where it currently ends. */
|
||||
if (cutbuffer != NULL) {
|
||||
cb_save = cutbottom;
|
||||
cb_save_len = strlen(cutbottom->data);
|
||||
if (copy_text) {
|
||||
/* If the cutbuffer isn't empty, remember where it currently ends. */
|
||||
if (cutbuffer != NULL) {
|
||||
cb_save = cutbottom;
|
||||
cb_save_len = strlen(cutbottom->data);
|
||||
}
|
||||
/* Don't add a magicline when moving text to the cutbuffer. */
|
||||
SET(NO_NEWLINES);
|
||||
}
|
||||
/* Don't add a magicline when moving text to the cutbuffer. */
|
||||
SET(NO_NEWLINES);
|
||||
}
|
||||
|
||||
if (cut_till_eof) {
|
||||
/* Move all text up to the end of the file into the cutbuffer. */
|
||||
cut_to_eof();
|
||||
} else if (openfile->mark_set) {
|
||||
/* Move the marked text to the cutbuffer, and turn the mark off. */
|
||||
cut_marked(&right_side_up);
|
||||
openfile->mark_set = FALSE;
|
||||
} else if (ISSET(CUT_FROM_CURSOR))
|
||||
/* Move all text up to the end of the line into the cutbuffer. */
|
||||
cut_to_eol();
|
||||
else
|
||||
if (cut_till_eof) {
|
||||
/* Move all text up to the end of the file into the cutbuffer. */
|
||||
cut_to_eof();
|
||||
} else if (openfile->mark) {
|
||||
/* Move the marked text to the cutbuffer, and turn the mark off. */
|
||||
cut_marked(&right_side_up);
|
||||
openfile->mark = NULL;
|
||||
} else if (ISSET(CUT_FROM_CURSOR))
|
||||
/* Move all text up to the end of the line into the cutbuffer. */
|
||||
cut_to_eol();
|
||||
else
|
||||
#endif
|
||||
/* Move the entire line into the cutbuffer. */
|
||||
cut_line();
|
||||
/* Move the entire line into the cutbuffer. */
|
||||
cut_line();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (copy_text) {
|
||||
/* Copy the text that is in the cutbuffer (starting at its saved end,
|
||||
* if there is one) back into the current buffer. This effectively
|
||||
* uncuts the text we just cut. */
|
||||
if (cutbuffer != NULL) {
|
||||
if (cb_save != NULL) {
|
||||
cb_save->data += cb_save_len;
|
||||
copy_from_buffer(cb_save);
|
||||
cb_save->data -= cb_save_len;
|
||||
} else
|
||||
copy_from_buffer(cutbuffer);
|
||||
if (copy_text) {
|
||||
/* Copy the text that is in the cutbuffer (starting at its saved end,
|
||||
* if there is one) back into the current buffer. This effectively
|
||||
* uncuts the text we just cut. */
|
||||
if (cutbuffer != NULL) {
|
||||
if (cb_save != NULL) {
|
||||
cb_save->data += cb_save_len;
|
||||
copy_from_buffer(cb_save);
|
||||
cb_save->data -= cb_save_len;
|
||||
} else
|
||||
copy_from_buffer(cutbuffer);
|
||||
|
||||
/* If the copied region was marked forward, put the new desired
|
||||
* x position at its end; otherwise, leave it at its beginning. */
|
||||
if (right_side_up)
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
/* Restore the magicline behavior now that we're done fiddling. */
|
||||
if (!old_no_newlines)
|
||||
UNSET(NO_NEWLINES);
|
||||
} else
|
||||
/* If the copied region was marked forward, put the new desired
|
||||
* x position at its end; otherwise, leave it at its beginning. */
|
||||
if (right_side_up)
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
/* Restore the magicline behavior now that we're done fiddling. */
|
||||
if (!old_no_newlines)
|
||||
UNSET(NO_NEWLINES);
|
||||
} else
|
||||
#endif /* !NANO_TINY */
|
||||
/* Only set the modification flag if actually something was cut. */
|
||||
if (openfile->totsize != was_totsize)
|
||||
set_modified();
|
||||
/* Only set the modification flag if actually something was cut. */
|
||||
if (openfile->totsize != was_totsize)
|
||||
set_modified();
|
||||
|
||||
refresh_needed = TRUE;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
check_the_multis(openfile->current);
|
||||
#endif
|
||||
refresh_needed = TRUE;
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_filestruct(cutbuffer);
|
||||
dump_filestruct(cutbuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -201,11 +197,11 @@ void do_cut_text(bool copy_text, bool cut_till_eof)
|
||||
void do_cut_text_void(void)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
add_undo(CUT);
|
||||
add_undo(CUT);
|
||||
#endif
|
||||
do_cut_text(FALSE, FALSE);
|
||||
do_cut_text(FALSE, FALSE);
|
||||
#ifndef NANO_TINY
|
||||
update_undo(CUT);
|
||||
update_undo(CUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -215,85 +211,75 @@ void do_cut_text_void(void)
|
||||
* was moved, blow away previous contents of the cutbuffer. */
|
||||
void do_copy_text(void)
|
||||
{
|
||||
static struct filestruct *next_contiguous_line = NULL;
|
||||
bool mark_set = openfile->mark_set;
|
||||
static struct filestruct *next_contiguous_line = NULL;
|
||||
bool mark_is_set = (openfile->mark != NULL);
|
||||
|
||||
/* Remember the current viewport and cursor position. */
|
||||
ssize_t is_edittop_lineno = openfile->edittop->lineno;
|
||||
size_t is_firstcolumn = openfile->firstcolumn;
|
||||
ssize_t is_current_lineno = openfile->current->lineno;
|
||||
size_t is_current_x = openfile->current_x;
|
||||
/* Remember the current viewport and cursor position. */
|
||||
ssize_t is_edittop_lineno = openfile->edittop->lineno;
|
||||
size_t is_firstcolumn = openfile->firstcolumn;
|
||||
ssize_t is_current_lineno = openfile->current->lineno;
|
||||
size_t is_current_x = openfile->current_x;
|
||||
|
||||
if (mark_set || openfile->current != next_contiguous_line)
|
||||
cutbuffer_reset();
|
||||
if (mark_is_set || openfile->current != next_contiguous_line)
|
||||
cutbuffer_reset();
|
||||
|
||||
do_cut_text(TRUE, FALSE);
|
||||
do_cut_text(TRUE, FALSE);
|
||||
|
||||
/* If the mark was set, blow away the cutbuffer on the next copy. */
|
||||
next_contiguous_line = (mark_set ? NULL : openfile->current);
|
||||
/* If the mark was set, blow away the cutbuffer on the next copy. */
|
||||
next_contiguous_line = (mark_is_set ? NULL : openfile->current);
|
||||
|
||||
if (mark_set) {
|
||||
/* Restore the viewport and cursor position. */
|
||||
openfile->edittop = fsfromline(is_edittop_lineno);
|
||||
openfile->firstcolumn = is_firstcolumn;
|
||||
openfile->current = fsfromline(is_current_lineno);
|
||||
openfile->current_x = is_current_x;
|
||||
}
|
||||
/* If the mark was set, restore the viewport and cursor position. */
|
||||
if (mark_is_set) {
|
||||
openfile->edittop = fsfromline(is_edittop_lineno);
|
||||
openfile->firstcolumn = is_firstcolumn;
|
||||
openfile->current = fsfromline(is_current_lineno);
|
||||
openfile->current_x = is_current_x;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cut from the current cursor position to the end of the file. */
|
||||
void do_cut_till_eof(void)
|
||||
{
|
||||
add_undo(CUT_TO_EOF);
|
||||
do_cut_text(FALSE, TRUE);
|
||||
update_undo(CUT_TO_EOF);
|
||||
add_undo(CUT_TO_EOF);
|
||||
do_cut_text(FALSE, TRUE);
|
||||
update_undo(CUT_TO_EOF);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Copy text from the cutbuffer into the current buffer. */
|
||||
void do_uncut_text(void)
|
||||
{
|
||||
ssize_t was_lineno = openfile->current->lineno;
|
||||
/* The line number where we started the paste. */
|
||||
size_t was_leftedge = 0;
|
||||
/* The leftedge where we started the paste. */
|
||||
ssize_t was_lineno = openfile->current->lineno;
|
||||
/* The line number where we started the paste. */
|
||||
size_t was_leftedge = 0;
|
||||
/* The leftedge where we started the paste. */
|
||||
|
||||
/* If the cutbuffer is empty, there is nothing to do. */
|
||||
if (cutbuffer == NULL)
|
||||
return;
|
||||
/* If the cutbuffer is empty, there is nothing to do. */
|
||||
if (cutbuffer == NULL)
|
||||
return;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(PASTE);
|
||||
add_undo(PASTE);
|
||||
|
||||
if (ISSET(SOFTWRAP))
|
||||
was_leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
if (ISSET(SOFTWRAP))
|
||||
was_leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
#endif
|
||||
|
||||
/* Add a copy of the text in the cutbuffer to the current buffer
|
||||
* at the current cursor position. */
|
||||
copy_from_buffer(cutbuffer);
|
||||
/* Add a copy of the text in the cutbuffer to the current buffer
|
||||
* at the current cursor position. */
|
||||
copy_from_buffer(cutbuffer);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(PASTE);
|
||||
update_undo(PASTE);
|
||||
#endif
|
||||
|
||||
/* If we pasted less than a screenful, don't center the cursor. */
|
||||
if (less_than_a_screenful(was_lineno, was_leftedge))
|
||||
focusing = FALSE;
|
||||
/* If we pasted less than a screenful, don't center the cursor. */
|
||||
if (less_than_a_screenful(was_lineno, was_leftedge))
|
||||
focusing = FALSE;
|
||||
|
||||
/* Set the desired x position to where the pasted text ends. */
|
||||
openfile->placewewant = xplustabs();
|
||||
/* Set the desired x position to where the pasted text ends. */
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* Mark the file as modified. */
|
||||
set_modified();
|
||||
|
||||
refresh_needed = TRUE;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
check_the_multis(openfile->current);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_filestruct_reverse();
|
||||
#endif
|
||||
set_modified();
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
3824
src/files.c
3824
src/files.c
File diff suppressed because it is too large
Load Diff
2494
src/global.c
2494
src/global.c
File diff suppressed because it is too large
Load Diff
953
src/help.c
953
src/help.c
File diff suppressed because it is too large
Load Diff
796
src/history.c
796
src/history.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* history.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2003-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2003-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -26,10 +26,6 @@
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
|
||||
#ifndef XDG_DATA_FALLBACK
|
||||
#define XDG_DATA_FALLBACK "/.local/share"
|
||||
#endif
|
||||
|
||||
#ifndef SEARCH_HISTORY
|
||||
#define SEARCH_HISTORY "search_history"
|
||||
#endif
|
||||
@@ -39,146 +35,146 @@
|
||||
#endif
|
||||
|
||||
static bool history_changed = FALSE;
|
||||
/* Whether any of the history lists has changed. */
|
||||
/* Whether any of the history lists has changed. */
|
||||
static struct stat stat_of_positions_file;
|
||||
/* The last-obtained stat information of the positions file. */
|
||||
/* The last-obtained stat information of the positions file. */
|
||||
static char *poshistname = NULL;
|
||||
/* The name of the positions-history file. */
|
||||
/* The name of the positions-history file. */
|
||||
|
||||
/* Initialize the lists of historical search and replace strings
|
||||
* and the list of historical executed commands. */
|
||||
void history_init(void)
|
||||
{
|
||||
search_history = make_new_node(NULL);
|
||||
search_history->data = mallocstrcpy(NULL, "");
|
||||
searchtop = search_history;
|
||||
searchbot = search_history;
|
||||
search_history = make_new_node(NULL);
|
||||
search_history->data = mallocstrcpy(NULL, "");
|
||||
searchtop = search_history;
|
||||
searchbot = search_history;
|
||||
|
||||
replace_history = make_new_node(NULL);
|
||||
replace_history->data = mallocstrcpy(NULL, "");
|
||||
replacetop = replace_history;
|
||||
replacebot = replace_history;
|
||||
replace_history = make_new_node(NULL);
|
||||
replace_history->data = mallocstrcpy(NULL, "");
|
||||
replacetop = replace_history;
|
||||
replacebot = replace_history;
|
||||
|
||||
execute_history = make_new_node(NULL);
|
||||
execute_history->data = mallocstrcpy(NULL, "");
|
||||
executetop = execute_history;
|
||||
executebot = execute_history;
|
||||
execute_history = make_new_node(NULL);
|
||||
execute_history->data = mallocstrcpy(NULL, "");
|
||||
executetop = execute_history;
|
||||
executebot = execute_history;
|
||||
}
|
||||
|
||||
/* Set the current position in the given history list to the bottom. */
|
||||
void history_reset(const filestruct *list)
|
||||
{
|
||||
if (list == search_history)
|
||||
search_history = searchbot;
|
||||
else if (list == replace_history)
|
||||
replace_history = replacebot;
|
||||
else if (list == execute_history)
|
||||
execute_history = executebot;
|
||||
if (list == search_history)
|
||||
search_history = searchbot;
|
||||
else if (list == replace_history)
|
||||
replace_history = replacebot;
|
||||
else if (list == execute_history)
|
||||
execute_history = executebot;
|
||||
}
|
||||
|
||||
/* Return from the history list that starts at start and ends at end
|
||||
* the first node that contains the first len characters of the given
|
||||
* text, or NULL if there is no such node. */
|
||||
filestruct *find_history(const filestruct *start, const filestruct *end,
|
||||
const char *text, size_t len)
|
||||
const char *text, size_t len)
|
||||
{
|
||||
const filestruct *item;
|
||||
const filestruct *item;
|
||||
|
||||
for (item = start; item != end->prev && item != NULL; item = item->prev) {
|
||||
if (strncmp(item->data, text, len) == 0)
|
||||
return (filestruct *)item;
|
||||
}
|
||||
for (item = start; item != end->prev && item != NULL; item = item->prev) {
|
||||
if (strncmp(item->data, text, len) == 0)
|
||||
return (filestruct *)item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Update a history list (the one in which item is the current position)
|
||||
* with a fresh string text. That is: add text, or move it to the end. */
|
||||
void update_history(filestruct **item, const char *text)
|
||||
{
|
||||
filestruct **htop = NULL, **hbot = NULL, *thesame;
|
||||
filestruct **htop = NULL, **hbot = NULL, *thesame;
|
||||
|
||||
if (*item == search_history) {
|
||||
htop = &searchtop;
|
||||
hbot = &searchbot;
|
||||
} else if (*item == replace_history) {
|
||||
htop = &replacetop;
|
||||
hbot = &replacebot;
|
||||
} else if (*item == execute_history) {
|
||||
htop = &executetop;
|
||||
hbot = &executebot;
|
||||
}
|
||||
if (*item == search_history) {
|
||||
htop = &searchtop;
|
||||
hbot = &searchbot;
|
||||
} else if (*item == replace_history) {
|
||||
htop = &replacetop;
|
||||
hbot = &replacebot;
|
||||
} else if (*item == execute_history) {
|
||||
htop = &executetop;
|
||||
hbot = &executebot;
|
||||
}
|
||||
|
||||
/* See if the string is already in the history. */
|
||||
thesame = find_history(*hbot, *htop, text, HIGHEST_POSITIVE);
|
||||
/* See if the string is already in the history. */
|
||||
thesame = find_history(*hbot, *htop, text, HIGHEST_POSITIVE);
|
||||
|
||||
/* If an identical string was found, delete that item. */
|
||||
if (thesame != NULL) {
|
||||
filestruct *after = thesame->next;
|
||||
/* If an identical string was found, delete that item. */
|
||||
if (thesame != NULL) {
|
||||
filestruct *after = thesame->next;
|
||||
|
||||
/* If the string is at the head of the list, move the head. */
|
||||
if (thesame == *htop)
|
||||
*htop = after;
|
||||
/* If the string is at the head of the list, move the head. */
|
||||
if (thesame == *htop)
|
||||
*htop = after;
|
||||
|
||||
unlink_node(thesame);
|
||||
renumber(after);
|
||||
}
|
||||
unlink_node(thesame);
|
||||
renumber(after);
|
||||
}
|
||||
|
||||
/* If the history is full, delete the oldest item (the one at the
|
||||
* head of the list), to make room for a new item at the end. */
|
||||
if ((*hbot)->lineno == MAX_SEARCH_HISTORY + 1) {
|
||||
filestruct *oldest = *htop;
|
||||
/* If the history is full, delete the oldest item (the one at the
|
||||
* head of the list), to make room for a new item at the end. */
|
||||
if ((*hbot)->lineno == MAX_SEARCH_HISTORY + 1) {
|
||||
filestruct *oldest = *htop;
|
||||
|
||||
*htop = (*htop)->next;
|
||||
unlink_node(oldest);
|
||||
renumber(*htop);
|
||||
}
|
||||
*htop = (*htop)->next;
|
||||
unlink_node(oldest);
|
||||
renumber(*htop);
|
||||
}
|
||||
|
||||
/* Store the fresh string in the last item, then create a new item. */
|
||||
(*hbot)->data = mallocstrcpy((*hbot)->data, text);
|
||||
splice_node(*hbot, make_new_node(*hbot));
|
||||
*hbot = (*hbot)->next;
|
||||
(*hbot)->data = mallocstrcpy(NULL, "");
|
||||
/* Store the fresh string in the last item, then create a new item. */
|
||||
(*hbot)->data = mallocstrcpy((*hbot)->data, text);
|
||||
splice_node(*hbot, make_new_node(*hbot));
|
||||
*hbot = (*hbot)->next;
|
||||
(*hbot)->data = mallocstrcpy(NULL, "");
|
||||
|
||||
/* Indicate that the history needs to be saved on exit. */
|
||||
history_changed = TRUE;
|
||||
/* Indicate that the history needs to be saved on exit. */
|
||||
history_changed = TRUE;
|
||||
|
||||
/* Set the current position in the list to the bottom. */
|
||||
*item = *hbot;
|
||||
/* Set the current position in the list to the bottom. */
|
||||
*item = *hbot;
|
||||
}
|
||||
|
||||
/* Move h to the string in the history list just before it, and return
|
||||
* that string. If there isn't one, don't move h and return NULL. */
|
||||
char *get_history_older(filestruct **h)
|
||||
{
|
||||
if ((*h)->prev == NULL)
|
||||
return NULL;
|
||||
if ((*h)->prev == NULL)
|
||||
return NULL;
|
||||
|
||||
*h = (*h)->prev;
|
||||
*h = (*h)->prev;
|
||||
|
||||
return (*h)->data;
|
||||
return (*h)->data;
|
||||
}
|
||||
|
||||
/* Move h to the string in the history list just after it, and return
|
||||
* that string. If there isn't one, don't move h and return NULL. */
|
||||
char *get_history_newer(filestruct **h)
|
||||
{
|
||||
if ((*h)->next == NULL)
|
||||
return NULL;
|
||||
if ((*h)->next == NULL)
|
||||
return NULL;
|
||||
|
||||
*h = (*h)->next;
|
||||
*h = (*h)->next;
|
||||
|
||||
return (*h)->data;
|
||||
return (*h)->data;
|
||||
}
|
||||
|
||||
/* More placeholders. */
|
||||
void get_history_newer_void(void)
|
||||
{
|
||||
;
|
||||
;
|
||||
}
|
||||
void get_history_older_void(void)
|
||||
{
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_TABCOMP
|
||||
@@ -188,400 +184,408 @@ void get_history_older_void(void)
|
||||
* s. */
|
||||
char *get_history_completion(filestruct **h, char *s, size_t len)
|
||||
{
|
||||
if (len > 0) {
|
||||
filestruct *htop = NULL, *hbot = NULL, *p;
|
||||
if (len > 0) {
|
||||
filestruct *htop = NULL, *hbot = NULL, *p;
|
||||
|
||||
if (*h == search_history) {
|
||||
htop = searchtop;
|
||||
hbot = searchbot;
|
||||
} else if (*h == replace_history) {
|
||||
htop = replacetop;
|
||||
hbot = replacebot;
|
||||
} else if (*h == execute_history) {
|
||||
htop = executetop;
|
||||
hbot = executebot;
|
||||
if (*h == search_history) {
|
||||
htop = searchtop;
|
||||
hbot = searchbot;
|
||||
} else if (*h == replace_history) {
|
||||
htop = replacetop;
|
||||
hbot = replacebot;
|
||||
} else if (*h == execute_history) {
|
||||
htop = executetop;
|
||||
hbot = executebot;
|
||||
}
|
||||
|
||||
/* Search the history list from the current position to the top
|
||||
* for a match of len characters. Skip over an exact match. */
|
||||
p = find_history((*h)->prev, htop, s, len);
|
||||
|
||||
while (p != NULL && strcmp(p->data, s) == 0)
|
||||
p = find_history(p->prev, htop, s, len);
|
||||
|
||||
if (p != NULL) {
|
||||
*h = p;
|
||||
return mallocstrcpy(s, (*h)->data);
|
||||
}
|
||||
|
||||
/* Search the history list from the bottom to the current position
|
||||
* for a match of len characters. Skip over an exact match. */
|
||||
p = find_history(hbot, *h, s, len);
|
||||
|
||||
while (p != NULL && strcmp(p->data, s) == 0)
|
||||
p = find_history(p->prev, *h, s, len);
|
||||
|
||||
if (p != NULL) {
|
||||
*h = p;
|
||||
return mallocstrcpy(s, (*h)->data);
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the history list from the current position to the top
|
||||
* for a match of len characters. Skip over an exact match. */
|
||||
p = find_history((*h)->prev, htop, s, len);
|
||||
|
||||
while (p != NULL && strcmp(p->data, s) == 0)
|
||||
p = find_history(p->prev, htop, s, len);
|
||||
|
||||
if (p != NULL) {
|
||||
*h = p;
|
||||
return mallocstrcpy(s, (*h)->data);
|
||||
}
|
||||
|
||||
/* Search the history list from the bottom to the current position
|
||||
* for a match of len characters. Skip over an exact match. */
|
||||
p = find_history(hbot, *h, s, len);
|
||||
|
||||
while (p != NULL && strcmp(p->data, s) == 0)
|
||||
p = find_history(p->prev, *h, s, len);
|
||||
|
||||
if (p != NULL) {
|
||||
*h = p;
|
||||
return mallocstrcpy(s, (*h)->data);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're here, we didn't find a match, we didn't find an inexact
|
||||
* match, or len is 0. Return s. */
|
||||
return (char *)s;
|
||||
/* If we're here, we didn't find a match, we didn't find an inexact
|
||||
* match, or len is 0. Return s. */
|
||||
return (char *)s;
|
||||
}
|
||||
#endif /* ENSABLE_TABCOMP */
|
||||
#endif /* ENABLE_TABCOMP */
|
||||
|
||||
void history_error(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, _(msg), ap);
|
||||
va_end(ap);
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, _(msg), ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr, _("\nPress Enter to continue\n"));
|
||||
while (getchar() != '\n')
|
||||
;
|
||||
fprintf(stderr, _("\nPress Enter to continue\n"));
|
||||
while (getchar() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
/* Check whether we have or could make a directory for history files. */
|
||||
bool have_statedir(void)
|
||||
{
|
||||
struct stat dirstat;
|
||||
const char *xdgdatadir;
|
||||
struct stat dirstat;
|
||||
const char *xdgdatadir;
|
||||
|
||||
get_homedir();
|
||||
get_homedir();
|
||||
|
||||
if (homedir != NULL) {
|
||||
statedir = concatenate(homedir, "/.nano/");
|
||||
if (homedir != NULL) {
|
||||
statedir = concatenate(homedir, "/.nano/");
|
||||
|
||||
if (stat(statedir, &dirstat) == 0 && S_ISDIR(dirstat.st_mode)) {
|
||||
poshistname = concatenate(statedir, POSITION_HISTORY);
|
||||
return TRUE;
|
||||
if (stat(statedir, &dirstat) == 0 && S_ISDIR(dirstat.st_mode)) {
|
||||
poshistname = concatenate(statedir, POSITION_HISTORY);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(statedir);
|
||||
xdgdatadir = getenv("XDG_DATA_HOME");
|
||||
free(statedir);
|
||||
xdgdatadir = getenv("XDG_DATA_HOME");
|
||||
|
||||
if (homedir == NULL && xdgdatadir == NULL)
|
||||
return FALSE;
|
||||
if (homedir == NULL && xdgdatadir == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (xdgdatadir != NULL)
|
||||
statedir = concatenate(xdgdatadir, "/nano/");
|
||||
else
|
||||
statedir = concatenate(homedir, XDG_DATA_FALLBACK "/nano/");
|
||||
if (xdgdatadir != NULL)
|
||||
statedir = concatenate(xdgdatadir, "/nano/");
|
||||
else
|
||||
statedir = concatenate(homedir, "/.local/share/nano/");
|
||||
|
||||
if (stat(statedir, &dirstat) == -1) {
|
||||
if (mkdir(statedir, S_IRWXU | S_IRWXG | S_IRWXO) == -1) {
|
||||
history_error(N_("Unable to create directory %s: %s\n"
|
||||
"It is required for saving/loading "
|
||||
"search history or cursor positions.\n"),
|
||||
statedir, strerror(errno));
|
||||
return FALSE;
|
||||
if (stat(statedir, &dirstat) == -1) {
|
||||
if (xdgdatadir == NULL) {
|
||||
char *statepath = concatenate(homedir, "/.local");
|
||||
mkdir(statepath, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
free(statepath);
|
||||
statepath = concatenate(homedir, "/.local/share");
|
||||
mkdir(statepath, S_IRWXU);
|
||||
free(statepath);
|
||||
}
|
||||
if (mkdir(statedir, S_IRWXU) == -1) {
|
||||
history_error(N_("Unable to create directory %s: %s\n"
|
||||
"It is required for saving/loading "
|
||||
"search history or cursor positions.\n"),
|
||||
statedir, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
} else if (!S_ISDIR(dirstat.st_mode)) {
|
||||
history_error(N_("Path %s is not a directory and needs to be.\n"
|
||||
"Nano will be unable to load or save "
|
||||
"search history or cursor positions.\n"),
|
||||
statedir);
|
||||
return FALSE;
|
||||
}
|
||||
} else if (!S_ISDIR(dirstat.st_mode)) {
|
||||
history_error(N_("Path %s is not a directory and needs to be.\n"
|
||||
"Nano will be unable to load or save "
|
||||
"search history or cursor positions.\n"),
|
||||
statedir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
poshistname = concatenate(statedir, POSITION_HISTORY);
|
||||
return TRUE;
|
||||
poshistname = concatenate(statedir, POSITION_HISTORY);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Load the histories for Search and Replace and Execute Command. */
|
||||
void load_history(void)
|
||||
{
|
||||
char *histname = concatenate(statedir, SEARCH_HISTORY);
|
||||
FILE *hisfile = fopen(histname, "rb");
|
||||
char *histname = concatenate(statedir, SEARCH_HISTORY);
|
||||
FILE *hisfile = fopen(histname, "rb");
|
||||
|
||||
if (hisfile == NULL) {
|
||||
if (errno != ENOENT) {
|
||||
/* When reading failed, don't save history when we quit. */
|
||||
UNSET(HISTORYLOG);
|
||||
history_error(N_("Error reading %s: %s"), histname,
|
||||
strerror(errno));
|
||||
}
|
||||
} else {
|
||||
/* Load the three history lists -- first search, then replace,
|
||||
* then execute -- from oldest entry to newest. Between two
|
||||
* lists there is an empty line. */
|
||||
filestruct **history = &search_history;
|
||||
char *line = NULL;
|
||||
size_t buf_len = 0;
|
||||
ssize_t read;
|
||||
if (hisfile == NULL) {
|
||||
if (errno != ENOENT) {
|
||||
/* When reading failed, don't save history when we quit. */
|
||||
UNSET(HISTORYLOG);
|
||||
history_error(N_("Error reading %s: %s"), histname,
|
||||
strerror(errno));
|
||||
}
|
||||
} else {
|
||||
/* Load the three history lists -- first search, then replace,
|
||||
* then execute -- from oldest entry to newest. Between two
|
||||
* lists there is an empty line. */
|
||||
filestruct **history = &search_history;
|
||||
char *line = NULL;
|
||||
size_t buf_len = 0;
|
||||
ssize_t read;
|
||||
|
||||
while ((read = getline(&line, &buf_len, hisfile)) > 0) {
|
||||
line[--read] = '\0';
|
||||
if (read > 0) {
|
||||
/* Encode any embedded NUL as 0x0A. */
|
||||
unsunder(line, read);
|
||||
update_history(history, line);
|
||||
} else if (history == &search_history)
|
||||
history = &replace_history;
|
||||
else
|
||||
history = &execute_history;
|
||||
while ((read = getline(&line, &buf_len, hisfile)) > 0) {
|
||||
line[--read] = '\0';
|
||||
if (read > 0) {
|
||||
/* Encode any embedded NUL as 0x0A. */
|
||||
unsunder(line, read);
|
||||
update_history(history, line);
|
||||
} else if (history == &search_history)
|
||||
history = &replace_history;
|
||||
else
|
||||
history = &execute_history;
|
||||
}
|
||||
|
||||
fclose(hisfile);
|
||||
free(line);
|
||||
}
|
||||
|
||||
fclose(hisfile);
|
||||
free(line);
|
||||
}
|
||||
/* After reading them in, set the status of the lists to "unchanged". */
|
||||
history_changed = FALSE;
|
||||
|
||||
/* After reading them in, set the status of the lists to "unchanged". */
|
||||
history_changed = FALSE;
|
||||
|
||||
free(histname);
|
||||
free(histname);
|
||||
}
|
||||
|
||||
/* Write the lines of a history list, starting at head, from oldest to newest,
|
||||
* to the given file. Return TRUE if writing succeeded, and FALSE otherwise. */
|
||||
bool write_list(const filestruct *head, FILE *hisfile)
|
||||
{
|
||||
const filestruct *item;
|
||||
const filestruct *item;
|
||||
|
||||
for (item = head; item != NULL; item = item->next) {
|
||||
size_t length = strlen(item->data);
|
||||
for (item = head; item != NULL; item = item->next) {
|
||||
size_t length = strlen(item->data);
|
||||
|
||||
/* Decode 0x0A bytes as embedded NULs. */
|
||||
sunder(item->data);
|
||||
/* Decode 0x0A bytes as embedded NULs. */
|
||||
sunder(item->data);
|
||||
|
||||
if (fwrite(item->data, sizeof(char), length, hisfile) < length)
|
||||
return FALSE;
|
||||
if (putc('\n', hisfile) == EOF)
|
||||
return FALSE;
|
||||
}
|
||||
if (fwrite(item->data, sizeof(char), length, hisfile) < length)
|
||||
return FALSE;
|
||||
if (putc('\n', hisfile) == EOF)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Save the histories for Search and Replace and Execute Command. */
|
||||
void save_history(void)
|
||||
{
|
||||
char *histname;
|
||||
FILE *hisfile;
|
||||
char *histname;
|
||||
FILE *hisfile;
|
||||
|
||||
/* If the histories are unchanged, don't bother saving them. */
|
||||
if (!history_changed)
|
||||
return;
|
||||
/* If the histories are unchanged, don't bother saving them. */
|
||||
if (!history_changed)
|
||||
return;
|
||||
|
||||
histname = concatenate(statedir, SEARCH_HISTORY);
|
||||
hisfile = fopen(histname, "wb");
|
||||
histname = concatenate(statedir, SEARCH_HISTORY);
|
||||
hisfile = fopen(histname, "wb");
|
||||
|
||||
if (hisfile == NULL)
|
||||
fprintf(stderr, _("Error writing %s: %s\n"), histname,
|
||||
strerror(errno));
|
||||
else {
|
||||
/* Don't allow others to read or write the history file. */
|
||||
chmod(histname, S_IRUSR | S_IWUSR);
|
||||
if (hisfile == NULL)
|
||||
fprintf(stderr, _("Error writing %s: %s\n"), histname,
|
||||
strerror(errno));
|
||||
else {
|
||||
/* Don't allow others to read or write the history file. */
|
||||
chmod(histname, S_IRUSR | S_IWUSR);
|
||||
|
||||
if (!write_list(searchtop, hisfile) ||
|
||||
!write_list(replacetop, hisfile) ||
|
||||
!write_list(executetop, hisfile))
|
||||
fprintf(stderr, _("Error writing %s: %s\n"), histname,
|
||||
strerror(errno));
|
||||
if (!write_list(searchtop, hisfile) ||
|
||||
!write_list(replacetop, hisfile) ||
|
||||
!write_list(executetop, hisfile))
|
||||
fprintf(stderr, _("Error writing %s: %s\n"), histname,
|
||||
strerror(errno));
|
||||
|
||||
fclose(hisfile);
|
||||
}
|
||||
fclose(hisfile);
|
||||
}
|
||||
|
||||
free(histname);
|
||||
free(histname);
|
||||
}
|
||||
|
||||
/* Load the recorded cursor positions for files that were edited. */
|
||||
void load_poshistory(void)
|
||||
{
|
||||
FILE *hisfile = fopen(poshistname, "rb");
|
||||
FILE *hisfile = fopen(poshistname, "rb");
|
||||
|
||||
if (hisfile == NULL) {
|
||||
if (errno != ENOENT) {
|
||||
/* When reading failed, don't save history when we quit. */
|
||||
UNSET(POS_HISTORY);
|
||||
history_error(N_("Error reading %s: %s"), poshistname, strerror(errno));
|
||||
if (hisfile == NULL) {
|
||||
if (errno != ENOENT) {
|
||||
/* When reading failed, don't save history when we quit. */
|
||||
UNSET(POS_HISTORY);
|
||||
history_error(N_("Error reading %s: %s"), poshistname, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
char *line = NULL, *lineptr, *xptr;
|
||||
size_t buf_len = 0;
|
||||
ssize_t read, count = 0;
|
||||
poshiststruct *record_ptr = NULL, *newrecord;
|
||||
|
||||
/* Read and parse each line, and store the extracted data. */
|
||||
while ((read = getline(&line, &buf_len, hisfile)) > 5) {
|
||||
/* Decode nulls as embedded newlines. */
|
||||
unsunder(line, read);
|
||||
|
||||
/* Find where the x index and line number are in the line. */
|
||||
xptr = revstrstr(line, " ", line + read - 3);
|
||||
if (xptr == NULL)
|
||||
continue;
|
||||
lineptr = revstrstr(line, " ", xptr - 2);
|
||||
if (lineptr == NULL)
|
||||
continue;
|
||||
|
||||
/* Now separate the three elements of the line. */
|
||||
*(xptr++) = '\0';
|
||||
*(lineptr++) = '\0';
|
||||
|
||||
/* Create a new position record. */
|
||||
newrecord = (poshiststruct *)nmalloc(sizeof(poshiststruct));
|
||||
newrecord->filename = mallocstrcpy(NULL, line);
|
||||
newrecord->lineno = atoi(lineptr);
|
||||
newrecord->xno = atoi(xptr);
|
||||
newrecord->next = NULL;
|
||||
|
||||
/* Add the record to the list. */
|
||||
if (position_history == NULL)
|
||||
position_history = newrecord;
|
||||
else
|
||||
record_ptr->next = newrecord;
|
||||
|
||||
record_ptr = newrecord;
|
||||
|
||||
/* Impose a limit, so the file will not grow indefinitely. */
|
||||
if (++count > 200) {
|
||||
poshiststruct *drop_record = position_history;
|
||||
|
||||
position_history = position_history->next;
|
||||
|
||||
free(drop_record->filename);
|
||||
free(drop_record);
|
||||
}
|
||||
}
|
||||
fclose(hisfile);
|
||||
free(line);
|
||||
|
||||
stat(poshistname, &stat_of_positions_file);
|
||||
}
|
||||
} else {
|
||||
char *line = NULL, *lineptr, *xptr;
|
||||
size_t buf_len = 0;
|
||||
ssize_t read, count = 0;
|
||||
poshiststruct *record_ptr = NULL, *newrecord;
|
||||
|
||||
/* Read and parse each line, and store the extracted data. */
|
||||
while ((read = getline(&line, &buf_len, hisfile)) > 5) {
|
||||
/* Decode nulls as embedded newlines. */
|
||||
unsunder(line, read);
|
||||
|
||||
/* Find where the x index and line number are in the line. */
|
||||
xptr = revstrstr(line, " ", line + read - 3);
|
||||
if (xptr == NULL)
|
||||
continue;
|
||||
lineptr = revstrstr(line, " ", xptr - 2);
|
||||
if (lineptr == NULL)
|
||||
continue;
|
||||
|
||||
/* Now separate the three elements of the line. */
|
||||
*(xptr++) = '\0';
|
||||
*(lineptr++) = '\0';
|
||||
|
||||
/* Create a new position record. */
|
||||
newrecord = (poshiststruct *)nmalloc(sizeof(poshiststruct));
|
||||
newrecord->filename = mallocstrcpy(NULL, line);
|
||||
newrecord->lineno = atoi(lineptr);
|
||||
newrecord->xno = atoi(xptr);
|
||||
newrecord->next = NULL;
|
||||
|
||||
/* Add the record to the list. */
|
||||
if (position_history == NULL)
|
||||
position_history = newrecord;
|
||||
else
|
||||
record_ptr->next = newrecord;
|
||||
|
||||
record_ptr = newrecord;
|
||||
|
||||
/* Impose a limit, so the file will not grow indefinitely. */
|
||||
if (++count > 200) {
|
||||
poshiststruct *drop_record = position_history;
|
||||
|
||||
position_history = position_history->next;
|
||||
|
||||
free(drop_record->filename);
|
||||
free(drop_record);
|
||||
}
|
||||
}
|
||||
fclose(hisfile);
|
||||
free(line);
|
||||
|
||||
stat(poshistname, &stat_of_positions_file);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the recorded cursor positions for files that were edited. */
|
||||
void save_poshistory(void)
|
||||
{
|
||||
poshiststruct *posptr;
|
||||
FILE *hisfile = fopen(poshistname, "wb");
|
||||
poshiststruct *posptr;
|
||||
FILE *hisfile = fopen(poshistname, "wb");
|
||||
|
||||
if (hisfile == NULL)
|
||||
fprintf(stderr, _("Error writing %s: %s\n"), poshistname, strerror(errno));
|
||||
else {
|
||||
/* Don't allow others to read or write the history file. */
|
||||
chmod(poshistname, S_IRUSR | S_IWUSR);
|
||||
if (hisfile == NULL)
|
||||
fprintf(stderr, _("Error writing %s: %s\n"), poshistname, strerror(errno));
|
||||
else {
|
||||
/* Don't allow others to read or write the history file. */
|
||||
chmod(poshistname, S_IRUSR | S_IWUSR);
|
||||
|
||||
for (posptr = position_history; posptr != NULL; posptr = posptr->next) {
|
||||
char *path_and_place;
|
||||
size_t length;
|
||||
for (posptr = position_history; posptr != NULL; posptr = posptr->next) {
|
||||
char *path_and_place;
|
||||
size_t length;
|
||||
|
||||
/* Assume 20 decimal positions each for line and column number,
|
||||
* plus two spaces, plus the line feed, plus the null byte. */
|
||||
path_and_place = charalloc(strlen(posptr->filename) + 44);
|
||||
sprintf(path_and_place, "%s %zd %zd\n",
|
||||
posptr->filename, posptr->lineno, posptr->xno);
|
||||
length = strlen(path_and_place);
|
||||
/* Assume 20 decimal positions each for line and column number,
|
||||
* plus two spaces, plus the line feed, plus the null byte. */
|
||||
path_and_place = charalloc(strlen(posptr->filename) + 44);
|
||||
sprintf(path_and_place, "%s %zd %zd\n",
|
||||
posptr->filename, posptr->lineno, posptr->xno);
|
||||
length = strlen(path_and_place);
|
||||
|
||||
/* Encode newlines in filenames as nulls. */
|
||||
sunder(path_and_place);
|
||||
/* Restore the terminating newline. */
|
||||
path_and_place[length - 1] = '\n';
|
||||
/* Encode newlines in filenames as nulls. */
|
||||
sunder(path_and_place);
|
||||
/* Restore the terminating newline. */
|
||||
path_and_place[length - 1] = '\n';
|
||||
|
||||
if (fwrite(path_and_place, sizeof(char), length, hisfile) < length)
|
||||
fprintf(stderr, _("Error writing %s: %s\n"),
|
||||
poshistname, strerror(errno));
|
||||
free(path_and_place);
|
||||
if (fwrite(path_and_place, sizeof(char), length, hisfile) < length)
|
||||
fprintf(stderr, _("Error writing %s: %s\n"),
|
||||
poshistname, strerror(errno));
|
||||
free(path_and_place);
|
||||
}
|
||||
fclose(hisfile);
|
||||
|
||||
stat(poshistname, &stat_of_positions_file);
|
||||
}
|
||||
fclose(hisfile);
|
||||
|
||||
stat(poshistname, &stat_of_positions_file);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reload the position history file if it has been modified since last load. */
|
||||
void reload_positions_if_needed(void)
|
||||
{
|
||||
struct stat newstat;
|
||||
struct stat newstat;
|
||||
|
||||
stat(poshistname, &newstat);
|
||||
stat(poshistname, &newstat);
|
||||
|
||||
if (newstat.st_mtime != stat_of_positions_file.st_mtime) {
|
||||
poshiststruct *ptr, *nextone;
|
||||
if (newstat.st_mtime != stat_of_positions_file.st_mtime) {
|
||||
poshiststruct *ptr, *nextone;
|
||||
|
||||
for (ptr = position_history; ptr != NULL; ptr = nextone) {
|
||||
nextone = ptr->next;
|
||||
free(ptr->filename);
|
||||
free(ptr);
|
||||
for (ptr = position_history; ptr != NULL; ptr = nextone) {
|
||||
nextone = ptr->next;
|
||||
free(ptr->filename);
|
||||
free(ptr);
|
||||
}
|
||||
position_history = NULL;
|
||||
|
||||
load_poshistory();
|
||||
}
|
||||
position_history = NULL;
|
||||
|
||||
load_poshistory();
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the recorded last file positions, given a filename, a line
|
||||
* and a column. If no entry is found, add a new one at the end. */
|
||||
void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
|
||||
{
|
||||
poshiststruct *posptr, *theone, *posprev = NULL;
|
||||
char *fullpath = get_full_path(filename);
|
||||
poshiststruct *posptr, *theone, *posprev = NULL;
|
||||
char *fullpath = get_full_path(filename);
|
||||
|
||||
if (fullpath == NULL || fullpath[strlen(fullpath) - 1] == '/' || inhelp) {
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
reload_positions_if_needed();
|
||||
|
||||
/* Look for a matching filename in the list. */
|
||||
for (posptr = position_history; posptr != NULL; posptr = posptr->next) {
|
||||
if (!strcmp(posptr->filename, fullpath))
|
||||
break;
|
||||
posprev = posptr;
|
||||
}
|
||||
|
||||
/* Don't record files that have the default cursor position. */
|
||||
if (lineno == 1 && xpos == 1) {
|
||||
if (posptr != NULL) {
|
||||
if (posprev == NULL)
|
||||
position_history = posptr->next;
|
||||
else
|
||||
posprev->next = posptr->next;
|
||||
free(posptr->filename);
|
||||
free(posptr);
|
||||
if (fullpath == NULL || fullpath[strlen(fullpath) - 1] == '/' || inhelp) {
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
reload_positions_if_needed();
|
||||
|
||||
/* Look for a matching filename in the list. */
|
||||
for (posptr = position_history; posptr != NULL; posptr = posptr->next) {
|
||||
if (!strcmp(posptr->filename, fullpath))
|
||||
break;
|
||||
posprev = posptr;
|
||||
}
|
||||
|
||||
/* Don't record files that have the default cursor position. */
|
||||
if (lineno == 1 && xpos == 1) {
|
||||
if (posptr != NULL) {
|
||||
if (posprev == NULL)
|
||||
position_history = posptr->next;
|
||||
else
|
||||
posprev->next = posptr->next;
|
||||
free(posptr->filename);
|
||||
free(posptr);
|
||||
save_poshistory();
|
||||
}
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
theone = posptr;
|
||||
|
||||
/* If we didn't find it, make a new node; otherwise, if we're
|
||||
* not at the end, move the matching one to the end. */
|
||||
if (theone == NULL) {
|
||||
theone = (poshiststruct *)nmalloc(sizeof(poshiststruct));
|
||||
theone->filename = mallocstrcpy(NULL, fullpath);
|
||||
if (position_history == NULL)
|
||||
position_history = theone;
|
||||
else
|
||||
posprev->next = theone;
|
||||
} else if (posptr->next != NULL) {
|
||||
if (posprev == NULL)
|
||||
position_history = posptr->next;
|
||||
else
|
||||
posprev->next = posptr->next;
|
||||
while (posptr->next != NULL)
|
||||
posptr = posptr->next;
|
||||
posptr->next = theone;
|
||||
}
|
||||
|
||||
/* Store the last cursor position. */
|
||||
theone->lineno = lineno;
|
||||
theone->xno = xpos;
|
||||
theone->next = NULL;
|
||||
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
theone = posptr;
|
||||
|
||||
/* If we didn't find it, make a new node; otherwise, if we're
|
||||
* not at the end, move the matching one to the end. */
|
||||
if (theone == NULL) {
|
||||
theone = (poshiststruct *)nmalloc(sizeof(poshiststruct));
|
||||
theone->filename = mallocstrcpy(NULL, fullpath);
|
||||
if (position_history == NULL)
|
||||
position_history = theone;
|
||||
else
|
||||
posprev->next = theone;
|
||||
} else if (posptr->next != NULL) {
|
||||
if (posprev == NULL)
|
||||
position_history = posptr->next;
|
||||
else
|
||||
posprev->next = posptr->next;
|
||||
while (posptr->next != NULL)
|
||||
posptr = posptr->next;
|
||||
posptr->next = theone;
|
||||
}
|
||||
|
||||
/* Store the last cursor position. */
|
||||
theone->lineno = lineno;
|
||||
theone->xno = xpos;
|
||||
theone->next = NULL;
|
||||
|
||||
free(fullpath);
|
||||
|
||||
save_poshistory();
|
||||
save_poshistory();
|
||||
}
|
||||
|
||||
/* Check whether the given file matches an existing entry in the recorded
|
||||
@@ -589,24 +593,24 @@ void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
|
||||
* set line and column to the retrieved values. */
|
||||
bool has_old_position(const char *file, ssize_t *line, ssize_t *column)
|
||||
{
|
||||
poshiststruct *posptr = position_history;
|
||||
char *fullpath = get_full_path(file);
|
||||
poshiststruct *posptr = position_history;
|
||||
char *fullpath = get_full_path(file);
|
||||
|
||||
if (fullpath == NULL)
|
||||
return FALSE;
|
||||
if (fullpath == NULL)
|
||||
return FALSE;
|
||||
|
||||
reload_positions_if_needed();
|
||||
reload_positions_if_needed();
|
||||
|
||||
while (posptr != NULL && strcmp(posptr->filename, fullpath) != 0)
|
||||
posptr = posptr->next;
|
||||
while (posptr != NULL && strcmp(posptr->filename, fullpath) != 0)
|
||||
posptr = posptr->next;
|
||||
|
||||
free(fullpath);
|
||||
free(fullpath);
|
||||
|
||||
if (posptr == NULL)
|
||||
return FALSE;
|
||||
if (posptr == NULL)
|
||||
return FALSE;
|
||||
|
||||
*line = posptr->lineno;
|
||||
*column = posptr->xno;
|
||||
return TRUE;
|
||||
*line = posptr->lineno;
|
||||
*column = posptr->xno;
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* ENABLE_HISTORIES */
|
||||
|
||||
734
src/move.c
734
src/move.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* move.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -24,44 +24,44 @@
|
||||
#include <string.h>
|
||||
|
||||
/* Move to the first line of the file. */
|
||||
void do_first_line(void)
|
||||
void to_first_line(void)
|
||||
{
|
||||
openfile->current = openfile->fileage;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
openfile->current = openfile->fileage;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
|
||||
refresh_needed = TRUE;
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* Move to the last line of the file. */
|
||||
void do_last_line(void)
|
||||
void to_last_line(void)
|
||||
{
|
||||
openfile->current = openfile->filebot;
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
openfile->placewewant = xplustabs();
|
||||
openfile->current = openfile->filebot;
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* Set the last line of the screen as the target for the cursor. */
|
||||
openfile->current_y = editwinrows - 1;
|
||||
/* Set the last line of the screen as the target for the cursor. */
|
||||
openfile->current_y = editwinrows - 1;
|
||||
|
||||
refresh_needed = TRUE;
|
||||
focusing = FALSE;
|
||||
refresh_needed = TRUE;
|
||||
focusing = FALSE;
|
||||
}
|
||||
|
||||
/* Determine the actual current chunk and the target column. */
|
||||
void get_edge_and_target(size_t *leftedge, size_t *target_column)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
size_t shim = editwincols * (1 + (tabsize / editwincols));
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
size_t shim = editwincols * (1 + (tabsize / editwincols));
|
||||
|
||||
*leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
*target_column = (openfile->placewewant + shim - *leftedge) % editwincols;
|
||||
} else
|
||||
*leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
*target_column = (openfile->placewewant + shim - *leftedge) % editwincols;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
*leftedge = 0;
|
||||
*target_column = openfile->placewewant;
|
||||
}
|
||||
{
|
||||
*leftedge = 0;
|
||||
*target_column = openfile->placewewant;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the index in line->data that corresponds to the given column on the
|
||||
@@ -69,104 +69,104 @@ void get_edge_and_target(size_t *leftedge, size_t *target_column)
|
||||
* on a tab, prevent the cursor from falling back a row when moving forward,
|
||||
* or from skipping a row when moving backward, by incrementing the index. */
|
||||
size_t proper_x(filestruct *line, size_t *leftedge, bool forward,
|
||||
size_t column, bool *shifted)
|
||||
size_t column, bool *shifted)
|
||||
{
|
||||
size_t index = actual_x(line->data, column);
|
||||
size_t index = actual_x(line->data, column);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP) && line->data[index] == '\t' &&
|
||||
((forward && strnlenpt(line->data, index) < *leftedge) ||
|
||||
(!forward && column / tabsize == (*leftedge - 1) / tabsize &&
|
||||
column / tabsize < (*leftedge + editwincols - 1) / tabsize))) {
|
||||
index++;
|
||||
if (ISSET(SOFTWRAP) && line->data[index] == '\t' &&
|
||||
((forward && strnlenpt(line->data, index) < *leftedge) ||
|
||||
(!forward && column / tabsize == (*leftedge - 1) / tabsize &&
|
||||
column / tabsize < (*leftedge + editwincols - 1) / tabsize))) {
|
||||
index++;
|
||||
|
||||
if (shifted != NULL)
|
||||
*shifted = TRUE;
|
||||
}
|
||||
if (shifted != NULL)
|
||||
*shifted = TRUE;
|
||||
}
|
||||
|
||||
if (ISSET(SOFTWRAP))
|
||||
*leftedge = leftedge_for(strnlenpt(line->data, index), line);
|
||||
if (ISSET(SOFTWRAP))
|
||||
*leftedge = leftedge_for(strnlenpt(line->data, index), line);
|
||||
#endif
|
||||
|
||||
return index;
|
||||
return index;
|
||||
}
|
||||
|
||||
/* Adjust the values for current_x and placewewant in case we have landed in
|
||||
* the middle of a tab that crosses a row boundary. */
|
||||
void set_proper_index_and_pww(size_t *leftedge, size_t target, bool forward)
|
||||
{
|
||||
bool shifted = FALSE;
|
||||
size_t was_edge = *leftedge;
|
||||
bool shifted = FALSE;
|
||||
size_t was_edge = *leftedge;
|
||||
|
||||
openfile->current_x = proper_x(openfile->current, leftedge, forward,
|
||||
actual_last_column(*leftedge, target), &shifted);
|
||||
|
||||
/* If the index was incremented, try going to the target column. */
|
||||
if (shifted || *leftedge < was_edge)
|
||||
openfile->current_x = proper_x(openfile->current, leftedge, forward,
|
||||
actual_last_column(*leftedge, target), &shifted);
|
||||
actual_last_column(*leftedge, target), &shifted);
|
||||
|
||||
openfile->placewewant = *leftedge + target;
|
||||
/* If the index was incremented, try going to the target column. */
|
||||
if (shifted || *leftedge < was_edge)
|
||||
openfile->current_x = proper_x(openfile->current, leftedge, forward,
|
||||
actual_last_column(*leftedge, target), &shifted);
|
||||
|
||||
openfile->placewewant = *leftedge + target;
|
||||
}
|
||||
|
||||
/* Move up nearly one screenful. */
|
||||
void do_page_up(void)
|
||||
{
|
||||
int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
|
||||
size_t leftedge, target_column;
|
||||
int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
|
||||
size_t leftedge, target_column;
|
||||
|
||||
/* If we're not in smooth scrolling mode, put the cursor at the
|
||||
* beginning of the top line of the edit window, as Pico does. */
|
||||
if (!ISSET(SMOOTH_SCROLL)) {
|
||||
openfile->current = openfile->edittop;
|
||||
leftedge = openfile->firstcolumn;
|
||||
openfile->current_y = 0;
|
||||
target_column = 0;
|
||||
} else
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
/* If we're not in smooth scrolling mode, put the cursor at the
|
||||
* beginning of the top line of the edit window, as Pico does. */
|
||||
if (!ISSET(SMOOTH_SCROLL)) {
|
||||
openfile->current = openfile->edittop;
|
||||
leftedge = openfile->firstcolumn;
|
||||
openfile->current_y = 0;
|
||||
target_column = 0;
|
||||
} else
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
|
||||
/* Move up the required number of lines or chunks. If we can't, we're
|
||||
* at the top of the file, so put the cursor there and get out. */
|
||||
if (go_back_chunks(mustmove, &openfile->current, &leftedge) > 0) {
|
||||
do_first_line();
|
||||
return;
|
||||
}
|
||||
/* Move up the required number of lines or chunks. If we can't, we're
|
||||
* at the top of the file, so put the cursor there and get out. */
|
||||
if (go_back_chunks(mustmove, &openfile->current, &leftedge) > 0) {
|
||||
to_first_line();
|
||||
return;
|
||||
}
|
||||
|
||||
set_proper_index_and_pww(&leftedge, target_column, FALSE);
|
||||
set_proper_index_and_pww(&leftedge, target_column, FALSE);
|
||||
|
||||
/* Move the viewport so that the cursor stays immobile, if possible. */
|
||||
adjust_viewport(STATIONARY);
|
||||
refresh_needed = TRUE;
|
||||
/* Move the viewport so that the cursor stays immobile, if possible. */
|
||||
adjust_viewport(STATIONARY);
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* Move down nearly one screenful. */
|
||||
void do_page_down(void)
|
||||
{
|
||||
int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
|
||||
size_t leftedge, target_column;
|
||||
int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
|
||||
size_t leftedge, target_column;
|
||||
|
||||
/* If we're not in smooth scrolling mode, put the cursor at the
|
||||
* beginning of the top line of the edit window, as Pico does. */
|
||||
if (!ISSET(SMOOTH_SCROLL)) {
|
||||
openfile->current = openfile->edittop;
|
||||
leftedge = openfile->firstcolumn;
|
||||
openfile->current_y = 0;
|
||||
target_column = 0;
|
||||
} else
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
/* If we're not in smooth scrolling mode, put the cursor at the
|
||||
* beginning of the top line of the edit window, as Pico does. */
|
||||
if (!ISSET(SMOOTH_SCROLL)) {
|
||||
openfile->current = openfile->edittop;
|
||||
leftedge = openfile->firstcolumn;
|
||||
openfile->current_y = 0;
|
||||
target_column = 0;
|
||||
} else
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
|
||||
/* Move down the required number of lines or chunks. If we can't, we're
|
||||
* at the bottom of the file, so put the cursor there and get out. */
|
||||
if (go_forward_chunks(mustmove, &openfile->current, &leftedge) > 0) {
|
||||
do_last_line();
|
||||
return;
|
||||
}
|
||||
/* Move down the required number of lines or chunks. If we can't, we're
|
||||
* at the bottom of the file, so put the cursor there and get out. */
|
||||
if (go_forward_chunks(mustmove, &openfile->current, &leftedge) > 0) {
|
||||
to_last_line();
|
||||
return;
|
||||
}
|
||||
|
||||
set_proper_index_and_pww(&leftedge, target_column, TRUE);
|
||||
set_proper_index_and_pww(&leftedge, target_column, TRUE);
|
||||
|
||||
/* Move the viewport so that the cursor stays immobile, if possible. */
|
||||
adjust_viewport(STATIONARY);
|
||||
refresh_needed = TRUE;
|
||||
/* Move the viewport so that the cursor stays immobile, if possible. */
|
||||
adjust_viewport(STATIONARY);
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
@@ -174,18 +174,18 @@ void do_page_down(void)
|
||||
* current line. If update_screen is TRUE, update the screen afterwards. */
|
||||
void do_para_begin(bool update_screen)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
filestruct *was_current = openfile->current;
|
||||
|
||||
if (openfile->current != openfile->fileage)
|
||||
openfile->current = openfile->current->prev;
|
||||
if (openfile->current != openfile->fileage)
|
||||
openfile->current = openfile->current->prev;
|
||||
|
||||
while (!begpar(openfile->current))
|
||||
openfile->current = openfile->current->prev;
|
||||
while (!begpar(openfile->current))
|
||||
openfile->current = openfile->current->prev;
|
||||
|
||||
openfile->current_x = 0;
|
||||
openfile->current_x = 0;
|
||||
|
||||
if (update_screen)
|
||||
edit_redraw(was_current, CENTERING);
|
||||
if (update_screen)
|
||||
edit_redraw(was_current, CENTERING);
|
||||
}
|
||||
|
||||
/* Move down to the beginning of the last line of the current paragraph.
|
||||
@@ -196,178 +196,194 @@ void do_para_begin(bool update_screen)
|
||||
* paragraph or isn't in a paragraph. */
|
||||
void do_para_end(bool update_screen)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
filestruct *was_current = openfile->current;
|
||||
|
||||
while (openfile->current != openfile->filebot &&
|
||||
!inpar(openfile->current))
|
||||
openfile->current = openfile->current->next;
|
||||
while (openfile->current != openfile->filebot &&
|
||||
!inpar(openfile->current))
|
||||
openfile->current = openfile->current->next;
|
||||
|
||||
while (openfile->current != openfile->filebot &&
|
||||
inpar(openfile->current->next) &&
|
||||
!begpar(openfile->current->next)) {
|
||||
openfile->current = openfile->current->next;
|
||||
}
|
||||
while (openfile->current != openfile->filebot &&
|
||||
inpar(openfile->current->next) &&
|
||||
!begpar(openfile->current->next)) {
|
||||
openfile->current = openfile->current->next;
|
||||
}
|
||||
|
||||
if (openfile->current != openfile->filebot) {
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = 0;
|
||||
} else
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
if (openfile->current != openfile->filebot) {
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = 0;
|
||||
} else
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
|
||||
if (update_screen)
|
||||
edit_redraw(was_current, CENTERING);
|
||||
if (update_screen)
|
||||
edit_redraw(was_current, CENTERING);
|
||||
}
|
||||
|
||||
/* Move up to first start of a paragraph before the current line. */
|
||||
void do_para_begin_void(void)
|
||||
{
|
||||
do_para_begin(TRUE);
|
||||
do_para_begin(TRUE);
|
||||
}
|
||||
|
||||
/* Move down to just after the first end of a paragraph. */
|
||||
void do_para_end_void(void)
|
||||
{
|
||||
do_para_end(TRUE);
|
||||
do_para_end(TRUE);
|
||||
}
|
||||
#endif /* ENABLE_JUSTIFY */
|
||||
|
||||
/* Move to the preceding block of text. */
|
||||
void do_prev_block(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
bool is_text = FALSE, seen_text = FALSE;
|
||||
filestruct *was_current = openfile->current;
|
||||
bool is_text = FALSE, seen_text = FALSE;
|
||||
|
||||
/* Skip backward until first blank line after some nonblank line(s). */
|
||||
while (openfile->current->prev != NULL && (!seen_text || is_text)) {
|
||||
openfile->current = openfile->current->prev;
|
||||
is_text = !white_string(openfile->current->data);
|
||||
seen_text = seen_text || is_text;
|
||||
}
|
||||
/* Skip backward until first blank line after some nonblank line(s). */
|
||||
while (openfile->current->prev != NULL && (!seen_text || is_text)) {
|
||||
openfile->current = openfile->current->prev;
|
||||
is_text = !white_string(openfile->current->data);
|
||||
seen_text = seen_text || is_text;
|
||||
}
|
||||
|
||||
/* Step forward one line again if this one is blank. */
|
||||
if (openfile->current->next != NULL &&
|
||||
white_string(openfile->current->data))
|
||||
openfile->current = openfile->current->next;
|
||||
/* Step forward one line again if this one is blank. */
|
||||
if (openfile->current->next != NULL &&
|
||||
white_string(openfile->current->data))
|
||||
openfile->current = openfile->current->next;
|
||||
|
||||
openfile->current_x = 0;
|
||||
edit_redraw(was_current, CENTERING);
|
||||
openfile->current_x = 0;
|
||||
edit_redraw(was_current, CENTERING);
|
||||
}
|
||||
|
||||
/* Move to the next block of text. */
|
||||
void do_next_block(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
bool is_white = white_string(openfile->current->data);
|
||||
bool seen_white = is_white;
|
||||
filestruct *was_current = openfile->current;
|
||||
bool is_white = white_string(openfile->current->data);
|
||||
bool seen_white = is_white;
|
||||
|
||||
/* Skip forward until first nonblank line after some blank line(s). */
|
||||
while (openfile->current->next != NULL && (!seen_white || is_white)) {
|
||||
openfile->current = openfile->current->next;
|
||||
is_white = white_string(openfile->current->data);
|
||||
seen_white = seen_white || is_white;
|
||||
}
|
||||
/* Skip forward until first nonblank line after some blank line(s). */
|
||||
while (openfile->current->next != NULL && (!seen_white || is_white)) {
|
||||
openfile->current = openfile->current->next;
|
||||
is_white = white_string(openfile->current->data);
|
||||
seen_white = seen_white || is_white;
|
||||
}
|
||||
|
||||
openfile->current_x = 0;
|
||||
edit_redraw(was_current, CENTERING);
|
||||
openfile->current_x = 0;
|
||||
edit_redraw(was_current, CENTERING);
|
||||
}
|
||||
|
||||
/* Move to the previous word. If allow_punct is TRUE, treat punctuation
|
||||
* as part of a word. When requested, update the screen afterwards. */
|
||||
void do_prev_word(bool allow_punct, bool update_screen)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
bool seen_a_word = FALSE, step_forward = FALSE;
|
||||
filestruct *was_current = openfile->current;
|
||||
bool seen_a_word = FALSE, step_forward = FALSE;
|
||||
|
||||
/* Move backward until we pass over the start of a word. */
|
||||
while (TRUE) {
|
||||
/* If at the head of a line, move to the end of the preceding one. */
|
||||
if (openfile->current_x == 0) {
|
||||
if (openfile->current->prev == NULL)
|
||||
break;
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
/* Move backward until we pass over the start of a word. */
|
||||
while (TRUE) {
|
||||
/* If at the head of a line, move to the end of the preceding one. */
|
||||
if (openfile->current_x == 0) {
|
||||
if (openfile->current->prev == NULL)
|
||||
break;
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
}
|
||||
|
||||
/* Step back one character. */
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
|
||||
if (is_word_mbchar(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. */
|
||||
if (openfile->current_x == 0)
|
||||
break;
|
||||
} else if (seen_a_word) {
|
||||
/* This is space now: we've overshot the start of the word. */
|
||||
step_forward = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step back one character. */
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
if (step_forward)
|
||||
/* Move one character forward again to sit on the start of the word. */
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x);
|
||||
|
||||
if (is_word_mbchar(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. */
|
||||
if (openfile->current_x == 0)
|
||||
break;
|
||||
} 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. */
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x);
|
||||
|
||||
if (update_screen)
|
||||
edit_redraw(was_current, FLOWING);
|
||||
if (update_screen)
|
||||
edit_redraw(was_current, FLOWING);
|
||||
}
|
||||
|
||||
/* Move to the next word. If allow_punct is TRUE, treat punctuation
|
||||
* as part of a word. When requested, update the screen afterwards.
|
||||
/* Move to the next word. If after_ends is TRUE, stop at the ends of words
|
||||
* instead of their beginnings. If allow_punct is TRUE, treat punctuation
|
||||
* as part of a word. When requested, update the screen afterwards.
|
||||
* Return TRUE if we started on a word, and FALSE otherwise. */
|
||||
bool do_next_word(bool allow_punct, bool update_screen)
|
||||
bool do_next_word(bool after_ends, bool allow_punct, bool update_screen)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
bool started_on_word = is_word_mbchar(openfile->current->data +
|
||||
openfile->current_x, allow_punct);
|
||||
bool seen_space = !started_on_word;
|
||||
filestruct *was_current = openfile->current;
|
||||
bool started_on_word = is_word_mbchar(openfile->current->data +
|
||||
openfile->current_x, allow_punct);
|
||||
bool seen_space = !started_on_word;
|
||||
bool seen_word = started_on_word;
|
||||
|
||||
/* Move forward until we reach the start of a word. */
|
||||
while (TRUE) {
|
||||
/* If at the end of a line, move to the beginning of the next one. */
|
||||
if (openfile->current->data[openfile->current_x] == '\0') {
|
||||
/* When at end of file, stop. */
|
||||
if (openfile->current->next == NULL)
|
||||
break;
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = 0;
|
||||
seen_space = TRUE;
|
||||
} else {
|
||||
/* Step forward one character. */
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x);
|
||||
/* Move forward until we reach the start of a word. */
|
||||
while (TRUE) {
|
||||
/* If at the end of a line, move to the beginning of the next one. */
|
||||
if (openfile->current->data[openfile->current_x] == '\0') {
|
||||
/* When at end of file, stop. */
|
||||
if (openfile->current->next == NULL)
|
||||
break;
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = 0;
|
||||
seen_space = TRUE;
|
||||
} else {
|
||||
/* Step forward one character. */
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
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,
|
||||
allow_punct))
|
||||
seen_word = TRUE;
|
||||
else if (seen_word)
|
||||
break;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* 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,
|
||||
allow_punct))
|
||||
seen_space = TRUE;
|
||||
else if (seen_space)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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,
|
||||
allow_punct))
|
||||
seen_space = TRUE;
|
||||
else if (seen_space)
|
||||
break;
|
||||
}
|
||||
if (update_screen)
|
||||
edit_redraw(was_current, FLOWING);
|
||||
|
||||
if (update_screen)
|
||||
edit_redraw(was_current, FLOWING);
|
||||
|
||||
/* Return whether we started on a word. */
|
||||
return started_on_word;
|
||||
/* Return whether we started on a word. */
|
||||
return started_on_word;
|
||||
}
|
||||
|
||||
/* Move to the previous word in the file, treating punctuation as part of a
|
||||
* word if the WORD_BOUNDS flag is set, and update the screen afterwards. */
|
||||
void do_prev_word_void(void)
|
||||
{
|
||||
do_prev_word(ISSET(WORD_BOUNDS), TRUE);
|
||||
do_prev_word(ISSET(WORD_BOUNDS), TRUE);
|
||||
}
|
||||
|
||||
/* Move to the next word in the file, treating punctuation as part of a word
|
||||
* if the WORD_BOUNDS flag is set, and update the screen afterwards. */
|
||||
/* 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)
|
||||
{
|
||||
do_next_word(ISSET(WORD_BOUNDS), TRUE);
|
||||
do_next_word(ISSET(AFTER_ENDS), ISSET(WORD_BOUNDS), TRUE);
|
||||
}
|
||||
|
||||
/* Move to the beginning of the current line (or softwrapped chunk).
|
||||
@@ -375,59 +391,59 @@ void do_next_word_void(void)
|
||||
* of the full line when already at the start of a chunk. */
|
||||
void do_home(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t was_column = xplustabs();
|
||||
bool moved_off_chunk = TRUE;
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t was_column = xplustabs();
|
||||
bool moved_off_chunk = TRUE;
|
||||
#ifndef NANO_TINY
|
||||
bool moved = FALSE;
|
||||
size_t leftedge = 0, leftedge_x = 0;
|
||||
bool moved = FALSE;
|
||||
size_t leftedge = 0, leftedge_x = 0;
|
||||
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
leftedge = leftedge_for(was_column, openfile->current);
|
||||
leftedge_x = proper_x(openfile->current, &leftedge, FALSE, leftedge,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (ISSET(SMART_HOME)) {
|
||||
size_t indent_x = indent_length(openfile->current->data);
|
||||
|
||||
if (openfile->current->data[indent_x] != '\0') {
|
||||
/* If we're exactly on the indent, move fully home. Otherwise,
|
||||
* when not softwrapping or not after the first nonblank chunk,
|
||||
* move to the first nonblank character. */
|
||||
if (openfile->current_x == indent_x) {
|
||||
openfile->current_x = 0;
|
||||
moved = TRUE;
|
||||
} else if (!ISSET(SOFTWRAP) || leftedge_x <= indent_x) {
|
||||
openfile->current_x = indent_x;
|
||||
moved = TRUE;
|
||||
}
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
leftedge = leftedge_for(was_column, openfile->current);
|
||||
leftedge_x = proper_x(openfile->current, &leftedge, FALSE, leftedge,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!moved && ISSET(SOFTWRAP)) {
|
||||
/* If already at the left edge of the screen, move fully home.
|
||||
* Otherwise, move to the left edge. */
|
||||
if (openfile->current_x == leftedge_x)
|
||||
openfile->current_x = 0;
|
||||
else {
|
||||
openfile->current_x = leftedge_x;
|
||||
openfile->placewewant = leftedge;
|
||||
moved_off_chunk = FALSE;
|
||||
if (ISSET(SMART_HOME)) {
|
||||
size_t indent_x = indent_length(openfile->current->data);
|
||||
|
||||
if (openfile->current->data[indent_x] != '\0') {
|
||||
/* If we're exactly on the indent, move fully home. Otherwise,
|
||||
* when not softwrapping or not after the first nonblank chunk,
|
||||
* move to the first nonblank character. */
|
||||
if (openfile->current_x == indent_x) {
|
||||
openfile->current_x = 0;
|
||||
moved = TRUE;
|
||||
} else if (!ISSET(SOFTWRAP) || leftedge_x <= indent_x) {
|
||||
openfile->current_x = indent_x;
|
||||
moved = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!moved)
|
||||
|
||||
if (!moved && ISSET(SOFTWRAP)) {
|
||||
/* If already at the left edge of the screen, move fully home.
|
||||
* Otherwise, move to the left edge. */
|
||||
if (openfile->current_x == leftedge_x)
|
||||
openfile->current_x = 0;
|
||||
else {
|
||||
openfile->current_x = leftedge_x;
|
||||
openfile->placewewant = leftedge;
|
||||
moved_off_chunk = FALSE;
|
||||
}
|
||||
} else if (!moved)
|
||||
#endif
|
||||
openfile->current_x = 0;
|
||||
openfile->current_x = 0;
|
||||
|
||||
if (moved_off_chunk)
|
||||
openfile->placewewant = xplustabs();
|
||||
if (moved_off_chunk)
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* If we changed chunk, we might be offscreen. Otherwise,
|
||||
* update current if the mark is on or we changed "page". */
|
||||
if (ISSET(SOFTWRAP) && moved_off_chunk)
|
||||
edit_redraw(was_current, FLOWING);
|
||||
else if (line_needs_update(was_column, openfile->placewewant))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
/* If we changed chunk, we might be offscreen. Otherwise,
|
||||
* update current if the mark is on or we changed "page". */
|
||||
if (ISSET(SOFTWRAP) && moved_off_chunk)
|
||||
edit_redraw(was_current, FLOWING);
|
||||
else if (line_needs_update(was_column, openfile->placewewant))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Move to the end of the current line (or softwrapped chunk).
|
||||
@@ -435,159 +451,157 @@ void do_home(void)
|
||||
* end of the full line. */
|
||||
void do_end(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t was_column = xplustabs();
|
||||
size_t line_len = strlen(openfile->current->data);
|
||||
bool moved_off_chunk = TRUE;
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t was_column = xplustabs();
|
||||
size_t line_len = strlen(openfile->current->data);
|
||||
bool moved_off_chunk = TRUE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
bool last_chunk = FALSE;
|
||||
size_t leftedge = leftedge_for(was_column, openfile->current);
|
||||
size_t rightedge = get_softwrap_breakpoint(openfile->current->data,
|
||||
leftedge, &last_chunk);
|
||||
size_t rightedge_x;
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
bool last_chunk = FALSE;
|
||||
size_t leftedge = leftedge_for(was_column, openfile->current);
|
||||
size_t rightedge = get_softwrap_breakpoint(openfile->current->data,
|
||||
leftedge, &last_chunk);
|
||||
size_t rightedge_x;
|
||||
|
||||
/* If we're on the last chunk, we're already at the end of the line.
|
||||
* Otherwise, we're one column past the end of the line. Shifting
|
||||
* backwards one column might put us in the middle of a multi-column
|
||||
* character, but actual_x() will fix that. */
|
||||
if (!last_chunk)
|
||||
rightedge--;
|
||||
/* If we're on the last chunk, we're already at the end of the line.
|
||||
* Otherwise, we're one column past the end of the line. Shifting
|
||||
* backwards one column might put us in the middle of a multi-column
|
||||
* character, but actual_x() will fix that. */
|
||||
if (!last_chunk)
|
||||
rightedge--;
|
||||
|
||||
rightedge_x = actual_x(openfile->current->data, rightedge);
|
||||
rightedge_x = actual_x(openfile->current->data, rightedge);
|
||||
|
||||
/* If already at the right edge of the screen, move fully to
|
||||
* the end of the line. Otherwise, move to the right edge. */
|
||||
if (openfile->current_x == rightedge_x)
|
||||
openfile->current_x = line_len;
|
||||
else {
|
||||
openfile->current_x = rightedge_x;
|
||||
openfile->placewewant = rightedge;
|
||||
moved_off_chunk = FALSE;
|
||||
}
|
||||
} else
|
||||
/* If already at the right edge of the screen, move fully to
|
||||
* the end of the line. Otherwise, move to the right edge. */
|
||||
if (openfile->current_x == rightedge_x)
|
||||
openfile->current_x = line_len;
|
||||
else {
|
||||
openfile->current_x = rightedge_x;
|
||||
openfile->placewewant = rightedge;
|
||||
moved_off_chunk = FALSE;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
openfile->current_x = line_len;
|
||||
openfile->current_x = line_len;
|
||||
|
||||
if (moved_off_chunk)
|
||||
openfile->placewewant = xplustabs();
|
||||
if (moved_off_chunk)
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* If we changed chunk, we might be offscreen. Otherwise,
|
||||
* update current if the mark is on or we changed "page". */
|
||||
if (ISSET(SOFTWRAP) && moved_off_chunk)
|
||||
edit_redraw(was_current, FLOWING);
|
||||
else if (line_needs_update(was_column, openfile->placewewant))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
/* If we changed chunk, we might be offscreen. Otherwise,
|
||||
* update current if the mark is on or we changed "page". */
|
||||
if (ISSET(SOFTWRAP) && moved_off_chunk)
|
||||
edit_redraw(was_current, FLOWING);
|
||||
else if (line_needs_update(was_column, openfile->placewewant))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Move the cursor to the preceding line or chunk. If scroll_only is TRUE,
|
||||
* also scroll the screen one row, so the cursor stays in the same spot. */
|
||||
void do_up(bool scroll_only)
|
||||
/* Move the cursor to the preceding line or chunk. */
|
||||
void do_up(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t leftedge, target_column;
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t leftedge, target_column;
|
||||
|
||||
/* When just scrolling and the top of the file is onscreen, get out. */
|
||||
if (scroll_only && openfile->edittop == openfile->fileage &&
|
||||
openfile->firstcolumn == 0)
|
||||
return;
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
/* If we can't move up one line or chunk, we're at top of file. */
|
||||
if (go_back_chunks(1, &openfile->current, &leftedge) > 0)
|
||||
return;
|
||||
|
||||
/* If we can't move up one line or chunk, we're at top of file. */
|
||||
if (go_back_chunks(1, &openfile->current, &leftedge) > 0)
|
||||
return;
|
||||
set_proper_index_and_pww(&leftedge, target_column, FALSE);
|
||||
|
||||
set_proper_index_and_pww(&leftedge, target_column, FALSE);
|
||||
if (openfile->current_y == 0 && ISSET(SMOOTH_SCROLL))
|
||||
edit_scroll(BACKWARD);
|
||||
else
|
||||
edit_redraw(was_current, FLOWING);
|
||||
|
||||
if (scroll_only)
|
||||
edit_scroll(BACKWARD, 1);
|
||||
|
||||
edit_redraw(was_current, FLOWING);
|
||||
|
||||
/* <Up> should not change placewewant, so restore it. */
|
||||
openfile->placewewant = leftedge + target_column;
|
||||
/* <Up> should not change placewewant, so restore it. */
|
||||
openfile->placewewant = leftedge + target_column;
|
||||
}
|
||||
|
||||
/* Move the cursor to next line or chunk. If scroll_only is TRUE, also
|
||||
* scroll the screen one row, so the cursor stays in the same spot. */
|
||||
void do_down(bool scroll_only)
|
||||
/* Move the cursor to next line or chunk. */
|
||||
void do_down(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t leftedge, target_column;
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t leftedge, target_column;
|
||||
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
|
||||
/* If we can't move down one line or chunk, we're at bottom of file. */
|
||||
if (go_forward_chunks(1, &openfile->current, &leftedge) > 0)
|
||||
return;
|
||||
/* If we can't move down one line or chunk, we're at bottom of file. */
|
||||
if (go_forward_chunks(1, &openfile->current, &leftedge) > 0)
|
||||
return;
|
||||
|
||||
set_proper_index_and_pww(&leftedge, target_column, TRUE);
|
||||
set_proper_index_and_pww(&leftedge, target_column, TRUE);
|
||||
|
||||
if (scroll_only)
|
||||
edit_scroll(FORWARD, 1);
|
||||
if (openfile->current_y == editwinrows - 1 && ISSET(SMOOTH_SCROLL))
|
||||
edit_scroll(FORWARD);
|
||||
else
|
||||
edit_redraw(was_current, FLOWING);
|
||||
|
||||
edit_redraw(was_current, FLOWING);
|
||||
|
||||
/* <Down> should not change placewewant, so restore it. */
|
||||
openfile->placewewant = leftedge + target_column;
|
||||
/* <Down> should not change placewewant, so restore it. */
|
||||
openfile->placewewant = leftedge + target_column;
|
||||
}
|
||||
|
||||
/* Move up one line or chunk. */
|
||||
void do_up_void(void)
|
||||
{
|
||||
do_up(FALSE);
|
||||
}
|
||||
|
||||
/* Move down one line or chunk. */
|
||||
void do_down_void(void)
|
||||
{
|
||||
do_down(FALSE);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
#ifdef ENABLE_HELP
|
||||
/* Scroll up one line or chunk without scrolling the cursor. */
|
||||
void do_scroll_up(void)
|
||||
{
|
||||
do_up(TRUE);
|
||||
/* When the top of the file is onscreen, we can't scroll. */
|
||||
if (openfile->edittop->prev == NULL && openfile->firstcolumn == 0)
|
||||
return;
|
||||
|
||||
if (openfile->current_y == editwinrows - 1)
|
||||
do_up();
|
||||
|
||||
if (editwinrows > 1)
|
||||
edit_scroll(BACKWARD);
|
||||
}
|
||||
|
||||
/* Scroll down one line or chunk without scrolling the cursor. */
|
||||
void do_scroll_down(void)
|
||||
{
|
||||
do_down(TRUE);
|
||||
if (openfile->current_y == 0)
|
||||
do_down();
|
||||
|
||||
if (openfile->edittop->next != NULL
|
||||
#ifndef NANO_TINY
|
||||
|| chunk_for(openfile->firstcolumn, openfile->edittop) <
|
||||
number_of_chunks_in(openfile->edittop)
|
||||
#endif
|
||||
)
|
||||
edit_scroll(FORWARD);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Move left one character. */
|
||||
void do_left(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
filestruct *was_current = openfile->current;
|
||||
|
||||
if (openfile->current_x > 0)
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->fileage) {
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
}
|
||||
if (openfile->current_x > 0)
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->fileage) {
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
}
|
||||
|
||||
edit_redraw(was_current, FLOWING);
|
||||
edit_redraw(was_current, FLOWING);
|
||||
}
|
||||
|
||||
/* Move right one character. */
|
||||
void do_right(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
filestruct *was_current = openfile->current;
|
||||
|
||||
if (openfile->current->data[openfile->current_x] != '\0')
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
if (openfile->current->data[openfile->current_x] != '\0')
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
|
||||
edit_redraw(was_current, FLOWING);
|
||||
edit_redraw(was_current, FLOWING);
|
||||
}
|
||||
|
||||
3511
src/nano.c
3511
src/nano.c
File diff suppressed because it is too large
Load Diff
640
src/nano.h
640
src/nano.h
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* nano.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -111,7 +111,7 @@
|
||||
#endif
|
||||
#define gettext_noop(string) (string)
|
||||
#define N_(string) gettext_noop(string)
|
||||
/* Mark a string that will be sent to gettext() later. */
|
||||
/* Mark a string that will be sent to gettext() later. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -142,417 +142,431 @@
|
||||
#define REPLACING 1
|
||||
#define INREGION 2
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
#define USE_THE_DEFAULT -1
|
||||
#define BAD_COLOR -2
|
||||
#endif
|
||||
|
||||
/* Enumeration types. */
|
||||
typedef enum {
|
||||
NIX_FILE, DOS_FILE, MAC_FILE
|
||||
NIX_FILE, DOS_FILE, MAC_FILE
|
||||
} file_format;
|
||||
|
||||
typedef enum {
|
||||
HUSH, MILD, ALERT
|
||||
HUSH, MILD, ALERT
|
||||
} message_type;
|
||||
|
||||
typedef enum {
|
||||
OVERWRITE, APPEND, PREPEND
|
||||
OVERWRITE, APPEND, PREPEND
|
||||
} kind_of_writing_type;
|
||||
|
||||
typedef enum {
|
||||
SOFTMARK, HARDMARK
|
||||
SOFTMARK, HARDMARK
|
||||
} mark_type;
|
||||
|
||||
typedef enum {
|
||||
CENTERING, FLOWING, STATIONARY
|
||||
CENTERING, FLOWING, STATIONARY
|
||||
} update_type;
|
||||
|
||||
/* The kinds of undo actions. ADD...REPLACE must come first. */
|
||||
typedef enum {
|
||||
ADD, DEL, BACK, CUT, CUT_TO_EOF, REPLACE,
|
||||
ADD, ENTER, BACK, DEL, JOIN, REPLACE,
|
||||
#ifdef ENABLE_WRAPPING
|
||||
SPLIT_BEGIN, SPLIT_END,
|
||||
SPLIT_BEGIN, SPLIT_END,
|
||||
#endif
|
||||
INDENT, UNINDENT,
|
||||
INDENT, UNINDENT,
|
||||
#ifdef ENABLE_COMMENT
|
||||
COMMENT, UNCOMMENT, PREFLIGHT,
|
||||
COMMENT, UNCOMMENT, PREFLIGHT,
|
||||
#endif
|
||||
JOIN, PASTE, INSERT, ENTER, OTHER
|
||||
CUT, CUT_TO_EOF, PASTE, INSERT, OTHER
|
||||
} undo_type;
|
||||
|
||||
/* Structure types. */
|
||||
#ifdef ENABLE_COLOR
|
||||
typedef struct colortype {
|
||||
short fg;
|
||||
/* This syntax's foreground color. */
|
||||
short bg;
|
||||
/* This syntax's background color. */
|
||||
bool bright;
|
||||
/* Is this color A_BOLD? */
|
||||
int pairnum;
|
||||
/* The color pair number used for this foreground color and
|
||||
* background color. */
|
||||
int attributes;
|
||||
/* Pair number and brightness composed into ready-to-use attributes. */
|
||||
int rex_flags;
|
||||
/* The regex compilation flags (with or without REG_ICASE). */
|
||||
char *start_regex;
|
||||
/* The start (or all) of the regex string. */
|
||||
regex_t *start;
|
||||
/* The compiled start (or all) of the regex string. */
|
||||
char *end_regex;
|
||||
/* The end (if any) of the regex string. */
|
||||
regex_t *end;
|
||||
/* The compiled end (if any) of the regex string. */
|
||||
struct colortype *next;
|
||||
/* Next set of colors. */
|
||||
int id;
|
||||
/* Basic id for assigning to lines later. */
|
||||
short fg;
|
||||
/* This syntax's foreground color. */
|
||||
short bg;
|
||||
/* This syntax's background color. */
|
||||
bool bright;
|
||||
/* Is this color A_BOLD? */
|
||||
int pairnum;
|
||||
/* The color pair number used for this foreground color and
|
||||
* background color. */
|
||||
int attributes;
|
||||
/* Pair number and brightness composed into ready-to-use attributes. */
|
||||
int rex_flags;
|
||||
/* The regex compilation flags (with or without REG_ICASE). */
|
||||
char *start_regex;
|
||||
/* The start (or all) of the regex string. */
|
||||
regex_t *start;
|
||||
/* The compiled start (or all) of the regex string. */
|
||||
char *end_regex;
|
||||
/* The end (if any) of the regex string. */
|
||||
regex_t *end;
|
||||
/* The compiled end (if any) of the regex string. */
|
||||
struct colortype *next;
|
||||
/* Next set of colors. */
|
||||
int id;
|
||||
/* Basic id for assigning to lines later. */
|
||||
} colortype;
|
||||
|
||||
typedef struct regexlisttype {
|
||||
char *full_regex;
|
||||
/* A regex string to match things that imply a certain syntax. */
|
||||
struct regexlisttype *next;
|
||||
/* The next regex. */
|
||||
char *full_regex;
|
||||
/* A regex string to match things that imply a certain syntax. */
|
||||
struct regexlisttype *next;
|
||||
/* The next regex. */
|
||||
} regexlisttype;
|
||||
|
||||
typedef struct syntaxtype {
|
||||
char *name;
|
||||
/* The name of this syntax. */
|
||||
regexlisttype *extensions;
|
||||
/* The list of extensions that this syntax applies to. */
|
||||
regexlisttype *headers;
|
||||
/* The list of headerlines that this syntax applies to. */
|
||||
regexlisttype *magics;
|
||||
/* The list of libmagic results that this syntax applies to. */
|
||||
char *linter;
|
||||
/* The command with which to lint this type of file. */
|
||||
char *formatter;
|
||||
/* The formatting command (for programming languages mainly). */
|
||||
char *name;
|
||||
/* The name of this syntax. */
|
||||
regexlisttype *extensions;
|
||||
/* The list of extensions that this syntax applies to. */
|
||||
regexlisttype *headers;
|
||||
/* The list of headerlines that this syntax applies to. */
|
||||
regexlisttype *magics;
|
||||
/* The list of libmagic results that this syntax applies to. */
|
||||
char *linter;
|
||||
/* The command with which to lint this type of file. */
|
||||
char *formatter;
|
||||
/* The formatting command (for programming languages mainly). */
|
||||
#ifdef ENABLE_COMMENT
|
||||
char *comment;
|
||||
/* The line comment prefix (and postfix) for this type of file. */
|
||||
char *comment;
|
||||
/* The line comment prefix (and postfix) for this type of file. */
|
||||
#endif
|
||||
colortype *color;
|
||||
/* The colors and their regexes used in this syntax. */
|
||||
int nmultis;
|
||||
/* How many multiline regex strings this syntax has. */
|
||||
struct syntaxtype *next;
|
||||
/* Next syntax. */
|
||||
colortype *color;
|
||||
/* The colors and their regexes used in this syntax. */
|
||||
int nmultis;
|
||||
/* How many multiline regex strings this syntax has. */
|
||||
struct syntaxtype *next;
|
||||
/* Next syntax. */
|
||||
} syntaxtype;
|
||||
|
||||
typedef struct lintstruct {
|
||||
ssize_t lineno;
|
||||
/* Line number of the error. */
|
||||
ssize_t colno;
|
||||
/* Column # of the error. */
|
||||
char *msg;
|
||||
/* Error message text. */
|
||||
char *filename;
|
||||
/* Filename. */
|
||||
struct lintstruct *next;
|
||||
/* Next error. */
|
||||
struct lintstruct *prev;
|
||||
/* Previous error. */
|
||||
ssize_t lineno;
|
||||
/* Line number of the error. */
|
||||
ssize_t colno;
|
||||
/* Column # of the error. */
|
||||
char *msg;
|
||||
/* Error message text. */
|
||||
char *filename;
|
||||
/* Filename. */
|
||||
struct lintstruct *next;
|
||||
/* Next error. */
|
||||
struct lintstruct *prev;
|
||||
/* Previous error. */
|
||||
} lintstruct;
|
||||
|
||||
/* Flags that indicate how a multiline regex applies to a line. */
|
||||
#define CNONE (1<<1)
|
||||
/* Yay, regex doesn't apply to this line at all! */
|
||||
#define CBEGINBEFORE (1<<2)
|
||||
/* Regex starts on an earlier line, ends on this one. */
|
||||
#define CENDAFTER (1<<3)
|
||||
/* Regex starts on this line and ends on a later one. */
|
||||
#define CWHOLELINE (1<<4)
|
||||
/* Whole line engulfed by the regex, start < me, end > me. */
|
||||
#define CSTARTENDHERE (1<<5)
|
||||
/* Regex starts and ends within this line. */
|
||||
#define CWOULDBE (1<<6)
|
||||
/* An unpaired start match on or before this line. */
|
||||
#define CNONE (1<<1)
|
||||
/* Yay, regex doesn't apply to this line at all! */
|
||||
#define CBEGINBEFORE (1<<2)
|
||||
/* Regex starts on an earlier line, ends on this one. */
|
||||
#define CENDAFTER (1<<3)
|
||||
/* Regex starts on this line and ends on a later one. */
|
||||
#define CWHOLELINE (1<<4)
|
||||
/* Whole line engulfed by the regex, start < me, end > me. */
|
||||
#define CSTARTENDHERE (1<<5)
|
||||
/* Regex starts and ends within this line. */
|
||||
#define CWOULDBE (1<<6)
|
||||
/* An unpaired start match on or before this line. */
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* More structure types. */
|
||||
typedef struct filestruct {
|
||||
char *data;
|
||||
/* The text of this line. */
|
||||
ssize_t lineno;
|
||||
/* The number of this line. */
|
||||
struct filestruct *next;
|
||||
/* Next node. */
|
||||
struct filestruct *prev;
|
||||
/* Previous node. */
|
||||
char *data;
|
||||
/* The text of this line. */
|
||||
ssize_t lineno;
|
||||
/* The number of this line. */
|
||||
struct filestruct *next;
|
||||
/* Next node. */
|
||||
struct filestruct *prev;
|
||||
/* Previous node. */
|
||||
#ifdef ENABLE_COLOR
|
||||
short *multidata;
|
||||
/* Array of which multi-line regexes apply to this line. */
|
||||
short *multidata;
|
||||
/* Array of which multi-line regexes apply to this line. */
|
||||
#endif
|
||||
} filestruct;
|
||||
|
||||
typedef struct partition {
|
||||
filestruct *fileage;
|
||||
/* The top line of this portion of the file. */
|
||||
filestruct *top_prev;
|
||||
/* The line before the top line of this portion of the file. */
|
||||
char *top_data;
|
||||
/* The text before the beginning of the top line of this portion
|
||||
* of the file. */
|
||||
filestruct *filebot;
|
||||
/* The bottom line of this portion of the file. */
|
||||
filestruct *bot_next;
|
||||
/* The line after the bottom line of this portion of the
|
||||
* file. */
|
||||
char *bot_data;
|
||||
/* The text after the end of the bottom line of this portion of
|
||||
* the file. */
|
||||
filestruct *fileage;
|
||||
/* The top line of this portion of the file. */
|
||||
filestruct *top_prev;
|
||||
/* The line before the top line of this portion of the file. */
|
||||
char *top_data;
|
||||
/* The text before the beginning of the top line of this portion
|
||||
* of the file. */
|
||||
filestruct *filebot;
|
||||
/* The bottom line of this portion of the file. */
|
||||
filestruct *bot_next;
|
||||
/* The line after the bottom line of this portion of the
|
||||
* file. */
|
||||
char *bot_data;
|
||||
/* The text after the end of the bottom line of this portion of
|
||||
* the file. */
|
||||
} partition;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct undo_group {
|
||||
ssize_t top_line;
|
||||
/* First line of group. */
|
||||
ssize_t bottom_line;
|
||||
/* Last line of group. */
|
||||
char **indentations;
|
||||
/* String data used to restore the affected lines; one per line. */
|
||||
struct undo_group *next;
|
||||
ssize_t top_line;
|
||||
/* First line of group. */
|
||||
ssize_t bottom_line;
|
||||
/* Last line of group. */
|
||||
char **indentations;
|
||||
/* String data used to restore the affected lines; one per line. */
|
||||
struct undo_group *next;
|
||||
} undo_group;
|
||||
|
||||
typedef struct undo {
|
||||
ssize_t lineno;
|
||||
undo_type type;
|
||||
/* What type of undo this was. */
|
||||
size_t begin;
|
||||
/* Where did this action begin or end. */
|
||||
char *strdata;
|
||||
/* String type data we will use for copying the affected line back. */
|
||||
size_t wassize;
|
||||
/* The file size before the action. */
|
||||
size_t newsize;
|
||||
/* The file size after the action. */
|
||||
int xflags;
|
||||
/* Some flag data we need. */
|
||||
undo_group *grouping;
|
||||
/* Undo info specific to groups of lines. */
|
||||
ssize_t lineno;
|
||||
undo_type type;
|
||||
/* What type of undo this was. */
|
||||
size_t begin;
|
||||
/* Where did this action begin or end. */
|
||||
char *strdata;
|
||||
/* String type data we will use for copying the affected line back. */
|
||||
size_t wassize;
|
||||
/* The file size before the action. */
|
||||
size_t newsize;
|
||||
/* The file size after the action. */
|
||||
int xflags;
|
||||
/* Some flag data we need. */
|
||||
undo_group *grouping;
|
||||
/* Undo info specific to groups of lines. */
|
||||
|
||||
/* Cut-specific stuff we need. */
|
||||
filestruct *cutbuffer;
|
||||
/* Copy of the cutbuffer. */
|
||||
filestruct *cutbottom;
|
||||
/* Copy of cutbottom. */
|
||||
ssize_t mark_begin_lineno;
|
||||
/* Mostly the line number of the current line; sometimes something else. */
|
||||
size_t mark_begin_x;
|
||||
/* The x position corresponding to the above line number. */
|
||||
struct undo *next;
|
||||
/* A pointer to the undo item of the preceding action. */
|
||||
/* Cut-specific stuff we need. */
|
||||
filestruct *cutbuffer;
|
||||
/* Copy of the cutbuffer. */
|
||||
filestruct *cutbottom;
|
||||
/* Copy of cutbottom. */
|
||||
ssize_t mark_begin_lineno;
|
||||
/* Mostly the line number of the current line; sometimes something else. */
|
||||
size_t mark_begin_x;
|
||||
/* The x position corresponding to the above line number. */
|
||||
struct undo *next;
|
||||
/* A pointer to the undo item of the preceding action. */
|
||||
} undo;
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
typedef struct poshiststruct {
|
||||
char *filename;
|
||||
/* The file. */
|
||||
ssize_t lineno;
|
||||
/* Line number we left off on. */
|
||||
ssize_t xno;
|
||||
/* x position in the file we left off on. */
|
||||
struct poshiststruct *next;
|
||||
char *filename;
|
||||
/* The file. */
|
||||
ssize_t lineno;
|
||||
/* Line number we left off on. */
|
||||
ssize_t xno;
|
||||
/* x position in the file we left off on. */
|
||||
struct poshiststruct *next;
|
||||
} poshiststruct;
|
||||
#endif
|
||||
|
||||
typedef struct openfilestruct {
|
||||
char *filename;
|
||||
/* The file's name. */
|
||||
filestruct *fileage;
|
||||
/* The file's first line. */
|
||||
filestruct *filebot;
|
||||
/* The file's last line. */
|
||||
filestruct *edittop;
|
||||
/* The current top of the edit window for this file. */
|
||||
filestruct *current;
|
||||
/* The current line for this file. */
|
||||
size_t totsize;
|
||||
/* The file's total number of characters. */
|
||||
size_t firstcolumn;
|
||||
/* The starting column of the top line of the edit window.
|
||||
* When not in softwrap mode, it's always zero. */
|
||||
size_t current_x;
|
||||
/* The file's x-coordinate position. */
|
||||
size_t placewewant;
|
||||
/* The file's x position we would like. */
|
||||
ssize_t current_y;
|
||||
/* The file's y-coordinate position. */
|
||||
bool modified;
|
||||
/* Whether the file has been modified. */
|
||||
struct stat *current_stat;
|
||||
/* The file's current stat information. */
|
||||
char *filename;
|
||||
/* The file's name. */
|
||||
filestruct *fileage;
|
||||
/* The file's first line. */
|
||||
filestruct *filebot;
|
||||
/* The file's last line. */
|
||||
filestruct *edittop;
|
||||
/* The current top of the edit window for this file. */
|
||||
filestruct *current;
|
||||
/* The current line for this file. */
|
||||
size_t totsize;
|
||||
/* The file's total number of characters. */
|
||||
size_t firstcolumn;
|
||||
/* The starting column of the top line of the edit window.
|
||||
* When not in softwrap mode, it's always zero. */
|
||||
size_t current_x;
|
||||
/* The file's x-coordinate position. */
|
||||
size_t placewewant;
|
||||
/* The file's x position we would like. */
|
||||
ssize_t current_y;
|
||||
/* The file's y-coordinate position. */
|
||||
bool modified;
|
||||
/* Whether the file has been modified. */
|
||||
struct stat *current_stat;
|
||||
/* The file's current stat information. */
|
||||
#ifndef NANO_TINY
|
||||
bool mark_set;
|
||||
/* Whether the mark is on in this file. */
|
||||
filestruct *mark_begin;
|
||||
/* The file's line where the mark is, if any. */
|
||||
size_t mark_begin_x;
|
||||
/* The file's mark's x-coordinate position, if any. */
|
||||
mark_type kind_of_mark;
|
||||
/* Whether this is a soft or a hard mark. */
|
||||
file_format fmt;
|
||||
/* The file's format. */
|
||||
undo *undotop;
|
||||
/* The top of the undo list. */
|
||||
undo *current_undo;
|
||||
/* The current (i.e. next) level of undo. */
|
||||
undo_type last_action;
|
||||
/* The type of the last action the user performed. */
|
||||
char *lock_filename;
|
||||
/* The path of the lockfile, if we created one. */
|
||||
filestruct *mark;
|
||||
/* The line in the file where the mark is set; NULL if not set. */
|
||||
size_t mark_x;
|
||||
/* The mark's x position in the above line. */
|
||||
mark_type kind_of_mark;
|
||||
/* Whether it is a soft (with Shift) or a hard mark. */
|
||||
file_format fmt;
|
||||
/* The file's format -- Unix or DOS or Mac or mixed. */
|
||||
undo *undotop;
|
||||
/* The top of the undo list. */
|
||||
undo *current_undo;
|
||||
/* The current (i.e. next) level of undo. */
|
||||
undo *last_saved;
|
||||
/* The undo item at which the file was last saved. */
|
||||
undo_type last_action;
|
||||
/* The type of the last action the user performed. */
|
||||
char *lock_filename;
|
||||
/* The path of the lockfile, if we created one. */
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
syntaxtype *syntax;
|
||||
/* The syntax struct for this file, if any. */
|
||||
colortype *colorstrings;
|
||||
/* The file's associated colors. */
|
||||
syntaxtype *syntax;
|
||||
/* The syntax struct for this file, if any. */
|
||||
colortype *colorstrings;
|
||||
/* The file's associated colors. */
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
struct openfilestruct *next;
|
||||
/* The next open file, if any. */
|
||||
struct openfilestruct *prev;
|
||||
/* The preceding open file, if any. */
|
||||
#endif
|
||||
struct openfilestruct *next;
|
||||
/* The next open file, if any. */
|
||||
struct openfilestruct *prev;
|
||||
/* The preceding open file, if any. */
|
||||
} openfilestruct;
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
typedef struct rcoption {
|
||||
const char *name;
|
||||
/* The name of the rcfile option. */
|
||||
long flag;
|
||||
/* The flag associated with it, if any. */
|
||||
const char *name;
|
||||
/* The name of the rcfile option. */
|
||||
long flag;
|
||||
/* The flag associated with it, if any. */
|
||||
} rcoption;
|
||||
#endif
|
||||
|
||||
typedef struct sc {
|
||||
const char *keystr;
|
||||
/* The string that describes a 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;
|
||||
/* Which menus this applies to. */
|
||||
void (*scfunc)(void);
|
||||
/* The function we're going to run. */
|
||||
const char *keystr;
|
||||
/* The string that describes a 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;
|
||||
/* Which menus this applies to. */
|
||||
void (*func)(void);
|
||||
/* The function we're going to run. */
|
||||
#ifndef NANO_TINY
|
||||
int toggle;
|
||||
/* If a toggle, what we're toggling. */
|
||||
int ordinal;
|
||||
/* The how-manieth toggle this is, in order to be able to
|
||||
* keep them in sequence. */
|
||||
int toggle;
|
||||
/* If a toggle, what we're toggling. */
|
||||
int ordinal;
|
||||
/* The how-manieth toggle this is, in order to be able to
|
||||
* keep them in sequence. */
|
||||
#endif
|
||||
struct sc *next;
|
||||
/* Next in the list. */
|
||||
#ifdef ENABLE_NANORC
|
||||
char *expansion;
|
||||
/* The string of keycodes to which this shortcut is expanded. */
|
||||
#endif
|
||||
struct sc *next;
|
||||
/* Next in the list. */
|
||||
} sc;
|
||||
|
||||
typedef struct subnfunc {
|
||||
void (*scfunc)(void);
|
||||
/* The actual function to call. */
|
||||
int menus;
|
||||
/* In what menus this function applies. */
|
||||
const char *desc;
|
||||
/* The function's short description, for example "Where Is". */
|
||||
void (*func)(void);
|
||||
/* The actual function to call. */
|
||||
int menus;
|
||||
/* In what menus this function applies. */
|
||||
const char *desc;
|
||||
/* The function's short description, for example "Where Is". */
|
||||
#ifdef ENABLE_HELP
|
||||
const char *help;
|
||||
/* The help-screen text for this function. */
|
||||
bool blank_after;
|
||||
/* Whether there should be a blank line after the help text
|
||||
* for this function. */
|
||||
const char *help;
|
||||
/* The help-screen text for this function. */
|
||||
bool blank_after;
|
||||
/* Whether there should be a blank line after the help text
|
||||
* for this function. */
|
||||
#endif
|
||||
bool viewok;
|
||||
/* Is this function allowed when in view mode? */
|
||||
long toggle;
|
||||
/* If this is a toggle, which toggle to affect. */
|
||||
struct subnfunc *next;
|
||||
/* Next item in the list. */
|
||||
bool viewok;
|
||||
/* Is this function allowed when in view mode? */
|
||||
long toggle;
|
||||
/* If this is a toggle, which toggle to affect. */
|
||||
struct subnfunc *next;
|
||||
/* Next item in the list. */
|
||||
} subnfunc;
|
||||
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
typedef struct completion_word {
|
||||
char *word;
|
||||
struct completion_word *next;
|
||||
char *word;
|
||||
struct completion_word *next;
|
||||
} completion_word;
|
||||
#endif
|
||||
|
||||
/* The elements of the interface that can be colored differently. */
|
||||
enum
|
||||
{
|
||||
TITLE_BAR = 0,
|
||||
LINE_NUMBER,
|
||||
SELECTED_TEXT,
|
||||
STATUS_BAR,
|
||||
KEY_COMBO,
|
||||
FUNCTION_TAG,
|
||||
NUMBER_OF_ELEMENTS
|
||||
TITLE_BAR = 0,
|
||||
LINE_NUMBER,
|
||||
SELECTED_TEXT,
|
||||
STATUS_BAR,
|
||||
ERROR_MESSAGE,
|
||||
KEY_COMBO,
|
||||
FUNCTION_TAG,
|
||||
NUMBER_OF_ELEMENTS
|
||||
};
|
||||
|
||||
/* Enumeration used in the flags array. See the definition of FLAGMASK. */
|
||||
enum
|
||||
{
|
||||
DONTUSE,
|
||||
CASE_SENSITIVE,
|
||||
CONSTANT_SHOW,
|
||||
NO_HELP,
|
||||
SUSPEND,
|
||||
NO_WRAP,
|
||||
AUTOINDENT,
|
||||
VIEW_MODE,
|
||||
USE_MOUSE,
|
||||
USE_REGEXP,
|
||||
TEMP_FILE,
|
||||
CUT_FROM_CURSOR,
|
||||
BACKWARDS_SEARCH,
|
||||
MULTIBUFFER,
|
||||
SMOOTH_SCROLL,
|
||||
REBIND_DELETE,
|
||||
REBIND_KEYPAD,
|
||||
NO_CONVERT,
|
||||
BACKUP_FILE,
|
||||
INSECURE_BACKUP,
|
||||
NO_COLOR_SYNTAX,
|
||||
PRESERVE,
|
||||
HISTORYLOG,
|
||||
RESTRICTED,
|
||||
SMART_HOME,
|
||||
WHITESPACE_DISPLAY,
|
||||
MORE_SPACE,
|
||||
TABS_TO_SPACES,
|
||||
QUICK_BLANK,
|
||||
WORD_BOUNDS,
|
||||
NO_NEWLINES,
|
||||
BOLD_TEXT,
|
||||
QUIET,
|
||||
SOFTWRAP,
|
||||
POS_HISTORY,
|
||||
LOCKING,
|
||||
NOREAD_MODE,
|
||||
MAKE_IT_UNIX,
|
||||
JUSTIFY_TRIM,
|
||||
SHOW_CURSOR,
|
||||
LINE_NUMBERS,
|
||||
NO_PAUSES,
|
||||
AT_BLANKS
|
||||
DONTUSE,
|
||||
CASE_SENSITIVE,
|
||||
CONSTANT_SHOW,
|
||||
NO_HELP,
|
||||
SUSPEND,
|
||||
NO_WRAP,
|
||||
AUTOINDENT,
|
||||
VIEW_MODE,
|
||||
USE_MOUSE,
|
||||
USE_REGEXP,
|
||||
TEMP_FILE,
|
||||
CUT_FROM_CURSOR,
|
||||
BACKWARDS_SEARCH,
|
||||
MULTIBUFFER,
|
||||
SMOOTH_SCROLL,
|
||||
REBIND_DELETE,
|
||||
REBIND_KEYPAD,
|
||||
NO_CONVERT,
|
||||
BACKUP_FILE,
|
||||
INSECURE_BACKUP,
|
||||
NO_COLOR_SYNTAX,
|
||||
PRESERVE,
|
||||
HISTORYLOG,
|
||||
RESTRICTED,
|
||||
SMART_HOME,
|
||||
WHITESPACE_DISPLAY,
|
||||
MORE_SPACE,
|
||||
TABS_TO_SPACES,
|
||||
QUICK_BLANK,
|
||||
WORD_BOUNDS,
|
||||
NO_NEWLINES,
|
||||
BOLD_TEXT,
|
||||
QUIET,
|
||||
SOFTWRAP,
|
||||
POS_HISTORY,
|
||||
LOCKING,
|
||||
NOREAD_MODE,
|
||||
MAKE_IT_UNIX,
|
||||
TRIM_BLANKS,
|
||||
SHOW_CURSOR,
|
||||
LINE_NUMBERS,
|
||||
NO_PAUSES,
|
||||
AT_BLANKS,
|
||||
AFTER_ENDS
|
||||
};
|
||||
|
||||
/* Flags for the menus in which a given function should be present. */
|
||||
#define MMAIN (1<<0)
|
||||
#define MWHEREIS (1<<1)
|
||||
#define MREPLACE (1<<2)
|
||||
#define MREPLACEWITH (1<<3)
|
||||
#define MGOTOLINE (1<<4)
|
||||
#define MWRITEFILE (1<<5)
|
||||
#define MINSERTFILE (1<<6)
|
||||
#define MEXTCMD (1<<7)
|
||||
#define MHELP (1<<8)
|
||||
#define MSPELL (1<<9)
|
||||
#define MBROWSER (1<<10)
|
||||
#define MWHEREISFILE (1<<11)
|
||||
#define MGOTODIR (1<<12)
|
||||
#define MYESNO (1<<13)
|
||||
#define MLINTER (1<<14)
|
||||
#define MFINDINHELP (1<<15)
|
||||
#define MMAIN (1<<0)
|
||||
#define MWHEREIS (1<<1)
|
||||
#define MREPLACE (1<<2)
|
||||
#define MREPLACEWITH (1<<3)
|
||||
#define MGOTOLINE (1<<4)
|
||||
#define MWRITEFILE (1<<5)
|
||||
#define MINSERTFILE (1<<6)
|
||||
#define MEXTCMD (1<<7)
|
||||
#define MHELP (1<<8)
|
||||
#define MSPELL (1<<9)
|
||||
#define MBROWSER (1<<10)
|
||||
#define MWHEREISFILE (1<<11)
|
||||
#define MGOTODIR (1<<12)
|
||||
#define MYESNO (1<<13)
|
||||
#define MLINTER (1<<14)
|
||||
#define MFINDINHELP (1<<15)
|
||||
/* This is an abbreviation for all menus except Help and YesNo. */
|
||||
#define MMOST (MMAIN|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE|MWRITEFILE|MINSERTFILE|\
|
||||
MEXTCMD|MBROWSER|MWHEREISFILE|MGOTODIR|MFINDINHELP|MSPELL|MLINTER)
|
||||
MEXTCMD|MBROWSER|MWHEREISFILE|MGOTODIR|MFINDINHELP|MSPELL|MLINTER)
|
||||
#ifndef NANO_TINY
|
||||
#define MSOME MMOST
|
||||
#else
|
||||
@@ -589,6 +603,7 @@ enum
|
||||
#define SHIFT_END 0x456
|
||||
#define SHIFT_PAGEUP 0x457
|
||||
#define SHIFT_PAGEDOWN 0x458
|
||||
#define SHIFT_TAB 0x45F
|
||||
|
||||
#ifdef USE_SLANG
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -604,11 +619,12 @@ enum
|
||||
#define KEY_WINCH -2
|
||||
|
||||
/* Some extra flags for the undo function. */
|
||||
#define WAS_FINAL_BACKSPACE (1<<1)
|
||||
#define WAS_WHOLE_LINE (1<<2)
|
||||
#define WAS_FINAL_BACKSPACE (1<<1)
|
||||
#define WAS_WHOLE_LINE (1<<2)
|
||||
#define WAS_FINAL_LINE (1<<3)
|
||||
/* The flags for the mark need to be the highest. */
|
||||
#define MARK_WAS_SET (1<<3)
|
||||
#define WAS_MARKED_FORWARD (1<<4)
|
||||
#define MARK_WAS_SET (1<<4)
|
||||
#define WAS_MARKED_FORWARD (1<<5)
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* The maximum number of entries displayed in the main shortcut list. */
|
||||
|
||||
1069
src/prompt.c
1069
src/prompt.c
File diff suppressed because it is too large
Load Diff
139
src/proto.h
139
src/proto.h
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* proto.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 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 *
|
||||
@@ -30,7 +30,7 @@ extern volatile sig_atomic_t the_window_resized;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
extern bool console;
|
||||
extern bool on_a_vt;
|
||||
#endif
|
||||
|
||||
extern bool meta_key;
|
||||
@@ -40,13 +40,6 @@ extern bool focusing;
|
||||
|
||||
extern bool as_an_at;
|
||||
|
||||
extern int margin;
|
||||
extern int editwincols;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
extern bool have_palette;
|
||||
#endif
|
||||
|
||||
extern bool suppress_cursorpos;
|
||||
|
||||
extern message_type lastmessage;
|
||||
@@ -58,6 +51,8 @@ extern char *title;
|
||||
|
||||
extern bool more_than_one;
|
||||
|
||||
extern bool also_the_last;
|
||||
|
||||
extern int didfind;
|
||||
|
||||
extern int controlleft;
|
||||
@@ -93,10 +88,13 @@ extern char *last_search;
|
||||
extern char *present_path;
|
||||
|
||||
extern unsigned flags[4];
|
||||
|
||||
extern WINDOW *topwin;
|
||||
extern WINDOW *edit;
|
||||
extern WINDOW *bottomwin;
|
||||
extern int editwinrows;
|
||||
extern int editwincols;
|
||||
extern int margin;
|
||||
|
||||
extern filestruct *cutbuffer;
|
||||
extern filestruct *cutbottom;
|
||||
@@ -106,9 +104,6 @@ extern openfilestruct *firstfile;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern char *matchbrackets;
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern char *whitespace;
|
||||
extern int whitespace_len[2];
|
||||
#endif
|
||||
@@ -124,7 +119,7 @@ extern char *quotestr;
|
||||
extern regex_t quotereg;
|
||||
extern int quoterc;
|
||||
extern char *quoteerr;
|
||||
#endif /* !ENABLE_JUSTIFY */
|
||||
#endif
|
||||
|
||||
extern char *word_chars;
|
||||
|
||||
@@ -148,6 +143,7 @@ extern char *alt_speller;
|
||||
#ifdef ENABLE_COLOR
|
||||
extern syntaxtype *syntaxes;
|
||||
extern char *syntaxstr;
|
||||
extern bool have_palette;
|
||||
#endif
|
||||
|
||||
extern bool refresh_needed;
|
||||
@@ -176,7 +172,7 @@ extern regmatch_t regmatches[10];
|
||||
|
||||
extern int hilite_attribute;
|
||||
#ifdef ENABLE_COLOR
|
||||
extern char* specified_color_combo[NUMBER_OF_ELEMENTS];
|
||||
extern colortype *color_combo[NUMBER_OF_ELEMENTS];
|
||||
#endif
|
||||
extern int interface_color_pair[NUMBER_OF_ELEMENTS];
|
||||
|
||||
@@ -195,8 +191,8 @@ void browser_refresh(void);
|
||||
void browser_select_dirname(const char *needle);
|
||||
void do_filesearch(void);
|
||||
void do_fileresearch(bool forwards);
|
||||
void do_first_file(void);
|
||||
void do_last_file(void);
|
||||
void to_first_file(void);
|
||||
void to_last_file(void);
|
||||
char *strip_last_component(const char *path);
|
||||
#endif
|
||||
|
||||
@@ -222,10 +218,8 @@ size_t move_mbright(const char *buf, size_t pos);
|
||||
int mbstrcasecmp(const char *s1, const char *s2);
|
||||
int mbstrncasecmp(const char *s1, const char *s2, size_t n);
|
||||
char *mbstrcasestr(const char *haystack, const char *needle);
|
||||
char *revstrstr(const char *haystack, const char *needle,
|
||||
const char *index);
|
||||
char *mbrevstrcasestr(const char *haystack, const char *needle,
|
||||
const char *index);
|
||||
char *revstrstr(const char *haystack, const char *needle, const char *index);
|
||||
char *mbrevstrcasestr(const char *haystack, const char *needle, const char *index);
|
||||
size_t mbstrlen(const char *s);
|
||||
size_t mbstrnlen(const char *s, size_t maxlen);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
|
||||
@@ -272,12 +266,13 @@ void do_uncut_text(void);
|
||||
|
||||
/* Most functions in files.c. */
|
||||
void initialize_buffer_text(void);
|
||||
bool open_buffer(const char *filename, bool undoable);
|
||||
void set_modified(void);
|
||||
bool open_buffer(const char *filename, bool new_buffer);
|
||||
#ifdef ENABLE_SPELLER
|
||||
void replace_buffer(const char *filename);
|
||||
#ifndef NANO_TINY
|
||||
void replace_marked_buffer(const char *filename, filestruct *top, size_t top_x,
|
||||
filestruct *bot, size_t bot_x);
|
||||
filestruct *bot, size_t bot_x);
|
||||
#endif
|
||||
#endif
|
||||
void prepare_for_display(void);
|
||||
@@ -286,8 +281,7 @@ void switch_to_prev_buffer(void);
|
||||
void switch_to_next_buffer(void);
|
||||
bool close_buffer(void);
|
||||
#endif
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable,
|
||||
bool checkwritable);
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable);
|
||||
int open_file(const char *filename, bool newfie, bool quiet, FILE **f);
|
||||
char *get_next_filename(const char *name, const char *suffix);
|
||||
void do_insertfile_void(void);
|
||||
@@ -304,10 +298,10 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
#endif
|
||||
int copy_file(FILE *inn, FILE *out, bool close_out);
|
||||
bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
kind_of_writing_type method, bool nonamechange);
|
||||
kind_of_writing_type method, bool fullbuffer);
|
||||
#ifndef NANO_TINY
|
||||
bool write_marked_file(const char *name, FILE *f_open, bool tmp,
|
||||
kind_of_writing_type method);
|
||||
kind_of_writing_type method);
|
||||
#endif
|
||||
int do_writeout(bool exiting, bool withprompt);
|
||||
void do_writeout_void(void);
|
||||
@@ -315,11 +309,10 @@ void do_savefile(void);
|
||||
char *real_dir_from_tilde(const char *buf);
|
||||
#if defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
|
||||
int diralphasort(const void *va, const void *vb);
|
||||
void free_chararray(char **array, size_t len);
|
||||
#endif
|
||||
#ifdef ENABLE_TABCOMP
|
||||
char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
bool *lastwastab, void (*refresh_func)(void), bool *listed);
|
||||
bool *lastwastab, void (*refresh_func)(void), bool *listed);
|
||||
#endif
|
||||
|
||||
/* Some functions in global.c. */
|
||||
@@ -374,8 +367,8 @@ bool has_old_position(const char *file, ssize_t *line, ssize_t *column);
|
||||
#endif
|
||||
|
||||
/* Most functions in move.c. */
|
||||
void do_first_line(void);
|
||||
void do_last_line(void);
|
||||
void to_first_line(void);
|
||||
void to_last_line(void);
|
||||
void do_page_up(void);
|
||||
void do_page_down(void);
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
@@ -387,16 +380,14 @@ void do_para_end_void(void);
|
||||
void do_prev_block(void);
|
||||
void do_next_block(void);
|
||||
void do_prev_word(bool allow_punct, bool update_screen);
|
||||
bool do_next_word(bool allow_punct, bool update_screen);
|
||||
bool do_next_word(bool after_ends, bool allow_punct, bool update_screen);
|
||||
void do_prev_word_void(void);
|
||||
void do_next_word_void(void);
|
||||
void do_home(void);
|
||||
void do_end(void);
|
||||
void do_up(bool scroll_only);
|
||||
void do_down(bool scroll_only);
|
||||
void do_up_void(void);
|
||||
void do_down_void(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_up(void);
|
||||
void do_down(void);
|
||||
#ifdef ENABLE_HELP
|
||||
void do_scroll_up(void);
|
||||
void do_scroll_down(void);
|
||||
#endif
|
||||
@@ -410,17 +401,19 @@ void unlink_node(filestruct *fileptr);
|
||||
void delete_node(filestruct *fileptr);
|
||||
filestruct *copy_filestruct(const filestruct *src);
|
||||
void free_filestruct(filestruct *src);
|
||||
void renumber(filestruct *fileptr);
|
||||
void renumber(filestruct *line);
|
||||
partition *partition_filestruct(filestruct *top, size_t top_x,
|
||||
filestruct *bot, size_t bot_x);
|
||||
filestruct *bot, size_t bot_x);
|
||||
void unpartition_filestruct(partition **p);
|
||||
void extract_buffer(filestruct **file_top, filestruct **file_bot,
|
||||
filestruct *top, size_t top_x, filestruct *bot, size_t bot_x);
|
||||
filestruct *top, size_t top_x, filestruct *bot, size_t bot_x);
|
||||
void ingraft_buffer(filestruct *somebuffer);
|
||||
void copy_from_buffer(filestruct *somebuffer);
|
||||
openfilestruct *make_new_opennode(void);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void unlink_opennode(openfilestruct *fileptr);
|
||||
void delete_opennode(openfilestruct *fileptr);
|
||||
#endif
|
||||
void print_view_warning(void);
|
||||
void show_restricted_warning(void);
|
||||
#ifndef ENABLE_HELP
|
||||
@@ -428,11 +421,14 @@ void say_there_is_no_help(void);
|
||||
#endif
|
||||
void finish(void);
|
||||
void die(const char *msg, ...);
|
||||
void die_save_file(const char *die_filename, struct stat *die_stat);
|
||||
void emergency_save(const char *die_filename, struct stat *die_stat);
|
||||
void window_init(void);
|
||||
void do_exit(void);
|
||||
void close_and_go(void);
|
||||
RETSIGTYPE handle_hupterm(int signal);
|
||||
#ifndef DEBUG
|
||||
RETSIGTYPE handle_crash(int signal);
|
||||
#endif
|
||||
RETSIGTYPE do_suspend(int signal);
|
||||
RETSIGTYPE do_continue(int signal);
|
||||
#ifndef NANO_TINY
|
||||
@@ -440,25 +436,18 @@ RETSIGTYPE handle_sigwinch(int signal);
|
||||
void regenerate_screen(void);
|
||||
void allow_sigwinch(bool allow);
|
||||
void do_toggle(int flag);
|
||||
void do_toggle_void(void);
|
||||
void enable_signals(void);
|
||||
#endif
|
||||
void disable_flow_control(void);
|
||||
void enable_flow_control(void);
|
||||
void terminal_init(void);
|
||||
void unbound_key(int code);
|
||||
bool okay_for_view(const sc *shortcut);
|
||||
int do_input(bool allow_funcs);
|
||||
#ifdef ENABLE_MOUSE
|
||||
int do_mouse(void);
|
||||
#endif
|
||||
void do_output(char *output, size_t output_len, bool allow_cntrls);
|
||||
|
||||
/* Most functions in prompt.c. */
|
||||
#ifdef ENABLE_MOUSE
|
||||
int do_statusbar_mouse(void);
|
||||
#endif
|
||||
void do_statusbar_output(int *the_input, size_t input_len,
|
||||
bool filtering);
|
||||
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);
|
||||
@@ -477,14 +466,13 @@ size_t get_statusbar_page_start(size_t start_col, size_t column);
|
||||
void reinit_statusbar_x(void);
|
||||
void update_the_statusbar(void);
|
||||
int do_prompt(bool allow_tabs, bool allow_files,
|
||||
int menu, const char *curranswer, filestruct **history_list,
|
||||
void (*refresh_func)(void), const char *msg, ...);
|
||||
int menu, const char *curranswer, filestruct **history_list,
|
||||
void (*refresh_func)(void), const char *msg, ...);
|
||||
int do_yesno_prompt(bool all, const char *msg);
|
||||
|
||||
/* Most functions in rcfile.c. */
|
||||
#ifdef ENABLE_NANORC
|
||||
#ifdef ENABLE_COLOR
|
||||
bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright);
|
||||
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage);
|
||||
#endif
|
||||
void parse_rcfile(FILE *rcstream, bool syntax_only);
|
||||
@@ -492,25 +480,26 @@ void do_rcfiles(void);
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
/* Most functions in search.c. */
|
||||
void not_found_msg(const char *str);
|
||||
void search_replace_abort(void);
|
||||
void tidy_up_after_search(void);
|
||||
int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
size_t *match_len, bool skipone, const filestruct *begin, size_t begin_x);
|
||||
size_t *match_len, bool skipone, const filestruct *begin, size_t begin_x);
|
||||
void do_search(void);
|
||||
void do_search_forward(void);
|
||||
void do_search_backward(void);
|
||||
void do_research(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_findprevious(void);
|
||||
void do_findnext(void);
|
||||
#endif
|
||||
void do_research(void);
|
||||
void not_found_msg(const char *str);
|
||||
void go_looking(void);
|
||||
ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
const filestruct *real_current, size_t *real_current_x);
|
||||
const filestruct *real_current, size_t *real_current_x);
|
||||
void do_replace(void);
|
||||
void ask_for_replacement(void);
|
||||
void goto_line_posx(ssize_t line, size_t pos_x);
|
||||
void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
bool interactive);
|
||||
bool interactive);
|
||||
void do_gotolinecolumn_void(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_find_bracket(void);
|
||||
@@ -534,7 +523,6 @@ void do_unindent(void);
|
||||
bool white_string(const char *s);
|
||||
#ifdef ENABLE_COMMENT
|
||||
void do_comment(void);
|
||||
bool comment_line(undo_type action, filestruct *f, const char *comment_seq);
|
||||
#endif
|
||||
void do_undo(void);
|
||||
void do_redo(void);
|
||||
@@ -542,7 +530,7 @@ void do_enter(void);
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE cancel_command(int signal);
|
||||
bool execute_command(const char *command);
|
||||
void discard_until(const undo *thisitem, openfilestruct *thefile);
|
||||
void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep);
|
||||
void add_undo(undo_type action);
|
||||
void update_multiline_undo(ssize_t lineno, char *indentation);
|
||||
void update_undo(undo_type action);
|
||||
@@ -591,12 +579,15 @@ void snuggly_fit(char **str);
|
||||
void null_at(char **data, size_t index);
|
||||
void unsunder(char *str, size_t true_len);
|
||||
void sunder(char *str);
|
||||
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
|
||||
void free_chararray(char **array, size_t len);
|
||||
#endif
|
||||
const char *fixbounds(const char *r);
|
||||
#ifdef ENABLE_SPELLER
|
||||
bool is_separate_word(size_t position, size_t length, const char *buf);
|
||||
#endif
|
||||
const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *start);
|
||||
const char *start);
|
||||
void nperror(const char *s);
|
||||
void *nmalloc(size_t howmuch);
|
||||
void *nrealloc(void *ptr, size_t howmuch);
|
||||
@@ -613,8 +604,9 @@ void new_magicline(void);
|
||||
void remove_magicline(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
||||
**bot, size_t *bot_x, bool *right_side_up);
|
||||
void mark_order(const filestruct **top, size_t *top_x,
|
||||
const filestruct **bot, size_t *bot_x, bool *right_side_up);
|
||||
void get_range(const filestruct **top, const filestruct **bot);
|
||||
#endif
|
||||
size_t get_totsize(const filestruct *begin, const filestruct *end);
|
||||
#ifndef NANO_TINY
|
||||
@@ -622,15 +614,17 @@ filestruct *fsfromline(ssize_t lineno);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
void dump_filestruct(const filestruct *inptr);
|
||||
void dump_filestruct_reverse(void);
|
||||
#endif
|
||||
|
||||
/* Most functions in winio.c. */
|
||||
void record_macro(void);
|
||||
void run_macro(void);
|
||||
void get_key_buffer(WINDOW *win);
|
||||
size_t get_key_buffer_len(void);
|
||||
void 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);
|
||||
@@ -640,17 +634,17 @@ 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);
|
||||
#ifdef ENABLE_MOUSE
|
||||
int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
|
||||
int get_mouseinput(int *mouse_row, int *mouse_col, bool allow_shortcuts);
|
||||
#endif
|
||||
const sc *get_shortcut(int *kbinput);
|
||||
void blank_row(WINDOW *win, int y, int x, int n);
|
||||
void blank_edit(void);
|
||||
void blank_statusbar(void);
|
||||
void wipe_statusbar(void);
|
||||
void blank_bottombars(void);
|
||||
void check_statusblank(void);
|
||||
char *display_string(const char *buf, size_t column, size_t span, bool isdata);
|
||||
void titlebar(const char *path);
|
||||
extern void set_modified(void);
|
||||
void statusbar(const char *msg);
|
||||
void warn_and_shortly_pause(const char *msg);
|
||||
void statusline(message_type importance, const char *msg, ...);
|
||||
@@ -658,7 +652,7 @@ void bottombars(int menu);
|
||||
void post_one_key(const char *keystroke, const char *tag, int width);
|
||||
void place_the_cursor(void);
|
||||
void edit_draw(filestruct *fileptr, const char *converted,
|
||||
int line, size_t from_col);
|
||||
int line, size_t from_col);
|
||||
int update_line(filestruct *fileptr, size_t index);
|
||||
#ifndef NANO_TINY
|
||||
int update_softwrapped_line(filestruct *fileptr);
|
||||
@@ -667,10 +661,10 @@ bool line_needs_update(const size_t old_column, const size_t new_column);
|
||||
int go_back_chunks(int nrows, filestruct **line, size_t *leftedge);
|
||||
int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge);
|
||||
bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge);
|
||||
void edit_scroll(bool direction, int nrows);
|
||||
void edit_scroll(bool direction);
|
||||
#ifndef NANO_TINY
|
||||
size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
||||
bool *end_of_line);
|
||||
bool *end_of_line);
|
||||
size_t get_chunk_and_edge(size_t column, filestruct *line, size_t *leftedge);
|
||||
size_t chunk_for(size_t column, filestruct *line);
|
||||
size_t leftedge_for(size_t column, filestruct *line);
|
||||
@@ -698,17 +692,17 @@ void do_credits(void);
|
||||
#endif
|
||||
|
||||
/* These are just name definitions. */
|
||||
void do_cancel(void);
|
||||
void case_sens_void(void);
|
||||
void regexp_void(void);
|
||||
void backwards_void(void);
|
||||
void flip_replace(void);
|
||||
void gototext_void(void);
|
||||
void flip_goto(void);
|
||||
#ifdef ENABLE_BROWSER
|
||||
void to_files_void(void);
|
||||
void goto_dir_void(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_toggle_void(void);
|
||||
void dos_format_void(void);
|
||||
void mac_format_void(void);
|
||||
void append_void(void);
|
||||
@@ -720,5 +714,6 @@ void flip_execute(void);
|
||||
void flip_newbuffer(void);
|
||||
#endif
|
||||
void discard_buffer(void);
|
||||
void do_cancel(void);
|
||||
|
||||
#endif /* !PROTO_H */
|
||||
|
||||
1772
src/rcfile.c
1772
src/rcfile.c
File diff suppressed because it is too large
Load Diff
1601
src/search.c
1601
src/search.c
File diff suppressed because it is too large
Load Diff
5768
src/text.c
5768
src/text.c
File diff suppressed because it is too large
Load Diff
665
src/utils.c
665
src/utils.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* utils.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -32,79 +32,79 @@
|
||||
* we fall back on the home directory of the effective user ID. */
|
||||
void get_homedir(void)
|
||||
{
|
||||
if (homedir == NULL) {
|
||||
const char *homenv = getenv("HOME");
|
||||
if (homedir == NULL) {
|
||||
const char *homenv = getenv("HOME");
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
/* When HOME isn't set, or when we're root, get the home directory
|
||||
* from the password file instead. */
|
||||
if (homenv == NULL || geteuid() == 0) {
|
||||
const struct passwd *userage = getpwuid(geteuid());
|
||||
/* When HOME isn't set, or when we're root, get the home directory
|
||||
* from the password file instead. */
|
||||
if (homenv == NULL || geteuid() == 0) {
|
||||
const struct passwd *userage = getpwuid(geteuid());
|
||||
|
||||
if (userage != NULL)
|
||||
homenv = userage->pw_dir;
|
||||
}
|
||||
if (userage != NULL)
|
||||
homenv = userage->pw_dir;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Only set homedir if some home directory could be determined,
|
||||
* otherwise keep homedir NULL. */
|
||||
if (homenv != NULL && strcmp(homenv, "") != 0)
|
||||
homedir = mallocstrcpy(NULL, homenv);
|
||||
}
|
||||
/* Only set homedir if some home directory could be determined,
|
||||
* otherwise keep homedir NULL. */
|
||||
if (homenv != NULL && *homenv != '\0')
|
||||
homedir = mallocstrcpy(NULL, homenv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the filename part of the given path. */
|
||||
const char *tail(const char *path)
|
||||
{
|
||||
const char *slash = strrchr(path, '/');
|
||||
const char *slash = strrchr(path, '/');
|
||||
|
||||
if (slash == NULL)
|
||||
return path;
|
||||
else
|
||||
return ++slash;
|
||||
if (slash == NULL)
|
||||
return path;
|
||||
else
|
||||
return ++slash;
|
||||
}
|
||||
|
||||
/* Return a copy of the two given strings, welded together. */
|
||||
char *concatenate(const char *path, const char *name)
|
||||
{
|
||||
size_t pathlen = strlen(path);
|
||||
char *joined = charalloc(pathlen + strlen(name) + 1);
|
||||
size_t pathlen = strlen(path);
|
||||
char *joined = charalloc(pathlen + strlen(name) + 1);
|
||||
|
||||
strcpy(joined, path);
|
||||
strcpy(joined + pathlen, name);
|
||||
strcpy(joined, path);
|
||||
strcpy(joined + pathlen, name);
|
||||
|
||||
return joined;
|
||||
return joined;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
/* Return the number of digits that the given integer n takes up. */
|
||||
int digits(ssize_t n)
|
||||
{
|
||||
if (n < 100000) {
|
||||
if (n < 1000) {
|
||||
if (n < 100)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
if (n < 100000) {
|
||||
if (n < 1000) {
|
||||
if (n < 100)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
} else {
|
||||
if (n < 10000)
|
||||
return 4;
|
||||
else
|
||||
return 5;
|
||||
}
|
||||
} else {
|
||||
if (n < 10000)
|
||||
return 4;
|
||||
else
|
||||
return 5;
|
||||
if (n < 10000000) {
|
||||
if (n < 1000000)
|
||||
return 6;
|
||||
else
|
||||
return 7;
|
||||
} else {
|
||||
if (n < 100000000)
|
||||
return 8;
|
||||
else
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (n < 10000000) {
|
||||
if (n < 1000000)
|
||||
return 6;
|
||||
else
|
||||
return 7;
|
||||
} else {
|
||||
if (n < 100000000)
|
||||
return 8;
|
||||
else
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -112,116 +112,130 @@ int digits(ssize_t n)
|
||||
* and return TRUE; otherwise, return FALSE. */
|
||||
bool parse_num(const char *str, ssize_t *result)
|
||||
{
|
||||
char *first_error;
|
||||
ssize_t value;
|
||||
char *first_error;
|
||||
ssize_t value;
|
||||
|
||||
/* The manual page for strtol() says this is required. */
|
||||
errno = 0;
|
||||
/* The manual page for strtol() says this is required. */
|
||||
errno = 0;
|
||||
|
||||
value = (ssize_t)strtol(str, &first_error, 10);
|
||||
value = (ssize_t)strtol(str, &first_error, 10);
|
||||
|
||||
if (errno == ERANGE || *str == '\0' || *first_error != '\0')
|
||||
return FALSE;
|
||||
if (errno == ERANGE || *str == '\0' || *first_error != '\0')
|
||||
return FALSE;
|
||||
|
||||
*result = value;
|
||||
*result = value;
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Read two numbers, separated by a comma, from str, and store them in
|
||||
* *line and *column. Return FALSE on error, and TRUE otherwise. */
|
||||
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column)
|
||||
{
|
||||
bool retval;
|
||||
char *firstpart;
|
||||
const char *comma;
|
||||
bool retval;
|
||||
char *firstpart;
|
||||
const char *comma;
|
||||
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
|
||||
comma = strpbrk(str, "m,. /;");
|
||||
comma = strpbrk(str, "m,. /;");
|
||||
|
||||
if (comma == NULL)
|
||||
return parse_num(str, line);
|
||||
if (comma == NULL)
|
||||
return parse_num(str, line);
|
||||
|
||||
retval = parse_num(comma + 1, column);
|
||||
retval = parse_num(comma + 1, column);
|
||||
|
||||
if (comma == str)
|
||||
return retval;
|
||||
|
||||
firstpart = mallocstrcpy(NULL, str);
|
||||
firstpart[comma - str] = '\0';
|
||||
|
||||
retval = parse_num(firstpart, line) && retval;
|
||||
|
||||
free(firstpart);
|
||||
|
||||
if (comma == str)
|
||||
return retval;
|
||||
|
||||
firstpart = mallocstrcpy(NULL, str);
|
||||
firstpart[comma - str] = '\0';
|
||||
|
||||
retval = parse_num(firstpart, line) && retval;
|
||||
|
||||
free(firstpart);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Reduce the memory allocation of a string to what is needed. */
|
||||
void snuggly_fit(char **str)
|
||||
{
|
||||
if (*str != NULL)
|
||||
*str = charealloc(*str, strlen(*str) + 1);
|
||||
if (*str != NULL)
|
||||
*str = charealloc(*str, strlen(*str) + 1);
|
||||
}
|
||||
|
||||
/* Null a string at a certain index and align it. */
|
||||
void null_at(char **data, size_t index)
|
||||
{
|
||||
*data = charealloc(*data, index + 1);
|
||||
(*data)[index] = '\0';
|
||||
*data = charealloc(*data, index + 1);
|
||||
(*data)[index] = '\0';
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so encode its nulls as newlines. */
|
||||
void unsunder(char *str, size_t true_len)
|
||||
{
|
||||
for (; true_len > 0; true_len--, str++) {
|
||||
if (*str == '\0')
|
||||
*str = '\n';
|
||||
}
|
||||
for (; true_len > 0; true_len--, str++) {
|
||||
if (*str == '\0')
|
||||
*str = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so decode its newlines as nulls. */
|
||||
void sunder(char *str)
|
||||
{
|
||||
for (; *str != '\0'; str++) {
|
||||
if (*str == '\n')
|
||||
*str = '\0';
|
||||
}
|
||||
for (; *str != '\0'; str++) {
|
||||
if (*str == '\n')
|
||||
*str = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
|
||||
/* Free the memory of the given array, which should contain len elements. */
|
||||
void free_chararray(char **array, size_t len)
|
||||
{
|
||||
if (array == NULL)
|
||||
return;
|
||||
|
||||
while (len > 0)
|
||||
free(array[--len]);
|
||||
|
||||
free(array);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fix the regex if we're on platforms which require an adjustment
|
||||
* from GNU-style to BSD-style word boundaries. */
|
||||
const char *fixbounds(const char *r)
|
||||
{
|
||||
#ifndef GNU_WORDBOUNDS
|
||||
int i, j = 0;
|
||||
char *r2 = charalloc(strlen(r) * 5);
|
||||
char *r3;
|
||||
int i, j = 0;
|
||||
char *r2 = charalloc(strlen(r) * 5);
|
||||
char *r3;
|
||||
|
||||
for (i = 0; i < strlen(r); i++) {
|
||||
if (r[i] != '\0' && r[i] == '\\' && (r[i + 1] == '>' || r[i + 1] == '<')) {
|
||||
strcpy(&r2[j], "[[:");
|
||||
r2[j + 3] = r[i + 1];
|
||||
strcpy(&r2[j + 4], ":]]");
|
||||
i++;
|
||||
j += 6;
|
||||
} else
|
||||
r2[j] = r[i];
|
||||
j++;
|
||||
}
|
||||
for (i = 0; i < strlen(r); i++) {
|
||||
if (r[i] != '\0' && r[i] == '\\' && (r[i + 1] == '>' || r[i + 1] == '<')) {
|
||||
strcpy(&r2[j], "[[:");
|
||||
r2[j + 3] = r[i + 1];
|
||||
strcpy(&r2[j + 4], ":]]");
|
||||
i++;
|
||||
j += 6;
|
||||
} else
|
||||
r2[j] = r[i];
|
||||
j++;
|
||||
}
|
||||
|
||||
r2[j] = '\0';
|
||||
r3 = mallocstrcpy(NULL, r2);
|
||||
free(r2);
|
||||
r2[j] = '\0';
|
||||
r3 = mallocstrcpy(NULL, r2);
|
||||
free(r2);
|
||||
|
||||
return (const char *) r3;
|
||||
return (const char *) r3;
|
||||
#endif /* !GNU_WORDBOUNDS */
|
||||
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SPELLER
|
||||
@@ -229,18 +243,18 @@ const char *fixbounds(const char *r)
|
||||
* a separate word? That is: is it not part of a longer word?*/
|
||||
bool is_separate_word(size_t position, size_t length, const char *buf)
|
||||
{
|
||||
char before[MAXCHARLEN], after[MAXCHARLEN];
|
||||
size_t word_end = position + length;
|
||||
char before[MAXCHARLEN], after[MAXCHARLEN];
|
||||
size_t word_end = position + length;
|
||||
|
||||
/* Get the characters before and after the word, if any. */
|
||||
parse_mbchar(buf + move_mbleft(buf, position), before, NULL);
|
||||
parse_mbchar(buf + word_end, after, NULL);
|
||||
/* Get the characters before and after the word, if any. */
|
||||
parse_mbchar(buf + move_mbleft(buf, position), before, NULL);
|
||||
parse_mbchar(buf + word_end, after, NULL);
|
||||
|
||||
/* 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)));
|
||||
/* 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)));
|
||||
}
|
||||
#endif /* ENABLE_SPELLER */
|
||||
|
||||
@@ -250,76 +264,79 @@ bool is_separate_word(size_t position, size_t length, const char *buf)
|
||||
* than start. If we are doing a regexp search, and we find a match, we fill
|
||||
* in the global variable regmatches with at most 9 subexpression matches. */
|
||||
const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *start)
|
||||
const char *start)
|
||||
{
|
||||
if (*needle == '\0') {
|
||||
if (*needle == '\0') {
|
||||
#ifndef NANO_TINY
|
||||
statusline(ALERT, "Searching for nothing -- please report a bug");
|
||||
statusline(ALERT, "Searching for nothing -- please report a bug");
|
||||
#endif
|
||||
return (char *)start;
|
||||
}
|
||||
|
||||
if (ISSET(USE_REGEXP)) {
|
||||
if (ISSET(BACKWARDS_SEARCH)) {
|
||||
size_t last_find, ceiling, far_end;
|
||||
size_t floor = 0, next_rung = 0;
|
||||
/* The start of the search range, and the next start. */
|
||||
|
||||
if (regexec(&search_regexp, haystack, 1, regmatches, 0) != 0)
|
||||
return NULL;
|
||||
|
||||
far_end = strlen(haystack);
|
||||
ceiling = start - haystack;
|
||||
last_find = regmatches[0].rm_so;
|
||||
|
||||
/* A result beyond the search range also means: no match. */
|
||||
if (last_find > ceiling)
|
||||
return NULL;
|
||||
|
||||
/* Move the start-of-range forward until there is no more match;
|
||||
* then the last match found is the first match backwards. */
|
||||
while (regmatches[0].rm_so <= ceiling) {
|
||||
floor = next_rung;
|
||||
last_find = regmatches[0].rm_so;
|
||||
/* If this is the last possible match, don't try to advance. */
|
||||
if (last_find == ceiling)
|
||||
break;
|
||||
next_rung = move_mbright(haystack, last_find);
|
||||
regmatches[0].rm_so = next_rung;
|
||||
regmatches[0].rm_eo = far_end;
|
||||
if (regexec(&search_regexp, haystack, 1, regmatches,
|
||||
REG_STARTEND) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Find the last match again, to get possible submatches. */
|
||||
regmatches[0].rm_so = floor;
|
||||
regmatches[0].rm_eo = far_end;
|
||||
if (regexec(&search_regexp, haystack, 10, regmatches,
|
||||
REG_STARTEND) != 0)
|
||||
return NULL;
|
||||
|
||||
return haystack + regmatches[0].rm_so;
|
||||
return (char *)start;
|
||||
}
|
||||
|
||||
/* Do a forward regex search from the starting point. */
|
||||
regmatches[0].rm_so = start - haystack;
|
||||
regmatches[0].rm_eo = strlen(haystack);
|
||||
if (regexec(&search_regexp, haystack, 10, regmatches,
|
||||
REG_STARTEND) != 0)
|
||||
return NULL;
|
||||
else
|
||||
return haystack + regmatches[0].rm_so;
|
||||
}
|
||||
if (ISSET(CASE_SENSITIVE)) {
|
||||
if (ISSET(BACKWARDS_SEARCH))
|
||||
return revstrstr(haystack, needle, start);
|
||||
else
|
||||
return strstr(start, needle);
|
||||
} else if (ISSET(BACKWARDS_SEARCH))
|
||||
return mbrevstrcasestr(haystack, needle, start);
|
||||
if (ISSET(USE_REGEXP)) {
|
||||
if (ISSET(BACKWARDS_SEARCH)) {
|
||||
size_t last_find, ceiling, far_end;
|
||||
size_t floor = 0, next_rung = 0;
|
||||
/* The start of the search range, and the next start. */
|
||||
|
||||
return mbstrcasestr(start, needle);
|
||||
if (regexec(&search_regexp, haystack, 1, regmatches, 0) != 0)
|
||||
return NULL;
|
||||
|
||||
far_end = strlen(haystack);
|
||||
ceiling = start - haystack;
|
||||
last_find = regmatches[0].rm_so;
|
||||
|
||||
/* A result beyond the search range also means: no match. */
|
||||
if (last_find > ceiling)
|
||||
return NULL;
|
||||
|
||||
/* Move the start-of-range forward until there is no more match;
|
||||
* then the last match found is the first match backwards. */
|
||||
while (regmatches[0].rm_so <= ceiling) {
|
||||
floor = next_rung;
|
||||
last_find = regmatches[0].rm_so;
|
||||
/* If this is the last possible match, don't try to advance. */
|
||||
if (last_find == ceiling)
|
||||
break;
|
||||
next_rung = move_mbright(haystack, last_find);
|
||||
regmatches[0].rm_so = next_rung;
|
||||
regmatches[0].rm_eo = far_end;
|
||||
if (regexec(&search_regexp, haystack, 1, regmatches,
|
||||
REG_STARTEND) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Find the last match again, to get possible submatches. */
|
||||
regmatches[0].rm_so = floor;
|
||||
regmatches[0].rm_eo = far_end;
|
||||
if (regexec(&search_regexp, haystack, 10, regmatches,
|
||||
REG_STARTEND) != 0)
|
||||
return NULL;
|
||||
|
||||
return haystack + regmatches[0].rm_so;
|
||||
}
|
||||
|
||||
/* Do a forward regex search from the starting point. */
|
||||
regmatches[0].rm_so = start - haystack;
|
||||
regmatches[0].rm_eo = strlen(haystack);
|
||||
if (regexec(&search_regexp, haystack, 10, regmatches,
|
||||
REG_STARTEND) != 0)
|
||||
return NULL;
|
||||
else
|
||||
return haystack + regmatches[0].rm_so;
|
||||
}
|
||||
|
||||
if (ISSET(CASE_SENSITIVE)) {
|
||||
if (ISSET(BACKWARDS_SEARCH))
|
||||
return revstrstr(haystack, needle, start);
|
||||
else
|
||||
return strstr(start, needle);
|
||||
}
|
||||
|
||||
if (ISSET(BACKWARDS_SEARCH))
|
||||
return mbrevstrcasestr(haystack, needle, start);
|
||||
else
|
||||
return mbstrcasestr(start, needle);
|
||||
}
|
||||
|
||||
/* This is a wrapper for the perror() function. The wrapper temporarily
|
||||
@@ -328,64 +345,64 @@ const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
* nperror() causes the window to flicker once. */
|
||||
void nperror(const char *s)
|
||||
{
|
||||
endwin();
|
||||
perror(s);
|
||||
doupdate();
|
||||
endwin();
|
||||
perror(s);
|
||||
doupdate();
|
||||
}
|
||||
|
||||
/* This is a wrapper for the malloc() function that properly handles
|
||||
* things when we run out of memory. Thanks, BG, many people have been
|
||||
* asking for this... */
|
||||
* things when we run out of memory. */
|
||||
void *nmalloc(size_t howmuch)
|
||||
{
|
||||
void *r = malloc(howmuch);
|
||||
void *r = malloc(howmuch);
|
||||
|
||||
if (r == NULL && howmuch != 0)
|
||||
die(_("nano is out of memory!"));
|
||||
if (r == NULL && howmuch != 0)
|
||||
die(_("nano is out of memory!"));
|
||||
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* This is a wrapper for the realloc() function that properly handles
|
||||
* things when we run out of memory. */
|
||||
void *nrealloc(void *ptr, size_t howmuch)
|
||||
{
|
||||
void *r = realloc(ptr, howmuch);
|
||||
void *r = realloc(ptr, howmuch);
|
||||
|
||||
if (r == NULL && howmuch != 0)
|
||||
die(_("nano is out of memory!"));
|
||||
if (r == NULL && howmuch != 0)
|
||||
die(_("nano is out of memory!"));
|
||||
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Allocate and copy the first n characters of the given src string, after
|
||||
* freeing the destination. Usage: "dest = mallocstrncpy(dest, src, n);". */
|
||||
char *mallocstrncpy(char *dest, const char *src, size_t n)
|
||||
{
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
|
||||
if (src != dest)
|
||||
free(dest);
|
||||
#ifndef NANO_TINY
|
||||
if (src == dest)
|
||||
fprintf(stderr, "\r*** Copying a string to itself -- please report a bug ***");
|
||||
#endif
|
||||
dest = charealloc(dest, n);
|
||||
strncpy(dest, src, n);
|
||||
|
||||
dest = charalloc(n);
|
||||
strncpy(dest, src, n);
|
||||
|
||||
return dest;
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* Free the dest string and return a malloc'ed copy of src. Should be used as:
|
||||
* "dest = mallocstrcpy(dest, src);". */
|
||||
char *mallocstrcpy(char *dest, const char *src)
|
||||
{
|
||||
return mallocstrncpy(dest, src, (src == NULL) ? 1 : strlen(src) + 1);
|
||||
return mallocstrncpy(dest, src, (src == NULL) ? 1 : strlen(src) + 1);
|
||||
}
|
||||
|
||||
/* Free the string at dest and return the string at src. */
|
||||
char *free_and_assign(char *dest, char *src)
|
||||
{
|
||||
free(dest);
|
||||
return src;
|
||||
free(dest);
|
||||
return src;
|
||||
}
|
||||
|
||||
/* When not in softwrap mode, nano scrolls horizontally within a line in
|
||||
@@ -395,193 +412,199 @@ char *free_and_assign(char *dest, char *src)
|
||||
* get_page_start(column) < COLS). */
|
||||
size_t get_page_start(size_t column)
|
||||
{
|
||||
if (column < editwincols - 1 || ISSET(SOFTWRAP) || column == 0)
|
||||
return 0;
|
||||
else if (editwincols > 8)
|
||||
return column - 7 - (column - 7) % (editwincols - 8);
|
||||
else
|
||||
return column - (editwincols - 2);
|
||||
if (column < editwincols - 1 || ISSET(SOFTWRAP) || column == 0)
|
||||
return 0;
|
||||
else if (editwincols > 8)
|
||||
return column - 7 - (column - 7) % (editwincols - 8);
|
||||
else
|
||||
return column - (editwincols - 2);
|
||||
}
|
||||
|
||||
/* Return the placewewant associated with current_x, i.e. the zero-based
|
||||
* column position of the cursor. */
|
||||
size_t xplustabs(void)
|
||||
{
|
||||
return strnlenpt(openfile->current->data, openfile->current_x);
|
||||
return strnlenpt(openfile->current->data, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Return the index in text of the character that (when displayed) will
|
||||
* not overshoot the given column. */
|
||||
size_t actual_x(const char *text, size_t column)
|
||||
{
|
||||
const char *start = text;
|
||||
/* From where we start walking through the text. */
|
||||
size_t width = 0;
|
||||
/* The current accumulated span, in columns. */
|
||||
const char *start = text;
|
||||
/* From where we start walking through the text. */
|
||||
size_t width = 0;
|
||||
/* The current accumulated span, in columns. */
|
||||
|
||||
while (*text != '\0') {
|
||||
int charlen = parse_mbchar(text, NULL, &width);
|
||||
while (*text != '\0') {
|
||||
int charlen = parse_mbchar(text, NULL, &width);
|
||||
|
||||
if (width > column)
|
||||
break;
|
||||
if (width > column)
|
||||
break;
|
||||
|
||||
text += charlen;
|
||||
}
|
||||
text += charlen;
|
||||
}
|
||||
|
||||
return (text - start);
|
||||
return (text - start);
|
||||
}
|
||||
|
||||
/* A strnlen() with tabs and multicolumn characters factored in:
|
||||
* how many columns wide are the first maxlen bytes of text? */
|
||||
size_t strnlenpt(const char *text, size_t maxlen)
|
||||
{
|
||||
size_t width = 0;
|
||||
/* The screen display width to text[maxlen]. */
|
||||
size_t width = 0;
|
||||
/* The screen display width to text[maxlen]. */
|
||||
|
||||
if (maxlen == 0)
|
||||
return 0;
|
||||
if (maxlen == 0)
|
||||
return 0;
|
||||
|
||||
while (*text != '\0') {
|
||||
int charlen = parse_mbchar(text, NULL, &width);
|
||||
while (*text != '\0') {
|
||||
size_t charlen = parse_mbchar(text, NULL, &width);
|
||||
|
||||
if (maxlen <= charlen)
|
||||
break;
|
||||
if (maxlen <= charlen)
|
||||
break;
|
||||
|
||||
maxlen -= charlen;
|
||||
text += charlen;
|
||||
}
|
||||
maxlen -= charlen;
|
||||
text += charlen;
|
||||
}
|
||||
|
||||
return width;
|
||||
return width;
|
||||
}
|
||||
|
||||
/* Return the number of columns that the given text occupies. */
|
||||
size_t strlenpt(const char *text)
|
||||
{
|
||||
size_t span = 0;
|
||||
size_t span = 0;
|
||||
|
||||
while (*text != '\0')
|
||||
text += parse_mbchar(text, NULL, &span);
|
||||
while (*text != '\0')
|
||||
text += parse_mbchar(text, NULL, &span);
|
||||
|
||||
return span;
|
||||
return span;
|
||||
}
|
||||
|
||||
/* Append a new magicline to filebot. */
|
||||
/* Append a new magicline to the end of the buffer. */
|
||||
void new_magicline(void)
|
||||
{
|
||||
openfile->filebot->next = make_new_node(openfile->filebot);
|
||||
openfile->filebot->next->data = mallocstrcpy(NULL, "");
|
||||
openfile->filebot = openfile->filebot->next;
|
||||
openfile->totsize++;
|
||||
openfile->filebot->next = make_new_node(openfile->filebot);
|
||||
openfile->filebot->next->data = mallocstrcpy(NULL, "");
|
||||
openfile->filebot = openfile->filebot->next;
|
||||
openfile->totsize++;
|
||||
}
|
||||
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
/* Remove the magicline from filebot, if there is one and it isn't the
|
||||
* only line in the file. Assume that edittop and current are not at
|
||||
* filebot. */
|
||||
/* Remove the magicline from the end of the buffer, if there is one and
|
||||
* it isn't the only line in the file. */
|
||||
void remove_magicline(void)
|
||||
{
|
||||
if (openfile->filebot->data[0] == '\0' &&
|
||||
openfile->filebot != openfile->fileage) {
|
||||
openfile->filebot = openfile->filebot->prev;
|
||||
free_filestruct(openfile->filebot->next);
|
||||
openfile->filebot->next = NULL;
|
||||
openfile->totsize--;
|
||||
}
|
||||
if (openfile->filebot->data[0] == '\0' &&
|
||||
openfile->filebot != openfile->fileage) {
|
||||
openfile->filebot = openfile->filebot->prev;
|
||||
free_filestruct(openfile->filebot->next);
|
||||
openfile->filebot->next = NULL;
|
||||
openfile->totsize--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Set top_x and bot_x to the top and bottom x-coordinates of the mark,
|
||||
* respectively, based on the locations of top and bot. If
|
||||
* right_side_up isn't NULL, set it to TRUE if the mark begins with
|
||||
* (mark_begin, mark_begin_x) and ends with (current, current_x), or
|
||||
* FALSE otherwise. */
|
||||
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
||||
**bot, size_t *bot_x, bool *right_side_up)
|
||||
/* Set (top, top_x) and (bot, bot_x) to 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 mark_order(const filestruct **top, size_t *top_x,
|
||||
const filestruct **bot, size_t *bot_x, bool *right_side_up)
|
||||
{
|
||||
if ((openfile->current->lineno == openfile->mark_begin->lineno &&
|
||||
openfile->current_x > openfile->mark_begin_x) ||
|
||||
openfile->current->lineno > openfile->mark_begin->lineno) {
|
||||
*top = openfile->mark_begin;
|
||||
*top_x = openfile->mark_begin_x;
|
||||
*bot = openfile->current;
|
||||
*bot_x = openfile->current_x;
|
||||
if (right_side_up != NULL)
|
||||
*right_side_up = TRUE;
|
||||
} else {
|
||||
*bot = openfile->mark_begin;
|
||||
*bot_x = openfile->mark_begin_x;
|
||||
*top = openfile->current;
|
||||
*top_x = openfile->current_x;
|
||||
if (right_side_up != NULL)
|
||||
*right_side_up = FALSE;
|
||||
}
|
||||
if ((openfile->current->lineno == openfile->mark->lineno &&
|
||||
openfile->current_x > openfile->mark_x) ||
|
||||
openfile->current->lineno > openfile->mark->lineno) {
|
||||
*top = openfile->mark;
|
||||
*top_x = openfile->mark_x;
|
||||
*bot = openfile->current;
|
||||
*bot_x = openfile->current_x;
|
||||
if (right_side_up != NULL)
|
||||
*right_side_up = TRUE;
|
||||
} else {
|
||||
*bot = openfile->mark;
|
||||
*bot_x = openfile->mark_x;
|
||||
*top = openfile->current;
|
||||
*top_x = openfile->current_x;
|
||||
if (right_side_up != NULL)
|
||||
*right_side_up = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the set of lines to work on -- either just the current line, or the
|
||||
* first to last lines of the marked region. When the cursor (or mark) is
|
||||
* at the start of the last line of the region, exclude that line. */
|
||||
void get_range(const filestruct **top, const filestruct **bot)
|
||||
{
|
||||
if (!openfile->mark) {
|
||||
*top = openfile->current;
|
||||
*bot = openfile->current;
|
||||
} else {
|
||||
size_t top_x, bot_x;
|
||||
|
||||
mark_order(top, &top_x, bot, &bot_x, NULL);
|
||||
|
||||
if (bot_x == 0 && *bot != *top && !also_the_last)
|
||||
*bot = (*bot)->prev;
|
||||
else
|
||||
also_the_last = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a line number, return a pointer to the corresponding struct. */
|
||||
filestruct *fsfromline(ssize_t lineno)
|
||||
{
|
||||
filestruct *f = openfile->current;
|
||||
filestruct *f = openfile->current;
|
||||
|
||||
if (lineno <= openfile->current->lineno)
|
||||
while (f->lineno != lineno && f->prev != NULL)
|
||||
f = f->prev;
|
||||
else
|
||||
while (f->lineno != lineno && f->next != NULL)
|
||||
f = f->next;
|
||||
if (lineno <= openfile->current->lineno)
|
||||
while (f->lineno != lineno && f->prev != NULL)
|
||||
f = f->prev;
|
||||
else
|
||||
while (f->lineno != lineno && f->next != NULL)
|
||||
f = f->next;
|
||||
|
||||
if (f->lineno != lineno) {
|
||||
statusline(ALERT, "Gone undo line -- please report a bug");
|
||||
return NULL;
|
||||
}
|
||||
if (f->lineno != lineno) {
|
||||
statusline(ALERT, "Gone undo line -- please report a bug");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return f;
|
||||
return f;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Count the number of characters from begin to end, and return it. */
|
||||
size_t get_totsize(const filestruct *begin, const filestruct *end)
|
||||
{
|
||||
const filestruct *line;
|
||||
size_t totsize = 0;
|
||||
const filestruct *line;
|
||||
size_t totsize = 0;
|
||||
|
||||
/* Sum the number of characters (plus a newline) in each line. */
|
||||
for (line = begin; line != end->next; line = line->next)
|
||||
totsize += mbstrlen(line->data) + 1;
|
||||
/* Sum the number of characters (plus a newline) in each line. */
|
||||
for (line = begin; line != end->next; line = line->next)
|
||||
totsize += mbstrlen(line->data) + 1;
|
||||
|
||||
/* The last line of a file doesn't have a newline -- otherwise it
|
||||
* wouldn't be the last line -- so subtract 1 when at EOF. */
|
||||
if (line == NULL)
|
||||
totsize--;
|
||||
/* The last line of a file doesn't have a newline -- otherwise it
|
||||
* wouldn't be the last line -- so subtract 1 when at EOF. */
|
||||
if (line == NULL)
|
||||
totsize--;
|
||||
|
||||
return totsize;
|
||||
return totsize;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Dump the given buffer to stderr. */
|
||||
void dump_filestruct(const filestruct *inptr)
|
||||
{
|
||||
if (inptr == openfile->fileage)
|
||||
fprintf(stderr, "Dumping file buffer to stderr...\n");
|
||||
else if (inptr == cutbuffer)
|
||||
fprintf(stderr, "Dumping cutbuffer to stderr...\n");
|
||||
else
|
||||
fprintf(stderr, "Dumping a buffer to stderr...\n");
|
||||
if (inptr == openfile->fileage)
|
||||
fprintf(stderr, "Dumping file buffer to stderr...\n");
|
||||
else if (inptr == cutbuffer)
|
||||
fprintf(stderr, "Dumping cutbuffer to stderr...\n");
|
||||
else
|
||||
fprintf(stderr, "Dumping a buffer to stderr...\n");
|
||||
|
||||
while (inptr != NULL) {
|
||||
fprintf(stderr, "(%zd) %s\n", inptr->lineno, inptr->data);
|
||||
inptr = inptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the current buffer to stderr in reverse. */
|
||||
void dump_filestruct_reverse(void)
|
||||
{
|
||||
const filestruct *fileptr = openfile->filebot;
|
||||
|
||||
while (fileptr != NULL) {
|
||||
fprintf(stderr, "(%zd) %s\n", fileptr->lineno, fileptr->data);
|
||||
fileptr = fileptr->prev;
|
||||
}
|
||||
while (inptr != NULL) {
|
||||
fprintf(stderr, "(%zd) %s\n", inptr->lineno, inptr->data);
|
||||
inptr = inptr->next;
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
5323
src/winio.c
5323
src/winio.c
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
## Here is an example for assembler.
|
||||
|
||||
syntax "asm" "\.(S|s|asm)$"
|
||||
magic "[Aa]ssembl(y|er)"
|
||||
syntax asm "\.(S|s|asm)$"
|
||||
magic "assembler source"
|
||||
comment "//"
|
||||
|
||||
color red "\<[A-Z_]{2,}\>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Autoconf.
|
||||
|
||||
syntax "autoconf" "\.(ac|m4)$"
|
||||
syntax autoconf "\.(ac|m4)$"
|
||||
comment "#"
|
||||
|
||||
# Keywords:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Here is an example for awk.
|
||||
|
||||
syntax "awk" "\.awk$"
|
||||
magic "awk.*script text"
|
||||
syntax awk "\.awk$"
|
||||
magic "awk script"
|
||||
comment "#"
|
||||
|
||||
# Records.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Here is an example for C/C++.
|
||||
|
||||
syntax "c" "\.(c(c|pp|xx|\+\+)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
|
||||
magic "(ASCII|UTF-8 Unicode) C(\+\+)? program text"
|
||||
syntax c "\.(c(c|pp|xx|\+\+)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
|
||||
magic "^(C|C\+\+) (source|program)"
|
||||
comment "//"
|
||||
|
||||
# Constants.
|
||||
@@ -33,7 +33,7 @@ color brightblue "//.*"
|
||||
color brightblue start="/\*" end="\*/"
|
||||
|
||||
# Reminders.
|
||||
color ,yellow "\<(FIXME|TODO|XXX)\>"
|
||||
color brightwhite,yellow "\<(FIXME|TODO|XXX)\>"
|
||||
|
||||
# Trailing whitespace.
|
||||
color ,green "[[:space:]]+$"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Colouring for Changelogs.
|
||||
|
||||
syntax "changelog" "Change[Ll]og.*"
|
||||
syntax changelog "Change[Ll]og.*"
|
||||
|
||||
# Author lines.
|
||||
color green "^(19|20).*$"
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
## Syntax highlighting for CMake files.
|
||||
|
||||
syntax "cmake" "(CMakeLists\.txt|\.cmake)$"
|
||||
syntax cmake "(CMakeLists\.txt|\.cmake)$"
|
||||
comment "#"
|
||||
|
||||
icolor green "^[[:space:]]*[A-Z0-9_]+"
|
||||
icolor brightyellow "^[[:space:]]*(include|include_directories|include_external_msproject)\>"
|
||||
|
||||
icolor brightgreen "^[[:space:]]*\<((else|end)?if|else|(end)?while|(end)?foreach|break)\>"
|
||||
color brightgreen "\<(NOT|COMMAND|POLICY|TARGET|EXISTS|IS_(DIRECTORY|ABSOLUTE)|DEFINED)\>[[:space:]]"
|
||||
color brightgreen "[[:space:]]\<(OR|AND|IS_NEWER_THAN|MATCHES|(STR|VERSION_)?(LESS|GREATER|EQUAL))\>[[:space:]]"
|
||||
icolor brightgreen "^[[:space:]]*((else|end)?if|else|(end)?while|(end)?foreach|break)\>"
|
||||
color brightgreen "\<(NOT|COMMAND|POLICY|TARGET|EXISTS|IS_(DIRECTORY|ABSOLUTE)|DEFINED)[[:space:]]"
|
||||
color brightgreen "[[:space:]](OR|AND|IS_NEWER_THAN|MATCHES|(STR|VERSION_)?(LESS|GREATER|EQUAL))[[:space:]]"
|
||||
|
||||
icolor brightred "^[[:space:]]*\<((end)?(function|macro)|return)"
|
||||
icolor brightred "^[[:space:]]*((end)?(function|macro)|return)"
|
||||
|
||||
icolor cyan start="\$(\{|ENV\{)" end="\}"
|
||||
color magenta "\<(APPLE|UNIX|WIN32|CYGWIN|BORLAND|MINGW|MSVC(_IDE|60|71|80|90)?)\>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for CSS files.
|
||||
|
||||
syntax "css" "\.css$"
|
||||
syntax css "\.css$"
|
||||
comment "/*|*/"
|
||||
|
||||
color brightred "."
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for apt's sources.list.
|
||||
|
||||
syntax "sources.list" "sources\.list(~|\.old|\.save)?$" "sources\.list\.d/.*\.list(~|\.old|\.save)?$"
|
||||
syntax sources.list "sources\.list(~|\.old|\.save)?$" "sources\.list\.d/.*\.list(~|\.old|\.save)?$"
|
||||
comment "#"
|
||||
|
||||
# Coloring the deb lines, working from tail to head. First the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## An example of a default syntax. The default syntax is used for
|
||||
## files that do not match any other syntax.
|
||||
|
||||
syntax "default"
|
||||
syntax default
|
||||
comment "#"
|
||||
|
||||
# Comments.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
## Here is an example for Emacs Lisp.
|
||||
|
||||
syntax "elisp" "\.el$"
|
||||
syntax elisp "\.el$"
|
||||
magic "Lisp/Scheme program"
|
||||
comment ";"
|
||||
|
||||
# Basic functions/macros
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Fortran 90/95.
|
||||
|
||||
syntax "fortran" "\.(f|f90|f95)$"
|
||||
syntax fortran "\.(f|f90|f95)$"
|
||||
comment "!"
|
||||
|
||||
color red "\<[0-9]+\>"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Here is an example for Gentoo ebuilds/eclasses,
|
||||
## and (further down) one for Portage control files.
|
||||
|
||||
syntax "ebuild" "\.e(build|class|blit)$"
|
||||
syntax ebuild "\.e(build|class|blit)$"
|
||||
comment "#"
|
||||
|
||||
## All the standard portage functions:
|
||||
@@ -24,7 +24,7 @@ color red "\<EBUILD_PHASE(_FUNC)?\>"
|
||||
color red "\<QA_((TEXTRELS|EXECSTACK|WX_LOAD)(_[a-zA-Z_0-9]+)?|DT_HASH|PRESTRIPPED)\>"
|
||||
color red "\<(PATCHES|(HTML_)?DOCS)\>" "\<WANT_(AUTO(CONF|MAKE)|LIBTOOL)\>" "\<AT_M4DIR\>"
|
||||
## Portage commands:
|
||||
color magenta "\<(use(_(with|enable|if_iuse)|x)?|in_iuse)\> [!a-zA-Z0-9_+ -]*" "inherit.*"
|
||||
color magenta "\<(use(_(with|enable|if_iuse)|x)?|in_iuse) [!a-zA-Z0-9_+ -]*" "inherit.*"
|
||||
color brightblue "\<e(begin|end|conf|install|make|qmake4|ant|(qa)?warn|infon?|error|log|patch(_user)?|new(group|user))\>"
|
||||
color brightblue "\<e(pause|beep|mktemp|(cvs|svn)_clean|punt_cxx)\>" "\<e(aclocal|auto(reconf|header|conf|make)|libtoolize)\>"
|
||||
color brightblue "\<e(stack|shopts|umask)_(push|pop)\>" "\<version_is_at_least\>"
|
||||
@@ -48,7 +48,7 @@ color ,green "[[:space:]]+$"
|
||||
color ,green " "
|
||||
|
||||
|
||||
syntax "/etc/portage" "\.(accept_keywords|env|keywords|mask|unmask|use)(/.+)?$"
|
||||
syntax /etc/portage "\.(accept_keywords|env|keywords|mask|unmask|use)(/.+)?$"
|
||||
comment "#"
|
||||
|
||||
## Base text:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Go.
|
||||
|
||||
syntax "go" "\.go$"
|
||||
syntax go "\.go$"
|
||||
comment "//"
|
||||
|
||||
# Set up a formatter since spelling is probably useless...
|
||||
@@ -24,13 +24,11 @@ color brightcyan "\<(package|import)\>"
|
||||
color brightcyan "//[[:space:]]*\+build[[:space:]]+(([a-zA-Z_0-9]+[[:space:]]*)+,[[:space:]]*)*[a-zA-Z_0-9]+"
|
||||
|
||||
# Literals.
|
||||
color red "\<[0-9]+\.[0-9]*([Ee][+-][0-9]+)?i?\>"
|
||||
color red "\<[0-9]+[Ee][+-][0-9]+i?\>"
|
||||
color red "\<\.[0-9]+([Ee][+-][0-9]+)?i?\>"
|
||||
color red "\<([1-9][0-9]*|0[0-7]*|0[xX][0-9A-Fa-f]+)\>"
|
||||
color red "\<[0-9]+\.[0-9]*([eE][+-]?[0-9]+)?i?\>"
|
||||
color red "\<[0-9]+[eE][+-]?[0-9]+i?\>"
|
||||
color red "\B\.[0-9]+([eE][+-]?[0-9]+)?i?\>"
|
||||
color red "\<[0-9]+i\>"
|
||||
color red "\<[1-9][0-9]*\>"
|
||||
color red "\<0[0-7]*\>"
|
||||
icolor red "\<0x[0-9a-f]+\>"
|
||||
|
||||
# Strings and characters; slightly fuzzy.
|
||||
color red "\<(true|false|nil|iota|_)\>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for groff.
|
||||
|
||||
syntax "groff" "\.m[ems]$" "\.rof" "\.tmac$" "^tmac."
|
||||
syntax groff "\.m[ems]$" "\.rof" "\.tmac$" "^tmac."
|
||||
comment ".\""
|
||||
|
||||
# The argument of .ds or .nr
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
## Here is an example for Guile Scheme.
|
||||
|
||||
syntax "guile" "\.scm$"
|
||||
syntax guile "\.scm$"
|
||||
header "^#!.*guile"
|
||||
magic "guile"
|
||||
comment ";"
|
||||
|
||||
# Basic scheme functions
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Here is an example for HTML.
|
||||
|
||||
syntax "html" "\.html?$"
|
||||
magic "HTML document text"
|
||||
syntax html "\.html?$"
|
||||
magic "HTML document"
|
||||
comment "<!--|-->"
|
||||
|
||||
# Tags:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Java.
|
||||
|
||||
syntax "java" "\.java$"
|
||||
syntax java "\.java$"
|
||||
magic "Java "
|
||||
comment "//"
|
||||
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
## Here is an example for Javascript.
|
||||
## Syntax highlighting for Javascript.
|
||||
|
||||
syntax "javascript" "\.js$"
|
||||
syntax javascript "\.js$"
|
||||
comment "//"
|
||||
|
||||
color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
||||
color green "\<(const|function|let|this|typeof|var|void)\>"
|
||||
color brightyellow "\<(for|if|while|with|do|else|case|default|switch)\>"
|
||||
color brightyellow "\<(export|try|throw|catch|new|delete)\>"
|
||||
color magenta "\<(continue|break|return|yield)\>"
|
||||
color brightmagenta "'([^'\]|(\\["'abfnrtv\\]))'" "'\\(([0-3]?[0-7]{1,2}))'" "'\\x[0-9A-Fa-f]{1,2}'"
|
||||
# Declarational stuff.
|
||||
color green "\<(async|class|const|extends|function|let|this|typeof|var|void)\>"
|
||||
# Flow control and special keywords.
|
||||
color brightyellow "\<(do|while|if|else|switch|case|default|for|each|in|of|with)\>"
|
||||
color brightyellow "\<(await|export|import|throw|try|catch|finally|new|delete)\>"
|
||||
# "Exit" points.
|
||||
color magenta "\<(break|continue|return|yield)\>"
|
||||
|
||||
# Octal/decimal and hexadecimal numbers.
|
||||
color cyan "\<[0-9]+\>" "\<0x[0-9A-Fa-f]+\>"
|
||||
|
||||
# Strings.
|
||||
color brightyellow "<[^= ]*>" ""(\\.|[^"])*"" "'(\\.|[^'])*'"
|
||||
color brightmagenta ""(\\.|[^"])*"" "'(\\.|[^'])*'" "`(\\.|[^`])*`"
|
||||
# Comments.
|
||||
color brightblue "//.*"
|
||||
color brightblue "(^|[[:space:]])//.*"
|
||||
color brightblue start="/\*" end="\*/"
|
||||
|
||||
# Trailing whitespace.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Original author: Aapo Rantalainen
|
||||
# License: GPLv3 or newer
|
||||
|
||||
syntax "json" "\.json$"
|
||||
syntax json "\.json$"
|
||||
# No comments are permitted in JSON.
|
||||
comment ""
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
## Syntax highlighting for Lua.
|
||||
#
|
||||
## Author: Matthew Wild <mwild1 (at) gmail.com>
|
||||
## Original author: Matthew Wild <mwild1 (at) gmail.com>
|
||||
## License: GPL 3 or later
|
||||
## Version: 2011-05-05
|
||||
|
||||
syntax "lua" "\.lua$"
|
||||
syntax lua "\.lua$"
|
||||
magic "Lua script"
|
||||
comment "--"
|
||||
|
||||
color brightwhite "\[\[.*\]\]"
|
||||
@@ -16,48 +16,42 @@ color brightyellow ":|\*|/|%|\+|-|\^|>|>=|<|<=|~=|=|\.\.|\<(not|and|or)\>"
|
||||
color brightblue "\<(do|end|while|repeat|until|if|elseif|then|else|for|in|function|local|return|break)\>"
|
||||
|
||||
# Keywords
|
||||
color brightyellow "\<(io|math|os|string|table|coroutine|debug)\>\."
|
||||
color brightyellow "\<(_G|_VERSION|assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|load|loadfile|module|next|pairs|pcall|print|rawequal|rawget|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)\s*\("
|
||||
color brightyellow "\<(_G|_VERSION|assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|load|loadfile|module|next|pairs|pcall|print|rawequal|rawget|rawlen|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)\s*\("
|
||||
|
||||
# Standard library
|
||||
color brightyellow "io\.\<(close|flush|input|lines|open|output|popen|read|tmpfile|type|write|stdin|stdout|stderr)\>"
|
||||
color brightyellow "math\.\<(abs|acos|asin|atan2|atan|ceil|cosh|cos|deg|exp|floor|fmod|frexp|huge|ldexp|log10|log)\>"
|
||||
color brightyellow "math\.\<(max|min|mod|modf|pi|pow|rad|random|randomseed|sinh|tan)\>"
|
||||
color brightyellow "os\.\<(clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname)\>"
|
||||
color brightyellow "package\.\<(cpath|loaded|loadlib|path|preload|seeall)\>"
|
||||
color brightyellow "string\.\<(byte|char|dump|find|format|gmatch|gsub|len|lower|match|rep|reverse|sub|upper)\>"
|
||||
color brightyellow "table\.\<(concat|insert|maxn|remove|sort)\>"
|
||||
color brightyellow "coroutine\.\<(create|resume|running|status|wrap|yield)\>"
|
||||
color brightyellow "debug\.\<(debug|getfenv|gethook|getinfo|getlocal|getmetatable|getregistry|getupvalue)\>"
|
||||
color brightyellow "debug\.\<(setfenv|sethook|setlocal|setmetatable|setupvalue|traceback)\>"
|
||||
color brightyellow "\<coroutine\.(create|isyieldable|resume|running|status|wrap|yield)\>"
|
||||
color brightyellow "\<debug\.(debug|(get|set)(fenv|hook|local|metatable|(up|user)value)|getinfo|getregistry|traceback|upvalue(id|join))\>"
|
||||
color brightyellow "\<io\.(close|flush|input|lines|output|p?open|read|tmpfile|type|write|std(in|out|err))\>"
|
||||
color brightyellow "\<math\.(abs|acos|asin|atan2?|ceil|cosh?|deg|exp|floor|fmod|frexp|huge|ldexp|log10|log)\>"
|
||||
color brightyellow "\<math\.((max|min)(integer)?|modf?|pi|pow|rad|random(seed)?|sinh?|sqrt|tan|tointeger|type|ult)\>"
|
||||
color brightyellow "\<os\.(clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname)\>"
|
||||
color brightyellow "\<package\.(config|cpath|loaded|loadlib|path|preload|searchers|searchpath|seeall)\>"
|
||||
color brightyellow "\<string\.(byte|char|dump|find|format|gmatch|gsub|len|lower|match|pack|packsize|rep|reverse|sub|unpack|upper)\>"
|
||||
color brightyellow "\<table\.(concat|insert|maxn|move|pack|remove|sort|unpack)\>"
|
||||
color brightyellow "\<utf8\.(char|charpattern|codepoint|codes|len|offset)\>"
|
||||
|
||||
# File handle methods
|
||||
color brightyellow "\:\<(close|flush|lines|read|seek|setvbuf|write)\>"
|
||||
|
||||
# false, nil, true
|
||||
color brightmagenta "\<(false|nil|true)\>"
|
||||
color brightyellow ":(close|flush|lines|read|seek|setvbuf|write)\>"
|
||||
|
||||
# External files
|
||||
color brightgreen "\<(dofile|require)\>"
|
||||
|
||||
# Numbers
|
||||
color red "\<([0-9]+)\>"
|
||||
# Special words
|
||||
color brightmagenta "\<(false|nil|true)\>"
|
||||
|
||||
# Symbols
|
||||
color brightmagenta "(\(|\)|\[|\]|\{|\})"
|
||||
# Decimal and hexadecimal numbers
|
||||
color red "\<[0-9]+(\.[0-9]*)?([Ee][+-]?[0-9]+)?\>"
|
||||
icolor red "\<0x[0-9a-f]+(\.[0-9a-f]*)?(p[+-]?[0-9]+)?\>"
|
||||
|
||||
# Brackets
|
||||
color brightmagenta "\(|\)|\[|\]|\{|\}"
|
||||
|
||||
# Shebang
|
||||
color brightcyan "^#!.*"
|
||||
color brightcyan "^#!.*"
|
||||
|
||||
# Simple comments
|
||||
color green "\-\-.*$"
|
||||
|
||||
# Multiline comments
|
||||
color green start="\-\-\[\[" end="\]\]"
|
||||
# Simple comments and multiline comments
|
||||
color green "--.*"
|
||||
color green start="--\[\[" end="\]\]"
|
||||
|
||||
# Strings
|
||||
color red "\"(\\.|[^\\\"])*\"|'(\\.|[^\\'])*'"
|
||||
##color red start="\[\[" end="\]\]"
|
||||
|
||||
# Hex literals
|
||||
color red "0x[0-9a-fA-F]*"
|
||||
color red ""(\\.|[^"\])*"|'(\\.|[^'\])*'"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
## Here is an example for Makefiles.
|
||||
|
||||
syntax "makefile" "Makefile[^/]*$" "\.(make|mk)$"
|
||||
syntax makefile "Makefile[^/]*$" "\.(make|mk)$"
|
||||
magic "makefile script"
|
||||
comment "#"
|
||||
|
||||
color red "[:=]"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Here is an example for manpages.
|
||||
|
||||
syntax "man" "\.[1-9]x?$"
|
||||
magic "troff or preprocessor input text"
|
||||
syntax man "\.[1-9]x?$"
|
||||
magic "troff or preprocessor input"
|
||||
comment ".\""
|
||||
|
||||
color green "\.(SH|SS|TH) .*$"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Magicpoint presentations.
|
||||
|
||||
syntax "mgp" "\.mgp$"
|
||||
syntax mgp "\.mgp$"
|
||||
header "^%include.*"
|
||||
comment "#"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for quoted emails (under e.g. mutt).
|
||||
|
||||
syntax "mutt"
|
||||
syntax mutt
|
||||
|
||||
# Quoted lines.
|
||||
color green "^>.*"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
## This is meant for highlighting key combos in a nano help text.
|
||||
|
||||
# It should not apply to any normal file, so no fileregex.
|
||||
syntax "nanohelp"
|
||||
syntax nanohelp
|
||||
|
||||
# Key combos:
|
||||
color cyan "\^[]4-8A-Z^\_◀▶▲▼]" "[◀▶▲▼]" "(\^|M-)Space" "\<M-." "\<F1?[0-9]"
|
||||
color cyan "\<(Tab|Enter|Ins|Del|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
|
||||
color cyan "\<(Tab|Sh-Tab|Enter|Ins|Del|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
|
||||
|
||||
# Quoted indicators:
|
||||
color brightred "'(\^|M-)'"
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
## Here is an example for nanorc files.
|
||||
|
||||
syntax "nanorc" "\.?nanorc$"
|
||||
syntax nanorc "\.?nanorc$"
|
||||
comment "#"
|
||||
|
||||
# Possible errors and parameters
|
||||
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|i?color|extendsyntax).*$"
|
||||
|
||||
# Keywords
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cutfromcursor|fill[[:space:]]+-?[[:digit:]]+|historylog|justifytrim|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize[[:space:]]+[1-9][0-9]*|tabstospaces|tempfile|unix|view|wordbounds)\>"
|
||||
icolor yellow "^[[:space:]]*set[[:space:]]+((function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
||||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+[[:alpha:]]+[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cutfromcursor|fill[[:space:]]+-?[[:digit:]]+|historylog|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize[[:space:]]+[1-9][0-9]*|tabstospaces|tempfile|trimblanks|unix|view|wordbounds)\>"
|
||||
icolor yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+([[:alpha:]]+|".*")[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|linter|formatter)[[:space:]]+.*$"
|
||||
icolor brightgreen "^[[:space:]]*(linter|formatter)[[:space:]]+[[:alpha:]]+"
|
||||
icolor brightgreen "^[[:space:]]*(syntax|linter|formatter)[[:space:]]+[^[:blank:]]+"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|extendsyntax)\>"
|
||||
|
||||
# Strings
|
||||
color brightmagenta "".+"([[:space:]]|$)"
|
||||
|
||||
# Colors
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
icolor magenta "^[[:space:]]*i?color\>" "\<(start|end)="
|
||||
|
||||
# Strings
|
||||
color brightmagenta ""(\\.|[^"])*""
|
||||
# Comments
|
||||
color brightblue "(^|[[:space:]]+)#.*$"
|
||||
color cyan "^[[:space:]]*##.*$"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for nftables.
|
||||
|
||||
syntax "nftables" "\.(nft|nftables)$"
|
||||
syntax nftables "\.(nft|nftables)$"
|
||||
header "^#!.*(nft|nftables)"
|
||||
comment "#"
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
## Here is an example for C/C++/Obj-C.
|
||||
|
||||
syntax "m" "\.m$"
|
||||
syntax m "\.m$"
|
||||
magic "Objective-C source"
|
||||
comment "//"
|
||||
|
||||
# Stuffs,
|
||||
@@ -11,7 +12,7 @@ color green "\<(class|namespace|template|public|protected|private|typename|this|
|
||||
color brightgreen "\<(for|if|while|do|else|case|default|switch)\>"
|
||||
color brightgreen "\<(try|throw|catch|operator|new|delete)\>"
|
||||
color brightgreen "\<(goto|continue|break|return)\>"
|
||||
color brightgreen "@\<(en(code|d)|i(mplementation|nterface)|selector)\>"
|
||||
color brightgreen "@(encode|end|implementation|interface)|selector)\>"
|
||||
|
||||
# GCC builtins.
|
||||
color cyan "__attribute__[[:space:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
## Syntax highlighting for OCaml.
|
||||
|
||||
syntax "ocaml" "\.mli?$"
|
||||
syntax ocaml "\.mli?$"
|
||||
magic "OCaml"
|
||||
comment "(*|*)"
|
||||
|
||||
# Uid:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Here is an example for patch files.
|
||||
|
||||
syntax "patch" "\.(patch|diff|debdiff)$"
|
||||
magic "diff output text"
|
||||
syntax patch "\.(patch|diff|debdiff)$"
|
||||
magic "diff output"
|
||||
# There is no official support for comments in patch files.
|
||||
comment ""
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user