Compare commits
273 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7853df8b6 | ||
|
|
1e9d12abc5 | ||
|
|
3bce9fb755 | ||
|
|
0a57da42e0 | ||
|
|
73067e0e16 | ||
|
|
b9328d0eac | ||
|
|
0596b875f0 | ||
|
|
b94dcfd34b | ||
|
|
4238564673 | ||
|
|
764ab96bda | ||
|
|
f0cc59bead | ||
|
|
282f438967 | ||
|
|
1b01adfa9f | ||
|
|
87fe73ddaa | ||
|
|
c2746c0bb2 | ||
|
|
399a024857 | ||
|
|
d131c2d438 | ||
|
|
eb0962fb06 | ||
|
|
7bf253702e | ||
|
|
76742cc193 | ||
|
|
37717baeed | ||
|
|
ade2fafbd3 | ||
|
|
53fe7ba26a | ||
|
|
7e04fea92b | ||
|
|
1fdd23d347 | ||
|
|
5ea930e25f | ||
|
|
45defd25f3 | ||
|
|
0d11964503 | ||
|
|
7545eb5bbf | ||
|
|
878bd53d11 | ||
|
|
e0a4ee0148 | ||
|
|
d3fbc4d498 | ||
|
|
a8e2a24f60 | ||
|
|
36855544d1 | ||
|
|
dc745c0b77 | ||
|
|
a8ed1d7a9a | ||
|
|
94c371a38f | ||
|
|
36618f1dca | ||
|
|
3ea2694d9c | ||
|
|
85cc99a2a3 | ||
|
|
befe4ea5de | ||
|
|
43d94692ce | ||
|
|
1364b41dc9 | ||
|
|
7d3a555464 | ||
|
|
0508520b47 | ||
|
|
6cbb7bc443 | ||
|
|
055e262b56 | ||
|
|
9d8388e836 | ||
|
|
895de17a58 | ||
|
|
b202966d30 | ||
|
|
a19a7820f9 | ||
|
|
0122119a44 | ||
|
|
64bf03b0d9 | ||
|
|
4bc6d67052 | ||
|
|
7519a458b2 | ||
|
|
bc36813349 | ||
|
|
9bd7d62c10 | ||
|
|
735a608e80 | ||
|
|
71402bb7e9 | ||
|
|
9266fa6657 | ||
|
|
6360e4170a | ||
|
|
dcb072d04b | ||
|
|
4c6ce3c39d | ||
|
|
41fd09706d | ||
|
|
24e5f956d0 | ||
|
|
f602613a9a | ||
|
|
ba124ffa5d | ||
|
|
d30ddf0add | ||
|
|
e66c7d0f8d | ||
|
|
7b9567719c | ||
|
|
04d33e7981 | ||
|
|
c62d12ca93 | ||
|
|
297633d086 | ||
|
|
10b99d8ac0 | ||
|
|
0693d6974a | ||
|
|
5129e718d7 | ||
|
|
8c406bc875 | ||
|
|
c53da9aa5b | ||
|
|
e7a420eca7 | ||
|
|
1236341746 | ||
|
|
c96c343fac | ||
|
|
02f1fec497 | ||
|
|
a102e45e90 | ||
|
|
86c9b9b54e | ||
|
|
e14127b843 | ||
|
|
67cdd71352 | ||
|
|
6a88fe8807 | ||
|
|
90f6f25e31 | ||
|
|
0f4bb64eaf | ||
|
|
45efe28f05 | ||
|
|
c8c7986f65 | ||
|
|
f437117bf2 | ||
|
|
33e882e6f8 | ||
|
|
bad591d43d | ||
|
|
7b48458380 | ||
|
|
1e16a3f411 | ||
|
|
6a3ba2ab50 | ||
|
|
1878168ae3 | ||
|
|
545709a165 | ||
|
|
ca398fdfdf | ||
|
|
d0bceb1449 | ||
|
|
caef3128eb | ||
|
|
856a6ecde3 | ||
|
|
e353203010 | ||
|
|
f1fc66060f | ||
|
|
ba4f4bdc64 | ||
|
|
2b6c08b955 | ||
|
|
b86f7868d1 | ||
|
|
54995defd2 | ||
|
|
b89bc2cce6 | ||
|
|
8f24ffaaef | ||
|
|
d31cc373de | ||
|
|
f52f503c38 | ||
|
|
8939163659 | ||
|
|
265bdd94f1 | ||
|
|
d1c412d200 | ||
|
|
5c4c30e26b | ||
|
|
1b65d39722 | ||
|
|
96e4fec31c | ||
|
|
208146f2f2 | ||
|
|
89e84e76c3 | ||
|
|
c44a5e960e | ||
|
|
c1bd54dd47 | ||
|
|
3efb9c3a2e | ||
|
|
b87d7f69fc | ||
|
|
8ba653f395 | ||
|
|
c6501beba7 | ||
|
|
dbf522b750 | ||
|
|
651e97ceef | ||
|
|
d8500f0467 | ||
|
|
a9bc118178 | ||
|
|
903942b4f0 | ||
|
|
7ebf5f52b8 | ||
|
|
4f7593b704 | ||
|
|
2157738a18 | ||
|
|
681d11c0cf | ||
|
|
d96f296b8e | ||
|
|
048ab0ee0b | ||
|
|
16dff06a4c | ||
|
|
c3900e90f0 | ||
|
|
0f334f8ee4 | ||
|
|
587e6e2c88 | ||
|
|
a3a1391a51 | ||
|
|
a4675acdba | ||
|
|
00ac41f632 | ||
|
|
fe22da6b2a | ||
|
|
0c87a4ba41 | ||
|
|
39705c60df | ||
|
|
9da23799ff | ||
|
|
29276d1d3a | ||
|
|
13b839734f | ||
|
|
63bb1b62b7 | ||
|
|
743100feab | ||
|
|
d3d2d324d2 | ||
|
|
925a1a11f9 | ||
|
|
5918ca6cab | ||
|
|
dc907bfe43 | ||
|
|
687efd210c | ||
|
|
b7539ea985 | ||
|
|
7d35f71c87 | ||
|
|
7f184ee2ba | ||
|
|
ec9fc5d320 | ||
|
|
3c2eb96243 | ||
|
|
de313586ab | ||
|
|
e96bda4b9f | ||
|
|
d9944c03c4 | ||
|
|
b9d6d547b8 | ||
|
|
622b031e27 | ||
|
|
26f5c8b9d5 | ||
|
|
e1601d2eb5 | ||
|
|
bc14fc35d7 | ||
|
|
f660f22623 | ||
|
|
300f67d78f | ||
|
|
8a3ecfe5c1 | ||
|
|
ced0019b6c | ||
|
|
5d88528fe4 | ||
|
|
1572248866 | ||
|
|
d26916199b | ||
|
|
2e9fb7d840 | ||
|
|
7a086bef08 | ||
|
|
777082a7b8 | ||
|
|
a4e3d88c67 | ||
|
|
06b903f807 | ||
|
|
d2869ab348 | ||
|
|
072c8aa39b | ||
|
|
5bd92d4c60 | ||
|
|
d6c194265f | ||
|
|
3f938e29b6 | ||
|
|
037b77555e | ||
|
|
51b9e86d13 | ||
|
|
cbf6fd021a | ||
|
|
b093d19262 | ||
|
|
7c698a9c3a | ||
|
|
17f531890a | ||
|
|
dac58bb651 | ||
|
|
4a403ae00f | ||
|
|
2c41600957 | ||
|
|
58a3293efc | ||
|
|
0906181d75 | ||
|
|
d5fcc9271a | ||
|
|
844c671bf1 | ||
|
|
7ff6b97e5c | ||
|
|
d679bbc802 | ||
|
|
6d88281357 | ||
|
|
32787a9f22 | ||
|
|
9709dfd563 | ||
|
|
6dd5a75d13 | ||
|
|
9c04d0c956 | ||
|
|
c3e74f02c2 | ||
|
|
cb56cd70f5 | ||
|
|
de0395bee9 | ||
|
|
abb5b14281 | ||
|
|
2289bb7c19 | ||
|
|
746ef89745 | ||
|
|
ffc0b4863b | ||
|
|
89f8d71001 | ||
|
|
a2878bff67 | ||
|
|
34cfa55f58 | ||
|
|
7dd5484cb5 | ||
|
|
37f1d43ce3 | ||
|
|
07b5d97a3a | ||
|
|
cb841de3fc | ||
|
|
e12f397140 | ||
|
|
3a22028042 | ||
|
|
f12264723d | ||
|
|
65f14624c8 | ||
|
|
30016a7e19 | ||
|
|
e8abbc7045 | ||
|
|
235f92ce09 | ||
|
|
22fc10911a | ||
|
|
11ae201d71 | ||
|
|
8586efda0b | ||
|
|
9e382ba691 | ||
|
|
accb645d3f | ||
|
|
620496f5cd | ||
|
|
73cd96838e | ||
|
|
82080b044b | ||
|
|
93b25ce014 | ||
|
|
f883465263 | ||
|
|
ba049fcaf8 | ||
|
|
ba47abb473 | ||
|
|
b9a1a586c0 | ||
|
|
7b19b4114c | ||
|
|
3e9c2ecc85 | ||
|
|
3940032cd3 | ||
|
|
d2d0c665b1 | ||
|
|
50aa3587d4 | ||
|
|
0bc834e6f3 | ||
|
|
dd24f6a18d | ||
|
|
462e9d4822 | ||
|
|
48ac0a64c6 | ||
|
|
cf4901da2d | ||
|
|
9f20fadee1 | ||
|
|
0f7a309adc | ||
|
|
c771167b6a | ||
|
|
e1cf93640c | ||
|
|
1716f140b7 | ||
|
|
586a7d22e7 | ||
|
|
cab9294f62 | ||
|
|
98a24fc8f9 | ||
|
|
bbc7c59563 | ||
|
|
b122d3b8e5 | ||
|
|
46e769a113 | ||
|
|
79545187b8 | ||
|
|
413a83c2e2 | ||
|
|
ab08eebfc1 | ||
|
|
ac4c56f636 | ||
|
|
1db7d57a24 | ||
|
|
e32ca98ccf | ||
|
|
5a635db262 | ||
|
|
c87bc1d55f | ||
|
|
5c63975097 | ||
|
|
fee905a34a |
311
ChangeLog
311
ChangeLog
@@ -1,3 +1,302 @@
|
||||
Changes between v5.5 and v5.6:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (52):
|
||||
build: avoid a warning about duplicate symbol when building from tarball
|
||||
build: detect a build from git also when building out of tree
|
||||
build: include a workaround only for versions of ncurses that need it
|
||||
bump version numbers and add a news item for the 5.6 release
|
||||
color: do not look for another 'end' match after already finding one
|
||||
color: give highlighted text its own color, to not look like marked text
|
||||
color: recompile the file-probing regexes a little faster with REG_NOSUB
|
||||
color: use bright yellow to highlight a search match
|
||||
color: use inverse video for highlighting when there are no colors
|
||||
debug: add timing instruments to cache precalculation and screen refresh
|
||||
display: for a large paste or insertion, recalculate the multiline cache
|
||||
docs: correct the description of --quickblank for the changed base value
|
||||
docs: correct the formatting of a comment in the sample nanorc
|
||||
docs: correct the word order for Alt+D in the cheat sheet -- it changed
|
||||
docs: mention the new 'set highlightcolor' option
|
||||
docs: remove all mentions of --markmatch and 'set markmatch'
|
||||
docs: say that --minibar is modified by --constantshow and --stateflags
|
||||
feedback: make Full Justify show a message also when using --minibar
|
||||
gnulib: update to its current upstream state
|
||||
minibar: show a message a little longer when --quickblank isn't used
|
||||
minibar: show cursor position + character code only with --constantshow
|
||||
minibar: show the state flags only when --stateflags is used
|
||||
minibar: suppress the toggling feedback for M-C, but show it for M-Y/M-P
|
||||
options: remove --markmatch and 'set markmatch', as the behavior is gone
|
||||
painting: always do backtracking for the first row of the screen
|
||||
painting: trigger a refresh when a second start match appears on a line
|
||||
painting: trigger fewer unneeded full-screen refreshes
|
||||
painting: when finding an end match, set its multidata right away
|
||||
scrolling: keep centering after large paste, also when line numbers widen
|
||||
search: just highlight the found occurrence, instead of marking it
|
||||
search: make highlighting the standard, non-changeable behavior
|
||||
tweaks: avoid the vague possibility of advancing beyond end-of-line
|
||||
tweaks: be slightly more efficient in marking lines as WOULDBE
|
||||
tweaks: call wattron()/wattroff() only when actually painting something
|
||||
tweaks: correct a comment, improve another, and trim some verbosity
|
||||
tweaks: don't bother comparing virgin multidata with current situation
|
||||
tweaks: don't bother initializing freshly allocated multidata
|
||||
tweaks: don't bother wiping the multidata before recomputing it
|
||||
tweaks: elide a function that is now just one line
|
||||
tweaks: frob a condition, to be more concise, and reshuffle another
|
||||
tweaks: frob some comments, and adjust indentation after previous change
|
||||
tweaks: frob some comments, and reshuffle two fragments of code
|
||||
tweaks: frob two fragments of code, to be more readable
|
||||
tweaks: make a skipping condition more precise
|
||||
tweaks: remove an old fix that was made superfluous by a recent fix
|
||||
tweaks: remove a strangely placed warning
|
||||
tweaks: rename six symbols, to be more straightforward
|
||||
tweaks: reshuffle some code, and reduce the scope of a variable
|
||||
tweaks: reshuffle three conditions into a better order
|
||||
tweaks: rewrap and reindent a few lines
|
||||
tweaks: rewrap two lines, for esthetics
|
||||
tweaks: stop evaluating a rule when the match is offscreen to the right
|
||||
|
||||
|
||||
Changes between v5.4 and v5.5:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (84):
|
||||
build: fix compilation for --enable-{tiny,help,multibuffer}
|
||||
build: fix compilation when configured with --disable-utf8
|
||||
build: fix compilation when configured with --enable-tiny
|
||||
build: remove the '--with-slang' configure option
|
||||
bump version numbers and add a news item for the 5.5 release
|
||||
chars: short-circuit determining the width of characters under U+0300
|
||||
chars: speed up the handling of invalid UTF-8 starter bytes
|
||||
copyright: update the years for the FSF
|
||||
display: add code for showing minimal state-information bar at the bottom
|
||||
display: do not show the state flags in the help viewer or file browser
|
||||
docs: explain the effect of --minibar / -_ / 'set minibar'
|
||||
docs: explain the purpose of --markmatch / -^ / 'set markmatch'
|
||||
docs: insert links to the mailing-list archives into the README
|
||||
docs: mention in NEWS that some workarounds were removed
|
||||
docs: mention the new 'set promptcolor' option
|
||||
docs: remove all mentions of Slang
|
||||
feedback: differentiate between remarks, mistakes, and information
|
||||
feedback: wipe the status bar by default after 20 keystrokes
|
||||
files: when truncating a file name, give an indication of this
|
||||
general: remove support for Slang
|
||||
gnulib: update to its current upstream state
|
||||
input: intercept ^Z also when --minibar is active
|
||||
input: interpret a keystroke as Meta only when an earlier escape was solo
|
||||
memory: avoid leaking the speller or linter command string, when invoked
|
||||
minibar: add an [x/y] "counter" when multiple files are open
|
||||
minibar: add a percentage that shows how far the cursor is into the file
|
||||
minibar: allow the number-of-lines to overrule also the state flags
|
||||
minibar: allow the number-of-lines to overrule location + character code
|
||||
minibar: drop the side spaces before suppressing the state flags
|
||||
minibar: represent bytes as 0xNN and valid Unicode code points as U+NNNN
|
||||
minibar: show the info bar again some 0.8 seconds after a message
|
||||
minibar: show the line count in the bar (at startup and when saving)
|
||||
minibar: show Unicode codes when in a UTF-8 locale
|
||||
minibar: suppress some elements when there is no room to show them
|
||||
minibar: when the next character has zero width, show its code too
|
||||
minibar: when the overnext character has zero width too, show its code
|
||||
mouse: do not offset the shortcuts by 'margin' when using --linenumbers
|
||||
oops: use the correct condition for checking the last line will change
|
||||
options: accept 'set promptcolor' for setting the color of the prompt bar
|
||||
options: add --markmatch and -^ for activating the select-match behavior
|
||||
options: add --minibar and -_ for activating basic state-information bar
|
||||
prompt: restore a workaround for a cursor misplacement bug in ncurses
|
||||
prompt: suppress the ">" character always when exactly at the right edge
|
||||
rcfile: rename 'nowrap' toggle to 'breaklonglines', to match the option
|
||||
search: set the mark at the end of a found match so it gets highlighted
|
||||
search: suppress the cursor when highlighting a match
|
||||
speller: do an internal spell check when --speller is an empty string
|
||||
speller: strip leading whitespace from command, to avoid a sneaky crash
|
||||
syntax: go: add author and license line
|
||||
syntax: nanorc: colorize 'bookstyle' as a valid option
|
||||
syntax: nanorc: colorize 'set promptcolor' as valid
|
||||
syntax: sh: recognize shebangs with any shell after 'env', not just 'sh'
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: avoid compilation warnings on 32-bit machine plus newer compiler
|
||||
tweaks: avoid computing the cursor column twice, and the "page" too
|
||||
tweaks: avoid hitting negative values when using size_t
|
||||
tweaks: change an intermediate variable to a better one
|
||||
tweaks: clean up after the previous change
|
||||
tweaks: condense the description of how to report a bug
|
||||
tweaks: correct a translator hint
|
||||
tweaks: correct two comments after the previous changes
|
||||
tweaks: do not change the pointer, but move the content of the string
|
||||
tweaks: drop a small optimization for invalid UTF-8 starter bytes
|
||||
tweaks: elide a variable, by using a reallocation instead
|
||||
tweaks: fold some conditions into bitwise masks, for efficiency
|
||||
tweaks: fold two similar and three identical cases together
|
||||
tweaks: move 'set indicator' to its alphabetical place in the manual
|
||||
tweaks: move the displaying of the state letters into a separate function
|
||||
tweaks: push back the deprecation of the 'set nowrap' option
|
||||
tweaks: put the new options in a consistent order in the code
|
||||
tweaks: reduce the scope of a static variable
|
||||
tweaks: remove some #ifdefs that were there only for Slang
|
||||
tweaks: rename a variable, to be similar to its sister
|
||||
tweaks: reshuffle a condition, to probably avoid an unneeded calculation
|
||||
tweaks: reshuffle an option, to have two related ones grouped together
|
||||
tweaks: reshuffle some lines, to group things better
|
||||
tweaks: reshuffle some lines, to have most #includes near the beginning
|
||||
tweaks: reshuffle some more lines, to have most #defines together
|
||||
tweaks: reshuffle two lines, and rename a variable to a plain word
|
||||
tweaks: reword the description of an option
|
||||
tweaks: simplify a bit of logic
|
||||
tweaks: use a boolean instead of an enumeration of two values
|
||||
undo: remove the added magic line when a replacement caused one
|
||||
weeding: remove some obsolete information from the README
|
||||
|
||||
OIX (1):
|
||||
mouse: update title bar (the M flag) when the click is on the cursor
|
||||
|
||||
|
||||
Changes between v5.3 and v5.4:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (31):
|
||||
bindings: accept b for scrolling back up in help viewer and file browser
|
||||
build: exclude a workaround for VTE/Konsole when using a recent ncurses
|
||||
build: include a workaround for VTE only when using an older libvte
|
||||
bump version numbers and add a news item for the 5.4 release
|
||||
copyright: update to the current year for significantly changed files
|
||||
docs: adjust for the changed name of the header-file package on Debian
|
||||
docs: use standard-compliant HTML entities for the four arrows
|
||||
feedback: abort when user tries to open multiple files in tiny version
|
||||
gnulib: update to its current upstream state
|
||||
help: allow the penultimate item extra space when the number is uneven
|
||||
help: show all valid help items also in the Write-Out menu
|
||||
linting: avoid putting the cursor beyond the end of the line
|
||||
moving: skip combining characters and other zero-width characters
|
||||
options: do not spew out the help text when an option is not recognized
|
||||
prompt: skip over combining characters also when editing a search string
|
||||
rcfile: stop accepting 'set view' in a nanorc file, and undocument it
|
||||
statusbar: properly pluralize the line+word+character count report
|
||||
tweaks: avoid copying an option's argument when there is no need
|
||||
tweaks: normalize the formatting after the previous two changes
|
||||
tweaks: rename two variables and improve two comments
|
||||
tweaks: rename two variables, one for contrast, another for visibility
|
||||
tweaks: reshuffle a fragment of code, for clarity
|
||||
tweaks: reshuffle a line, elide two braces, and adjust the indentation
|
||||
tweaks: reshuffle three lines and elide braces after the previous change
|
||||
tweaks: slightly shorten a loop, to place the actual action outside of it
|
||||
tweaks: use the standard symbols for the three standard file descriptors
|
||||
utils: die when trying to allocate zero bytes
|
||||
weeding: remove another unneeded workaround for VTE
|
||||
weeding: remove a workaround for early versions of ncurses-6.0
|
||||
weeding: remove a workaround for versions of ncurses before 5.9
|
||||
weeding: remove a workaround for VTE that is not needed
|
||||
|
||||
|
||||
Changes between v5.2 and v5.3:
|
||||
------------------------------
|
||||
|
||||
Arturo Borrero González (1):
|
||||
syntax: nftables: include author and license lines
|
||||
|
||||
Benno Schulenberg (92):
|
||||
browser: make M-W/M-Q functional right after startup, if there is history
|
||||
browser: sort names that differ only in case with uppercase first
|
||||
browser: wipe the status bar before searching again with M-W or M-Q
|
||||
build: abort the update script if a PO file contains a control character
|
||||
build: avoid two compiler warnings when gnulib has been ripped out
|
||||
build: do not accept --enable-libmagic when not having color support
|
||||
build: do not let Slang translate escape sequences to key codes
|
||||
build: exclude bunches of raw escape sequences from the tiny version
|
||||
build: exclude --emptyline, --jumpyscrolling, and --noread from tiny nano
|
||||
build: exclude excessive version information from the tiny version
|
||||
build: exclude option --tabsize (-T) from the tiny version
|
||||
build: exclude reading a file from standard input from the tiny version
|
||||
build: exclude the three --help column headers from the tiny version
|
||||
build: include some raw sequences for the graphical Debian installer
|
||||
build: stop using an obsolete macro, and use 'void' for signal handlers
|
||||
build: to verify wide curses, probe for a function that cannot be a macro
|
||||
bump version numbers and add a news item for the 5.3 release
|
||||
chars: reduce searching time with roughly 85 percent for plain ASCII
|
||||
display: do not unnecessarily wipe the status bar
|
||||
display: do not wipe the status bar when the terminal has just one row
|
||||
display: force the cursor to reappear after a message (when using Slang)
|
||||
display: force the cursor to reappear in a better way (when using Slang)
|
||||
display: skip a special-case refresh when a message was written
|
||||
docs: add a link to the website also to the info manual
|
||||
docs: add the customary (1) after the name of command-line programs
|
||||
docs: condense the descriptions of cutting and pasting
|
||||
docs: explain the purpose of -! / --magic / 'set magic'
|
||||
docs: explain the 'set scrollercolor' option, for coloring the indicator
|
||||
docs: explain what the options --stateflags (-%) and 'set stateflags' do
|
||||
docs: improve two wordings in the sample nanorc
|
||||
docs: mention that syntax definitions are available in /usr/share/nano/
|
||||
feedback: don't give a hint for <Bsp>, and not after an Alt+key was used
|
||||
feedback: in the tiny version, let M-H show the helpful hint too
|
||||
feedback: make an "Unbound key" message disappear on the next keystroke
|
||||
feedback: show a helpful message for ^G even when there is no help
|
||||
feedback: show helpful message for the first ^H at the top of the file
|
||||
gnulib: update to its current upstream state
|
||||
help: do not leave the cursor on the status bar after a search
|
||||
help: do not show "^G Help" in the tiny version when there is no help
|
||||
help: ensure the help lines are always drawn, also when using Slang
|
||||
help: in the tiny version, show Prev/Next Word before Backward/Forward
|
||||
help: nicely pair menu items also when built with just --disable-help
|
||||
new feature: option --stateflags to show some states in top-right corner
|
||||
options: add -? as a synonym of -h (--help), but leave it undocumented
|
||||
options: move --stateflags (-%) and --magic (-!) to the end of the list
|
||||
options: require --magic or 'set magic' to enable the use of libmagic
|
||||
rcfile: add 'set scrollercolor', for changing the color of the indicator
|
||||
suspension: do not enter an invalid byte upon resume (when using Slang)
|
||||
suspension: properly resume from an external SIGSTOP
|
||||
suspension: resume properly from an external SIGSTOP (when using Slang)
|
||||
suspension: switch off flow control at the right moment (for Slang)
|
||||
syntaxes: add author and license lines to four of the files
|
||||
syntax: nanorc: stop coloring 'morespace' and 'smooth' as valid
|
||||
syntax: nanorc: stop coloring 'nopauses' and 'nowrap' as valid
|
||||
syntax: nanorc: stop coloring 'quiet' and 'backwards' and 'finalnewline'
|
||||
syntax: po: do not leave the occasional tab with a red background color
|
||||
syntax: po: highlight embedded control codes that shouldn't be there
|
||||
syntax: sh: recognize some shell scripts by their Emacs modeline
|
||||
tweaks: add a hint for translators
|
||||
tweaks: add some comments to the C syntax, and sort some keywords
|
||||
tweaks: adjust some whitespace in the docs, and improve a comment
|
||||
tweaks: avoid a compiler warning when compiling with more than -O1
|
||||
tweaks: condense a bit of code
|
||||
tweaks: condense a bit of code after the previous change
|
||||
tweaks: drop the unneeded saving and restoring of a global variable
|
||||
tweaks: dummy commit, to add some info about the previous one
|
||||
tweaks: elide a one-line function, after reducing it to a single call
|
||||
tweaks: fold one function into another, to elide an unneeded return value
|
||||
tweaks: harmonize the spelling of a compound word, and rewrap a section
|
||||
tweaks: harmonize the style of error messages and warnings in ./configure
|
||||
tweaks: make two of the changes that 'autoupdate' suggests
|
||||
tweaks: move three functions, to before the ones that call them
|
||||
tweaks: move two more functions, to before the ones that call them
|
||||
tweaks: move two more functions, to before the one that calls them
|
||||
tweaks: normalize the indentation after the previous change
|
||||
tweaks: remove an inconsistent newline from the end of an error message
|
||||
tweaks: remove an unused element from 'funcstruct', saving 8 more bytes
|
||||
tweaks: remove mistaken escape sequences for function keys on xterm
|
||||
tweaks: remove two stray comments and two lines that were commented out
|
||||
tweaks: rename another variable, away from being misnamed
|
||||
tweaks: rename four variables, reshuffle them, and correct one type
|
||||
tweaks: rename two elements of history struct, away from abbreviations
|
||||
tweaks: rename two variables, to be more distinct
|
||||
tweaks: replace two more occurrences of 'AC_TRY_RUN' with 'AC_RUN_IFELSE'
|
||||
tweaks: reshuffle a condition, to elide a blank string
|
||||
tweaks: reshuffle some lines after the previous change
|
||||
tweaks: reshuffle some lines and adjust indentation after previous change
|
||||
tweaks: reshuffle two lines and a function name, for a consistent order
|
||||
tweaks: rewrap nine more old NEWS items, for balanced line lengths
|
||||
tweaks: rewrap three NEWS items, for more balanced line lengths
|
||||
tweaks: stop 'autoupdate' from failing with "end of file in string"
|
||||
version: remove URL and email address from the --version output
|
||||
|
||||
Hussam al-Homsi (5):
|
||||
syntax: c: colorize also one-character constants, and the null directive
|
||||
syntax: c: colorize also the keywords that start with an underscore
|
||||
syntax: c: colorize also the 'restrict' keyword, and the #line directive
|
||||
tweaks: reorder a member of 'funcstruct', to save 8 bytes of padding
|
||||
tweaks: stop casting the return of malloc() and friends
|
||||
|
||||
Ryan Westlund (1):
|
||||
syntax: markdown: add author and license line
|
||||
|
||||
|
||||
Changes between v5.1 and v5.2:
|
||||
------------------------------
|
||||
|
||||
@@ -216,7 +515,7 @@ Benno Schulenberg (374):
|
||||
locking: prevent a symlink attack by not opening an existing lock file
|
||||
memory: plug a leak, by freeing the cutbuffer after a bracketed paste
|
||||
menus: remove unneeded words and shortenings from key labels
|
||||
new feature: a position-plus-portion indicator on the righthand side
|
||||
new feature: a position-plus-portion indicator on the right-hand side
|
||||
oops -- restore an accidentally changed file
|
||||
options: add --indicator and -q for switching on the scroll-bar thing
|
||||
options: add -O/--bookstyle to make leading whitespace mean new paragraph
|
||||
@@ -276,7 +575,7 @@ Benno Schulenberg (374):
|
||||
tweaks: adjust the conditional help-item pairing for absence of speller
|
||||
tweaks: adjust the file format indicator in a quicker way
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweask: adjust the indentation after the previous change
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: avoid a compiler warning
|
||||
tweaks: avoid a function call when a simple boolean will do
|
||||
tweaks: avoid an unnecessary refresh for zero or just one completion
|
||||
@@ -876,7 +1175,7 @@ Benno Schulenberg (166):
|
||||
tweaks: reshuffle some declarations, and expand a few variable names
|
||||
tweaks: reshuffle some lines, to avoid tallying the menus when not needed
|
||||
tweaks: reshuffle some lines, to group all ignored keystrokes together
|
||||
tweaks: reshuffle three lines, to make the grouping tighther
|
||||
tweaks: reshuffle three lines, to make the grouping tighter
|
||||
tweaks: reshuffle two lines, to do the linking first, then the content
|
||||
tweaks: reword two comments, and rewrap another
|
||||
tweaks: rewrap a comment and a line, and reshuffle a fragment of code
|
||||
@@ -1340,7 +1639,7 @@ Benno Schulenberg (235):
|
||||
tweaks: elide a pre-processor #else clause, by using braces instead
|
||||
tweaks: elide a variable, drop a comment, and remove unneeded braces
|
||||
tweaks: elide two unneeded variables
|
||||
tweaks: enforce the miminum amount of scrolling in a simpler way
|
||||
tweaks: enforce the minimum amount of scrolling in a simpler way
|
||||
tweaks: exclude a bug check from the tiny version
|
||||
tweaks: exclude another bug check from the tiny version
|
||||
tweaks: factor out a fragment of code that is repeated three times
|
||||
@@ -1360,7 +1659,7 @@ Benno Schulenberg (235):
|
||||
tweaks: move a function to the file where it is used
|
||||
tweaks: move an assignment that is useful only when searching forward
|
||||
tweaks: move a syntax check to a better place, to reduce duplication
|
||||
tweaks: move the tyding-up-after-a-search to a single exit point
|
||||
tweaks: move the tidying-up-after-a-search to a single exit point
|
||||
tweaks: normalize the indentation after the previous two changes
|
||||
tweaks: place a function better, and reduce some comments to a single one
|
||||
tweaks: put some timing code back into the search function
|
||||
@@ -1566,7 +1865,7 @@ Benno Schulenberg (85):
|
||||
tweaks: rename a variable, to be more distinct and more descriptive
|
||||
tweaks: rename a variable, to get out of the way for another rename
|
||||
tweaks: rename some variables, for more contrast and to match others
|
||||
tweaks: rename some variables, to be less repititious
|
||||
tweaks: rename some variables, to be less repetitious
|
||||
tweaks: rename two variables, for more contrast
|
||||
tweaks: rename two variables, to be more distinct and more fitting
|
||||
tweaks: rename two variables, to make more sense
|
||||
|
||||
@@ -2,6 +2,12 @@ Improvements in GNU nano
|
||||
========================
|
||||
|
||||
Since 5.0:
|
||||
- A search highlights the found text, in black on yellow by default.
|
||||
- Option --minibar reduces the interface to a bottom bar with basic info.
|
||||
- The cursor skips over combining characters, <Del> deletes them together
|
||||
with the character they combine with, but <Bsp> deletes them separately.
|
||||
- For using libmagic the option --magic or -! or 'set magic' is required.
|
||||
- With --stateflags the state of some things is shown in the title bar.
|
||||
- M-Bsp deletes a word leftward.
|
||||
- With --indicator a "scrollbar" is shown, indicating position+portion.
|
||||
- M-Ins places an anchor, M-PgUp/M-PgDn jump to the nearest anchor.
|
||||
|
||||
244
NEWS
244
NEWS
@@ -1,3 +1,52 @@
|
||||
2021.02.24 - GNU nano 5.6 "Wielewaal"
|
||||
• A search match gets highlighted (in black on yellow by default),
|
||||
in addition to placing the cursor at the start of the match.
|
||||
The color combination can be changed with 'set highlightcolor'.
|
||||
By default the cursor is hidden until the next keystroke, but
|
||||
it can be forced on with --showcursor / 'set showcursor'.
|
||||
• Option --markmatch / 'set markmatch' has been removed.
|
||||
• Cursor position and character code are displayed in the minibar
|
||||
only when option --constantshow / 'set constantshow' is used,
|
||||
and their display can be toggled with M-C.
|
||||
• The state flags are displayed in the minibar only when option
|
||||
--stateflags / 'set stateflags' is used.
|
||||
|
||||
2021.01.14 - GNU nano 5.5 "Rebecca"
|
||||
• Option 'set minibar' makes nano suppress the title bar and instead
|
||||
show a bar with basic editing information at the bottom: file name
|
||||
(plus an asterisk when the buffer is modified), the cursor position
|
||||
(line,column), the character under the cursor (U+xxxx), the flags
|
||||
that --stateflags normally shows, plus the percentage of the buffer
|
||||
that is above the cursor.
|
||||
• With 'set promptcolor' the color combination of the prompt bar can
|
||||
be changed, to allow contrasting it with the mini bar (which always
|
||||
has the same color as the title bar).
|
||||
• Option 'set markmatch' highlights the result of a successful search
|
||||
by putting the mark at the end of the match, making the match more
|
||||
visible. It also suppresses the cursor until the next keystroke.
|
||||
(If you dislike the hiding of the cursor, use 'set showcursor'.)
|
||||
• The bindable toggle 'nowrap' has been renamed to 'breaklonglines',
|
||||
to match the corresponding option, like for all other toggles.
|
||||
• Support for Slang has been removed.
|
||||
|
||||
2020.12.02 - GNU nano 5.4 "Terre des hommes"
|
||||
• Moving the cursor now skips over combining characters (and other
|
||||
zero-width characters). Deleting a character deletes also any
|
||||
succeeding zero-width characters, but backspacing deletes just
|
||||
one character at a time.
|
||||
• Workarounds for older ncurses and older libvtes were removed.
|
||||
|
||||
2020.10.07 - GNU nano 5.3 "Revolution!"
|
||||
• Option 'set stateflags' makes nano show the state of auto-indenting,
|
||||
the mark, hard-wrapping, macro recording, and soft-wrapping in the
|
||||
title bar. The flags take the place of "Modified", and a modified
|
||||
buffer is instead indicated by an asterisk (*) after its name.
|
||||
• Nano no longer by default tries using libmagic to determine the type
|
||||
of a file (when neither filename nor first line gave a clue), because
|
||||
in most cases it is a waste of time. It requires using the option
|
||||
--magic or -! or 'set magic' to make nano try libmagic.
|
||||
• The color of the indicator can be changed with 'set scrollercolor'.
|
||||
|
||||
2020.08.24 - GNU nano 5.2 "Ranrapalca"
|
||||
• Making certain replacements after a large paste does not crash.
|
||||
• Hitting a toggle at the Search prompt does not clear the answer.
|
||||
@@ -529,7 +578,7 @@
|
||||
|
||||
2016.02.12 - GNU nano 2.5.2 is carrying too many dogs. This release
|
||||
includes several fixes for various memory leaks, position-
|
||||
history size growth, and a long standing issue with using
|
||||
history size growth, and a long-standing issue with using
|
||||
nano under sudo creating root-owned files. There are also
|
||||
the usual bevy of documentation and other miscellaneous
|
||||
fixes and touchups. Upgrade today while supplies last,
|
||||
@@ -771,28 +820,27 @@
|
||||
|
||||
2009.11.30 - GNU nano 2.2.0 "Doc Brown" is released! The culmination
|
||||
of almost two years of development and hot on the heels
|
||||
of nano's 10th birthday is available for all your
|
||||
editing needs! Bugs fixed since the last release
|
||||
include several fixes for tiny mode (involving both
|
||||
the help keys and replace menu text), more 'final'
|
||||
fixes for soft wrapping, and several typo and documentation
|
||||
updates including nanorc tweaks and a new syntax
|
||||
highlighting file for makefiles. Also included is a long
|
||||
standing fix for random crashing when using nanorc on
|
||||
FreeBSD, and nano will no longer clear the screen on
|
||||
suspend to maintain compatibility with other *nix editors.
|
||||
For those who haven't been playing along at home, please
|
||||
see the official web page for the summary of new
|
||||
features since 2.0. Special thanks to all who have
|
||||
submitted bug reports recently in support of our new
|
||||
stable release, and apologies for all those bugs we
|
||||
didn't yet find :-) Peace to all.
|
||||
of nano's 10th birthday is available for all your editing
|
||||
needs! Bugs fixed since the last release include several
|
||||
fixes for tiny mode (involving both the help keys and
|
||||
replace menu text), more 'final' fixes for soft wrapping,
|
||||
and several typo and documentation updates including nanorc
|
||||
tweaks and a new syntax highlighting file for makefiles.
|
||||
Also included is a long-standing fix for random crashing
|
||||
when using nanorc on FreeBSD, and nano will no longer clear
|
||||
the screen on suspend to maintain compatibility with other
|
||||
*nix editors. For those who haven't been playing along at
|
||||
home, please see the official web page for the summary of
|
||||
new features since 2.0. Special thanks to all who have
|
||||
submitted bug reports recently in support of our new stable
|
||||
release, and apologies for all those bugs we didn't yet
|
||||
find :-) Peace to all.
|
||||
|
||||
|
||||
2009.11.21 - GNU nano 2.1.99pre2 is available for a special pre-Black
|
||||
Friday discount. Included are some (hopefully final)
|
||||
fixes for issues with last page display caused by the
|
||||
soft wrapping code, and a fix for a long standing issue
|
||||
soft wrapping code, and a fix for a long-standing issue
|
||||
with hitting the Home key when going through the search
|
||||
history. On the features front, nano will now attempt to
|
||||
retain the proper ownership and permissions when trying
|
||||
@@ -924,7 +972,7 @@
|
||||
contains fixes for binding bad keys, some
|
||||
configure-specific compilation failures, and more issues
|
||||
with the new input back end and in particular the status
|
||||
bar. Also fixed are some long standing issues with
|
||||
bar. Also fixed are some long-standing issues with
|
||||
compiling on AIX, and a segfault when making the terminal
|
||||
window too small. Rest in Peace Tim and George!
|
||||
|
||||
@@ -1105,7 +1153,7 @@
|
||||
|
||||
2005.12.23 - GNU nano 1.3.10 rises to the surface. This release
|
||||
contains several new features as well as fixes for
|
||||
several longstanding bugs. The former include the
|
||||
several long-standing bugs. The former include the
|
||||
ability to scroll up or down single lines without
|
||||
scrolling the cursor, reworked bracket searching code
|
||||
that doesn't require regular expression support,
|
||||
@@ -1327,38 +1375,37 @@
|
||||
and enjoy GNU nano 1.2.0.
|
||||
|
||||
|
||||
2003.02.13 - GNU nano 1.1.99pre3 "The last testing version, no
|
||||
really!" is released. This release includes fixes for
|
||||
wrapping (again), resizing, color syntax highlighting,
|
||||
rcfile parsing, the mouse code, more memory leaks, and
|
||||
some reversion of the code to get the user's home
|
||||
directory (nano will now again rely on $HOME). There
|
||||
are also translation updates, a new manual page for the
|
||||
nanorc file, and an UPGRADE file detailing the changes
|
||||
since version 1.0. Please submit reports for any bugs
|
||||
you might find to the development team
|
||||
(nano-devel@gnu.org), and enjoy nano almost-1.2.0 ;-)
|
||||
2003.02.13 - GNU nano 1.1.99pre3 "The last testing version, no really!"
|
||||
is released. This release includes fixes for wrapping
|
||||
(again), resizing, color syntax highlighting, rcfile
|
||||
parsing, the mouse code, more memory leaks, and some
|
||||
reversion of the code to get the user's home directory
|
||||
(nano will now again rely on $HOME). There are also
|
||||
translation updates, a new manual page for the nanorc
|
||||
file, and an UPGRADE file detailing the changes since
|
||||
version 1.0. Please submit reports for any bugs you
|
||||
might find to the development team (nano-devel@gnu.org),
|
||||
and enjoy nano almost-1.2.0 ;-)
|
||||
|
||||
2003.02.03 - GNU nano 1.1.99pre2 "bugs in my pockets, bugs in my
|
||||
shoes" is released. There are, not surprisingly, only
|
||||
bugfixes in this release as we move toward the stable
|
||||
1.2.0 release. Fixes are included for translatable
|
||||
string format, subexpression replacement, constant
|
||||
cursor position, invalid search regexes, justify, screen
|
||||
state on SIGHUP and SIGTERM, cutting to end cuts with
|
||||
long lines, many file browser and operating directory
|
||||
bugs, memory and file descriptor leaks, marker code,
|
||||
spell checker, the mouse code with long lines, multiple
|
||||
buffers and non-file open errors, replacement string
|
||||
length, and a silly but serious history message crash.
|
||||
There is also a drastic improvement in CPU utilization
|
||||
for the color regex code.
|
||||
Depending on the number of bugs found in this
|
||||
release, there may be a 1.1.99pre3 or RC1, or just a
|
||||
1.2.0 release. Most of the major bugs seem to have been
|
||||
worked out, so if you are waiting for a good time to
|
||||
test nano before the official 1.2.0 release, this would
|
||||
be the one to use. Happy bug hunting!
|
||||
2003.02.03 - GNU nano 1.1.99pre2 "bugs in my pockets, bugs in my shoes"
|
||||
is released. There are, not surprisingly, only bugfixes
|
||||
in this release as we move toward the stable 1.2.0
|
||||
release. Fixes are included for translatable string
|
||||
format, subexpression replacement, constant cursor
|
||||
position, invalid search regexes, justify, screen state on
|
||||
SIGHUP and SIGTERM, cutting to end cuts with long lines,
|
||||
many file browser and operating directory bugs, memory and
|
||||
file descriptor leaks, marker code, spell checker, the
|
||||
mouse code with long lines, multiple buffers and non-file
|
||||
open errors, replacement string length, and a silly but
|
||||
serious history message crash. There is also a drastic
|
||||
improvement in CPU utilization for the color regex code.
|
||||
Depending on the number of bugs found in this release,
|
||||
there may be a 1.1.99pre3 or RC1, or just a 1.2.0 release.
|
||||
Most of the major bugs seem to have been worked out, so if
|
||||
you are waiting for a good time to test nano before the
|
||||
official 1.2.0 release, this would be the one to use.
|
||||
Happy bug hunting!
|
||||
|
||||
2003.01.17 - GNU nano 1.1.99pre1 "enough already" has been released.
|
||||
This release is, barring bug fixes and documentation
|
||||
@@ -1419,19 +1466,19 @@
|
||||
word and next word, nanorc parser and line wrapping
|
||||
code. Have fun!
|
||||
|
||||
2002.07.25 - At long last! GNU nano 1.1.10 "What didn't we break?" is
|
||||
released. This version of GNU nano features version
|
||||
2002.07.25 - At long last! GNU nano 1.1.10 "What didn't we break?"
|
||||
is released. This version of GNU nano features version
|
||||
0.11.2 of gettext, building with automake 1.6, some new
|
||||
code for displaying control characters, browser
|
||||
improvements, a new backup file option (-B, --backup), a
|
||||
new option to ignore rc files (-I, --ignorercfiles),
|
||||
improvements, a new backup file option (-B, --backup),
|
||||
a new option to ignore rc files (-I, --ignorercfiles),
|
||||
compatibility with -pedantic, handling null characters
|
||||
before EOF, a slightly sportier nanorc.sample and more.
|
||||
Fixes are included for justification,
|
||||
the reading and writing file routines, resizing and fill
|
||||
length, millions of memory leaks, the usage screen was
|
||||
updated, and the --quotestr and --regexp really work
|
||||
now ;-) Enjoy :)
|
||||
Fixes are included for justification, the reading
|
||||
and writing file routines, resizing and fill length,
|
||||
millions of memory leaks, the usage screen was updated,
|
||||
and the --quotestr and --regexp really work now ;-)
|
||||
Enjoy :)
|
||||
|
||||
2002.05.12 - GNU nano 1.1.9 is released, happy Mother's Day! This
|
||||
release includes many new features, including a prepend
|
||||
@@ -1701,7 +1748,7 @@
|
||||
|
||||
2000.11.23 - Happy Thanksgiving! Nano 0.9.21 is our "last version was
|
||||
a big turkey" release. It fixes several bugs introduced
|
||||
by the previous version, as well as a few long- standing
|
||||
by the previous version, as well as a few long-standing
|
||||
display bugs. All 0.9.20 users are strongly encouraged
|
||||
to upgrade to this release.
|
||||
|
||||
@@ -1922,19 +1969,19 @@
|
||||
it is yours to take care of and keep up to date.
|
||||
|
||||
2000.03.01 - Well, to continue my trend of going back on my previous
|
||||
release's comments, nano 0.8.7 is released. The
|
||||
crashing behavior was still occurring, and this most
|
||||
recent fix also fixes some other wrapping problems, so
|
||||
here you go. There may be another release soon, there
|
||||
may not be, is that vague enough? =)
|
||||
release's comments, nano 0.8.7 is released. The crashing
|
||||
behavior was still occurring, and this most recent fix
|
||||
also fixes some other wrapping problems, so here you go.
|
||||
There may be another release soon, there may not be, is
|
||||
that vague enough? =)
|
||||
|
||||
2000.02.25 - More minor bugfixes in 0.8.6, the bizarre behavior at the
|
||||
end of a page has ceased, thankfully. I'm also moving
|
||||
next weekend, so don't be shocked if you don't see a new
|
||||
version of nano next week =-)
|
||||
|
||||
2000.02.11 - Okay, here we go again. Aside from a few minor fixes and
|
||||
some under-the-hood changes, you won't notice much
|
||||
2000.02.11 - Okay, here we go again. Aside from a few minor fixes
|
||||
and some under-the-hood changes, you won't notice much
|
||||
different in this version of nano. I haven't gotten
|
||||
much feedback on the help feature, is it simply amazing
|
||||
or does no one care? Write and let me know! =)
|
||||
@@ -1949,23 +1996,22 @@
|
||||
address nano@asty.org for bugs, etc.
|
||||
|
||||
2000.02.02 - Okay, I hate to go back on what I said in the last release,
|
||||
but I may be changing jobs very soon. I will release
|
||||
version 0.8.2 as is (no i18n, no help menu (yet)). I
|
||||
expect things to settle down by the end of next week,
|
||||
and then I can try to start on the i18n support and help
|
||||
menu; look for these new features in version 0.8.5 to
|
||||
0.9.0.
|
||||
but I may be changing jobs very soon. I will release version
|
||||
0.8.2 as is (no i18n, no help menu (yet)). I expect things
|
||||
to settle down by the end of next week, and then I can try to
|
||||
start on the i18n support and help menu; look for these new
|
||||
features in version 0.8.5 to 0.9.0.
|
||||
|
||||
2000.01.28 - Nano 0.8.1 marks our first official step toward
|
||||
internationalization (i18n) and the help system (^G). I
|
||||
will be merging in Jordi's patches for initial i18n in
|
||||
the next version, and will implement the help system
|
||||
internationalization (i18n) and the help system (^G).
|
||||
I will be merging in Jordi's patches for initial i18n
|
||||
in the next version, and will implement the help system
|
||||
with i18n built into it shortly after that. Please
|
||||
don't hesitate to send bug reports, as long as you're
|
||||
sure the fault lies with nano =-).
|
||||
|
||||
2000.01.25 - Nano 0.8.0 is officially the 'let's try and be at least a
|
||||
little portable, mmmmkay?' release. There are many
|
||||
2000.01.25 - Nano 0.8.0 is officially the "let's try and be at least
|
||||
a little portable, mmmmkay?" release. There are many
|
||||
portability checks and fixes; many thanks to Andy Kahn
|
||||
for his patches. I removed the broken do_spell behavior
|
||||
with the 'spell' program; for now, we only try to call
|
||||
@@ -1975,31 +2021,29 @@
|
||||
2000.01.24 - Nano 0.7.9 features many new features. Among them are a
|
||||
new autoindent feature (-i, --autoindent), tempfile flag
|
||||
like Pico's -t flag (-t, --tempfile), and preliminary
|
||||
spelling program support. The spelling function tries
|
||||
to run 'spell' and then 'ispell' in that order, but you
|
||||
can specify another spelling program with -s or
|
||||
--speller.
|
||||
spelling program support. The spelling function tries to
|
||||
run 'spell' and then 'ispell' in that order, but you can
|
||||
specify another spelling program with -s or --speller.
|
||||
|
||||
2000.01.17 - Nano 0.7.7 is officially the 'way too much stuff changed this
|
||||
release' release. It's the busy time at work for me, so
|
||||
please don't get offended if your patch doesn't get
|
||||
included in the next immediate version of nano. I'm
|
||||
sure all the changes in this release will cause a few
|
||||
bugs, so 0.7.8 will primarily be about fixing those
|
||||
bugs.
|
||||
2000.01.17 - Nano 0.7.7 is officially the "way too much stuff changed
|
||||
this release" release. It's the busy time at work for me,
|
||||
so please don't get offended if your patch doesn't get
|
||||
included in the next immediate version of nano. I'm sure
|
||||
all the changes in this release will cause a few bugs, so
|
||||
0.7.8 will primarily be about fixing those bugs.
|
||||
|
||||
Things added this release include resizability (kinda),
|
||||
new -x and -c flags (see nano -h for help), long command
|
||||
line flag support, and the usual array of bugfixes.
|
||||
|
||||
2000.01.15 - Nano 0.7.6 is officially the 'lightning' release. It now
|
||||
loads large files much faster than previous versions,
|
||||
and is even much faster than Pico or vi in some rather
|
||||
rudimentary tests. Many thanks to Adam Rogoyski for the
|
||||
read_byte patch!
|
||||
2000.01.15 - Nano 0.7.6 is officially the "lightning" release.
|
||||
It now loads large files much faster than previous
|
||||
versions, and is even much faster than Pico or vi
|
||||
in some rather rudimentary tests. Many thanks to
|
||||
Adam Rogoyski for the read_byte patch!
|
||||
|
||||
2000.01.09 - As of this version (0.7.4), TIP has officially been renamed
|
||||
to nano. The new homepage is at
|
||||
http://faculty.plattsburgh.edu/astyanax/nano. Please
|
||||
update your bookmarks, tell your friends, and all that
|
||||
jazz.
|
||||
2000.01.09 - As of this version (0.7.4), TIP has officially
|
||||
been renamed to nano. The new homepage is at
|
||||
http://faculty.plattsburgh.edu/astyanax/nano.
|
||||
Please update your bookmarks, tell your friends,
|
||||
and all that jazz.
|
||||
|
||||
32
README
32
README
@@ -25,7 +25,7 @@ Overview
|
||||
|
||||
How to compile and install nano
|
||||
|
||||
Download the latest nano source tarball, then:
|
||||
Download the latest nano source tarball, and then:
|
||||
|
||||
tar -xvf nano-x.y.tar.gz
|
||||
cd nano-x.y
|
||||
@@ -33,12 +33,13 @@ How to compile and install nano
|
||||
make
|
||||
make install
|
||||
|
||||
It's that simple. Use --prefix with configure to override the
|
||||
default installation directory of /usr/local.
|
||||
You will need the header files of ncurses installed for ./configure
|
||||
to succeed -- get them from libncurses-dev (Debian) or ncurses-devel
|
||||
(Fedora) or a similarly named package. 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
|
||||
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
|
||||
@@ -51,26 +52,25 @@ 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.
|
||||
|
||||
To subscribe, send email to <name>-request@gnu.org with a subject
|
||||
of "subscribe", where <name> is the list you want to subscribe to.
|
||||
|
||||
The archives of the development and help mailing lists are here:
|
||||
|
||||
https://lists.gnu.org/archive/html/nano-devel/
|
||||
https://lists.gnu.org/archive/html/help-nano/
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
If you find a bug, please file a detailed description of the problem
|
||||
on nano's bug tracker: https://savannah.gnu.org/bugs/?group=nano.
|
||||
|
||||
Copyright Years
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ packages:
|
||||
- pkg-config (version >= 0.22)
|
||||
- texinfo (version >= 4.0)
|
||||
|
||||
If you want UTF-8 support, you will also need libncursesw5-dev installed
|
||||
(version >= 5.7), or libslang2-dev (version >= 2.0) if you use --with-slang.
|
||||
You will also need to have the header files for ncurses installed,
|
||||
from libncurses-dev on Debian, ncurses-devel on Fedora, or similar.
|
||||
|
||||
These should all be available in your distro's package manager or software
|
||||
center, or otherwise on any GNU mirror.
|
||||
These should all be available in your distro's package manager or
|
||||
software center, or otherwise on any GNU mirror.
|
||||
|
||||
|
||||
Download the source
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="6a78706ae230ad24bc06d33d9eddca25806ffb2a"
|
||||
gnulib_hash="c9b44f214c7c798c7701c7a281584e262b263655"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
306
configure.ac
306
configure.ac
@@ -1,6 +1,6 @@
|
||||
# Configuration for GNU nano - a small and user-friendly text editor
|
||||
#
|
||||
# Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2014, 2017 Mike Frysinger
|
||||
#
|
||||
# GNU nano is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
AC_INIT([GNU nano], [5.2], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [5.6], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.14])
|
||||
@@ -36,12 +36,12 @@ gl_cv_glob_lists_symlinks=yes
|
||||
|
||||
dnl Checks for programs.
|
||||
|
||||
AC_GNU_SOURCE
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_PROG_CC
|
||||
gl_EARLY
|
||||
gl_INIT
|
||||
AC_PROG_LN_S
|
||||
AC_ISC_POSIX
|
||||
AC_SEARCH_LIBS([strerror], [cposix])
|
||||
AC_SYS_LARGEFILE
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
@@ -59,7 +59,7 @@ AC_DEFINE_DIR([PKGDATADIR], [pkgdatadir], [Where data are placed to.])
|
||||
dnl Whether this is a git repository.
|
||||
|
||||
AC_MSG_CHECKING([whether building from git])
|
||||
if test -f roll-a-release.sh ; then
|
||||
if test -f "$srcdir/roll-a-release.sh" ; then
|
||||
AC_MSG_RESULT([yes])
|
||||
from_git=yes
|
||||
else
|
||||
@@ -73,14 +73,14 @@ dnl Checks for pkg-config and gettext when building from git.
|
||||
if test x$from_git = xyes; then
|
||||
if test ! -f $(aclocal --print-ac-dir)/pkg.m4; then
|
||||
AC_MSG_ERROR([
|
||||
*** The pkg.m4 macros are missing. ***
|
||||
*** The pkg-config package needs to be installed when building from git. ***
|
||||
*** After fixing this problem, rerun ./autogen.sh. ***])
|
||||
*** The pkg.m4 macros are missing.
|
||||
*** The pkg-config package needs to be installed when building from git.
|
||||
*** After fixing this problem, rerun ./autogen.sh.])
|
||||
fi
|
||||
if test "$ac_cv_path_MSGFMT" = ":"; then
|
||||
AC_MSG_ERROR([
|
||||
*** The msgfmt program is missing. ***
|
||||
*** The gettext package needs to be installed when building from git. ***])
|
||||
*** The msgfmt program is missing.
|
||||
*** The gettext package needs to be installed when building from git.])
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -90,12 +90,6 @@ AC_CHECK_HEADERS(libintl.h limits.h pwd.h termios.h sys/param.h)
|
||||
|
||||
dnl Checks for options.
|
||||
|
||||
if test "x$with_slang" = xyes; then
|
||||
if test "x$enable_tiny" != xyes; then
|
||||
AC_MSG_ERROR([--with-slang is supported only together with --enable-tiny])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(browser,
|
||||
AS_HELP_STRING([--disable-browser], [Disable the built-in file browser]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
@@ -112,7 +106,8 @@ AS_HELP_STRING([--disable-color], [Disable color and syntax highlighting]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_color" = xyes; then
|
||||
if test "x$enable_nanorc" != xyes; then
|
||||
AC_MSG_ERROR([--enable-color needs --enable-nanorc to work])
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-color needs --enable-nanorc to work])
|
||||
fi
|
||||
else
|
||||
enable_color=no
|
||||
@@ -120,7 +115,8 @@ if test "x$enable_tiny" = xyes; then
|
||||
fi
|
||||
if test "x$enable_nanorc" = xno; then
|
||||
if test "x$enable_color" = xyes; then
|
||||
AC_MSG_ERROR([--enable-color cannot work with --disable-nanorc])
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-color cannot work with --disable-nanorc])
|
||||
else
|
||||
# Disabling nanorc silently disables color support.
|
||||
enable_color=no
|
||||
@@ -135,7 +131,8 @@ AC_ARG_ENABLE(comment,
|
||||
AS_HELP_STRING([--disable-comment], [Disable the comment/uncomment function]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_comment" = xyes; then
|
||||
AC_MSG_ERROR([--enable-comment cannot work with --enable-tiny])
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-comment cannot work with --enable-tiny])
|
||||
else
|
||||
enable_comment=no
|
||||
fi
|
||||
@@ -160,7 +157,8 @@ AS_HELP_STRING([--disable-help], [Disable the built-in help texts]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_help" = xyes; then
|
||||
if test "x$enable_multibuffer" != xyes; then
|
||||
AC_MSG_ERROR([--enable-help needs --enable-multibuffer to work])
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-help needs --enable-multibuffer to work])
|
||||
fi
|
||||
else
|
||||
enable_help=no
|
||||
@@ -168,7 +166,8 @@ if test "x$enable_tiny" = xyes; then
|
||||
fi
|
||||
if test "x$enable_multibuffer" = xno; then
|
||||
if test "x$enable_help" = xyes; then
|
||||
AC_MSG_ERROR([--enable-help cannot work with --disable-multibuffer])
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-help cannot work with --disable-multibuffer])
|
||||
else
|
||||
# Disabling multibuffer silently disables the help texts.
|
||||
enable_help=no
|
||||
@@ -202,6 +201,18 @@ fi
|
||||
|
||||
AC_ARG_ENABLE(libmagic,
|
||||
AS_HELP_STRING([--disable-libmagic], [Disable detection of file types via libmagic]))
|
||||
if test "x$enable_libmagic" = xyes; then
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_color" != xyes; then
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-libmagic needs --enable-color and --enable-nanorc to work])
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_color" = xno; then
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-libmagic cannot work with --disable-color nor --disable-nanorc])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(linenumbers,
|
||||
AS_HELP_STRING([--disable-linenumbers], [Disable line numbering]))
|
||||
@@ -285,7 +296,8 @@ AC_ARG_ENABLE(wordcomp,
|
||||
AS_HELP_STRING([--disable-wordcomp], [Disable the word-completion function]))
|
||||
if test "x$enable_tiny" = xyes; then
|
||||
if test "x$enable_wordcomp" = xyes; then
|
||||
AC_MSG_ERROR([--enable-wordcomp cannot work with --enable-tiny])
|
||||
AC_MSG_ERROR([
|
||||
*** --enable-wordcomp cannot work with --enable-tiny])
|
||||
else
|
||||
enable_wordcomp=no
|
||||
fi
|
||||
@@ -335,209 +347,16 @@ AS_HELP_STRING([--enable-altrcname], [Specify an alternate rcfile name (default:
|
||||
AC_DEFINE_UNQUOTED(RCFILE_NAME, "$enableval", [Specify an alternate rcfile name (default: .nanorc).]) rcfilename=$enableval
|
||||
fi])
|
||||
|
||||
|
||||
AC_MSG_CHECKING([whether to use slang])
|
||||
CURSES_LIB_NAME=""
|
||||
AC_ARG_WITH(slang,
|
||||
AS_HELP_STRING([--with-slang[=DIR]], [Use the slang library instead of curses]),
|
||||
[ case "$with_slang" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
if test x$with_slang != xyes; then
|
||||
# Add additional search path.
|
||||
LDFLAGS="-L$with_slang/lib $LDFLAGS"
|
||||
CPPFLAGS="-I$with_slang/include $CPPFLAGS"
|
||||
fi
|
||||
|
||||
if test "x$enable_utf8" != xno; then
|
||||
AC_CHECK_HEADER(slcurses.h,
|
||||
AC_MSG_CHECKING([for SLutf8_enable in -lslang])
|
||||
_libs=$LIBS
|
||||
LIBS="$LIBS -lslang"
|
||||
AC_TRY_RUN([
|
||||
#include <slcurses.h>
|
||||
int main(void)
|
||||
{
|
||||
SLutf8_enable(1);
|
||||
return 0;
|
||||
}],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
|
||||
CURSES_LIB_WIDE=yes
|
||||
if test x$with_slang != xyes; then
|
||||
CURSES_LIB="-L${with_slang}/lib -lslang"
|
||||
else
|
||||
CURSES_LIB="-lslang"
|
||||
fi
|
||||
CURSES_LIB_NAME=slang],
|
||||
[AC_MSG_RESULT(no)
|
||||
|
||||
# We might need the term library.
|
||||
for termlib in ncurses curses termcap terminfo termlib; do
|
||||
AC_CHECK_LIB([${termlib}], tputs, [tcap="-l$termlib"])
|
||||
test -n "$tcap" && break
|
||||
done
|
||||
|
||||
AC_MSG_CHECKING([for SLutf8_enable in -lslang $tcap])
|
||||
LIBS="$LIBS $tcap"
|
||||
AC_TRY_RUN([
|
||||
#include <slcurses.h>
|
||||
int main(void)
|
||||
{
|
||||
SLutf8_enable(1);
|
||||
return 0;
|
||||
}],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
|
||||
CURSES_LIB_WIDE=yes
|
||||
if test x$with_slang != xyes; then
|
||||
CURSES_LIB="-L${with_slang}/lib -lslang $tcap"
|
||||
else
|
||||
CURSES_LIB="-lslang $tcap"
|
||||
fi
|
||||
CURSES_LIB_NAME=slang],
|
||||
[AC_MSG_RESULT(no)
|
||||
|
||||
# We might need the math library.
|
||||
AC_MSG_CHECKING([for SLutf8_enable in -lslang $tcap -lm])
|
||||
LIBS="$LIBS -lm"
|
||||
AC_TRY_RUN([
|
||||
#include <slcurses.h>
|
||||
int main(void)
|
||||
{
|
||||
SLutf8_enable(1);
|
||||
return 0;
|
||||
}],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
|
||||
CURSES_LIB_WIDE=yes
|
||||
if test x$with_slang != xyes; then
|
||||
CURSES_LIB="-L${with_slang}/lib -lslang $tcap -lm"
|
||||
else
|
||||
CURSES_LIB="-lslang $tcap -lm"
|
||||
fi
|
||||
CURSES_LIB_NAME=slang],
|
||||
[AC_MSG_RESULT(no)],
|
||||
AC_MSG_WARN([*** Can not use slang when cross-compiling]))],
|
||||
AC_MSG_WARN([*** Can not use slang when cross-compiling]))],
|
||||
AC_MSG_WARN([*** Can not use slang when cross-compiling])),
|
||||
AC_MSG_ERROR([
|
||||
*** The header file slcurses.h was not found. This header file
|
||||
*** is required if you wish to use Slang support. Please either
|
||||
*** install a version of Slang that includes the slcurses.h file
|
||||
*** or do not call the configure script with --with-slang.]))
|
||||
fi
|
||||
|
||||
if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
# Reset libs if the above slang tests failed.
|
||||
if test "x$enable_utf8" != xno; then
|
||||
LIBS=$_libs
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADER(slcurses.h,
|
||||
AC_MSG_CHECKING([for SLtt_initialize in -lslang])
|
||||
_libs=$LIBS
|
||||
LIBS="$LIBS -lslang"
|
||||
AC_TRY_RUN([
|
||||
#include <slcurses.h>
|
||||
int main(void)
|
||||
{
|
||||
SLtt_initialize(NULL);
|
||||
return 0;
|
||||
}],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
|
||||
if test x$with_slang != xyes; then
|
||||
CURSES_LIB="-L${with_slang}/lib -lslang"
|
||||
else
|
||||
CURSES_LIB="-lslang"
|
||||
fi
|
||||
CURSES_LIB_NAME=slang],
|
||||
[AC_MSG_RESULT(no)
|
||||
|
||||
# We might need the term library.
|
||||
for termlib in ncurses curses termcap terminfo termlib; do
|
||||
AC_CHECK_LIB([${termlib}], tputs, [tcap="-l$termlib"])
|
||||
test -n "$tcap" && break
|
||||
done
|
||||
|
||||
AC_MSG_CHECKING([for SLtt_initialize in -lslang $tcap])
|
||||
LIBS="$LIBS $tcap"
|
||||
AC_TRY_RUN([
|
||||
#include <slcurses.h>
|
||||
int main(void)
|
||||
{
|
||||
SLtt_initialize(NULL);
|
||||
return 0;
|
||||
}],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
|
||||
if test x$with_slang != xyes; then
|
||||
CURSES_LIB="-L${with_slang}/lib -lslang $tcap"
|
||||
else
|
||||
CURSES_LIB="-lslang $tcap"
|
||||
fi
|
||||
CURSES_LIB_NAME=slang],
|
||||
[AC_MSG_RESULT(no)
|
||||
|
||||
# We might need the math library.
|
||||
AC_MSG_CHECKING([for SLtt_initialize in -lslang $tcap -lm])
|
||||
LIBS="$LIBS -lm"
|
||||
AC_TRY_RUN([
|
||||
#include <slcurses.h>
|
||||
int main(void)
|
||||
{
|
||||
SLtt_initialize(NULL);
|
||||
return 0;
|
||||
}],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_SLANG, 1, [Define this to use the slang wrappers for curses instead of native curses.])
|
||||
if test x$with_slang != xyes; then
|
||||
CURSES_LIB="-L${with_slang}/lib -lslang $tcap -lm"
|
||||
else
|
||||
CURSES_LIB="-lslang $tcap -lm"
|
||||
fi
|
||||
CURSES_LIB_NAME=slang],
|
||||
[AC_MSG_RESULT(no)],
|
||||
AC_MSG_WARN([*** Can not use slang when cross-compiling]))],
|
||||
AC_MSG_WARN([*** Can not use slang when cross-compiling]))],
|
||||
AC_MSG_WARN([*** Can not use slang when cross-compiling])),
|
||||
AC_MSG_ERROR([
|
||||
*** The header file slcurses.h was not found. This header file
|
||||
*** is required if you wish to use Slang support. Please either
|
||||
*** install a version of Slang that includes the slcurses.h file
|
||||
*** or do not call the configure script with --with-slang.]))
|
||||
fi
|
||||
|
||||
if test "${_libs+set}" = "set"; then
|
||||
LIBS=$_libs
|
||||
fi
|
||||
|
||||
if test x$with_slang != xyes; then
|
||||
LDFLAGS=${_ldflags}
|
||||
fi
|
||||
;;
|
||||
esac], [AC_MSG_RESULT(no)])
|
||||
|
||||
dnl Checks for functions.
|
||||
|
||||
if test "x$enable_utf8" != xno; then
|
||||
AC_CHECK_FUNCS(iswalnum iswpunct mblen mbstowcs mbtowc wctomb)
|
||||
fi
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
|
||||
dnl Checks for available flags.
|
||||
|
||||
AX_CHECK_COMPILE_FLAG([-Wall], [CFLAGS="$CFLAGS -Wall"], [], [])
|
||||
|
||||
dnl Checks for library functions.
|
||||
|
||||
AC_TYPE_SIGNAL
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
@@ -567,9 +386,9 @@ if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
CURSES_LIB=`$NCURSESW_CONFIG --libs`
|
||||
LIBS="$CURSES_LIB $LIBS"
|
||||
CPPFLAGS="`$NCURSESW_CONFIG --cflags` $CPPFLAGS"
|
||||
AC_CHECK_LIB(ncursesw, get_wch, [CURSES_LIB_NAME=ncursesw CURSES_LIB_WIDE=yes])
|
||||
AC_CHECK_LIB(ncursesw, wget_wch, [CURSES_LIB_NAME=ncursesw CURSES_LIB_WIDE=yes])
|
||||
else
|
||||
AC_CHECK_LIB(ncursesw, get_wch, [CURSES_LIB="-lncursesw" CURSES_LIB_NAME=ncursesw CURSES_LIB_WIDE=yes])
|
||||
AC_CHECK_LIB(ncursesw, wget_wch, [CURSES_LIB="-lncursesw" CURSES_LIB_NAME=ncursesw CURSES_LIB_WIDE=yes])
|
||||
fi
|
||||
LIBS="$OLDLIBS"
|
||||
fi
|
||||
@@ -583,7 +402,7 @@ if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
AC_CHECK_HEADERS(curses.h)
|
||||
|
||||
if test "x$enable_utf8" != xno; then
|
||||
AC_CHECK_LIB(curses, get_wch, [CURSES_LIB="-lcurses" CURSES_LIB_NAME=curses CURSES_LIB_WIDE=yes])
|
||||
AC_CHECK_LIB(curses, wget_wch, [CURSES_LIB="-lcurses" CURSES_LIB_NAME=curses CURSES_LIB_WIDE=yes])
|
||||
fi
|
||||
|
||||
if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
@@ -594,7 +413,7 @@ fi
|
||||
if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
AC_MSG_ERROR([
|
||||
*** No curses lib was found. Please install the curses header files
|
||||
*** from libncursesw5-dev (Debian), ncurses-devel (Fedora), or similar.
|
||||
*** from libncurses-dev (Debian), ncurses-devel (Fedora), or similar.
|
||||
*** (Or install ncurses from https://ftp.gnu.org/gnu/ncurses/.)])
|
||||
else
|
||||
AC_MSG_RESULT([ The curses library to be used is: $CURSES_LIB_NAME])
|
||||
@@ -610,8 +429,6 @@ AC_CHECK_LIB([$CURSES_LIB_NAME], [key_defined],
|
||||
[AC_DEFINE(HAVE_KEY_DEFINED, 1, [Define this if your curses library has the key_defined() function.])],
|
||||
[], [$CURSES_LIB])
|
||||
|
||||
dnl Parse any configure options.
|
||||
|
||||
LIBS="$LIBS $CURSES_LIB"
|
||||
|
||||
AC_SUBST(CURSES_LIB)
|
||||
@@ -664,16 +481,16 @@ AC_DEFINE_UNQUOTED(NANO_REG_EXTENDED, $nano_reg_extended,
|
||||
[Flag(s) to use to get the full range of extended regular expressions])
|
||||
|
||||
if test x$color_support = xyes; then
|
||||
# if test x$CURSES_LIB_NAME = xcurses; then
|
||||
AC_MSG_CHECKING([whether _XOPEN_SOURCE_EXTENDED is needed])
|
||||
AC_TRY_RUN([
|
||||
AC_MSG_CHECKING([whether _XOPEN_SOURCE_EXTENDED is needed])
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <curses.h>
|
||||
int main(void)
|
||||
{
|
||||
int testcolor = COLOR_WHITE;
|
||||
return 0;
|
||||
}], AC_MSG_RESULT(no),
|
||||
AC_TRY_RUN([
|
||||
}]])],
|
||||
AC_MSG_RESULT(no),
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
#define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
@@ -682,35 +499,38 @@ int main(void)
|
||||
{
|
||||
int testcolor = COLOR_WHITE;
|
||||
return 0;
|
||||
}],
|
||||
AC_DEFINE(NEED_XOPEN_SOURCE_EXTENDED, 1, [Define this if you need the _XOPEN_SOURCE_EXTENDED macro for color support.])
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(not sure)
|
||||
AC_MSG_WARN([*** Couldn't successfully compile basic color test with or without _XOPEN_SOURCE_EXTENDED])
|
||||
AC_MSG_WARN([*** This build may not compile. Consider configuring with --disable-color or installing ncurses])),
|
||||
AC_MSG_WARN([*** Can't check need for _XOPEN_SOURCE_EXTENDED when cross-compiling]))
|
||||
# fi
|
||||
}]])],
|
||||
AC_DEFINE(NEED_XOPEN_SOURCE_EXTENDED, 1, [Define this if you need the _XOPEN_SOURCE_EXTENDED macro for color support.])
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(not sure)
|
||||
AC_MSG_WARN([
|
||||
*** Couldn't successfully compile basic color test with or without
|
||||
*** _XOPEN_SOURCE_EXTENDED. This build may not compile. Consider
|
||||
*** configuring with --disable-color or installing ncurses.])),
|
||||
AC_MSG_WARN([
|
||||
*** Can't check need for _XOPEN_SOURCE_EXTENDED when cross-compiling.]))
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether LINES and COLS can be redefined])
|
||||
AC_TRY_RUN([
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <curses.h>
|
||||
int main(void)
|
||||
{
|
||||
LINES = 80;
|
||||
COLS = 25;
|
||||
return 0;
|
||||
}],
|
||||
}]])],
|
||||
AC_DEFINE(REDEFINING_MACROS_OK, 1, [Define this if you know your curses library allows LINES and COLS to be redefined to deal with a resizing bug.])
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no),
|
||||
AC_MSG_WARN([*** Can't check for macro redefinability when cross-compiling]))
|
||||
AC_MSG_WARN([
|
||||
*** Can't check for macro redefinability when cross-compiling.]))
|
||||
|
||||
AS_IF([test "x$enable_libmagic" != "xno"], [
|
||||
AC_CHECK_HEADERS([magic.h])
|
||||
AC_CHECK_LIB(magic, magic_open)
|
||||
AC_CHECK_HEADERS([zlib.h])
|
||||
AC_CHECK_LIB(z, inflate)
|
||||
AC_CHECK_HEADERS([magic.h])
|
||||
AC_CHECK_LIB(magic, magic_open)
|
||||
AC_CHECK_HEADERS([zlib.h])
|
||||
AC_CHECK_LIB(z, inflate)
|
||||
])
|
||||
|
||||
# Check for groff html support.
|
||||
@@ -719,8 +539,8 @@ groff -t -mandoc -Thtml </dev/null >/dev/null
|
||||
if test $? -ne 0 ; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_WARN([
|
||||
*** Will not generate HTML version of man pages. ***
|
||||
*** Consider installing a newer version of groff with HTML support. ***])
|
||||
*** Will not generate HTML version of man pages. Consider
|
||||
*** installing a newer version of groff with HTML support.])
|
||||
groff_html_support=no
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
|
||||
@@ -79,14 +79,14 @@
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+B </td><td>One character backward</td></tr>
|
||||
<tr><td>Ctrl+F</td><td>One character forward</td></tr>
|
||||
<tr><td>Ctrl+<b>←</b></td><td>One word backward</td></tr>
|
||||
<tr><td>Ctrl+<b>→</b></td><td>One word forward</td></tr>
|
||||
<tr><td>Ctrl+<b>←</b></td><td>One word backward</td></tr>
|
||||
<tr><td>Ctrl+<b>→</b></td><td>One word forward</td></tr>
|
||||
<tr><td>Ctrl+A</td><td>To start of line</td></tr>
|
||||
<tr><td>Ctrl+E</td><td>To end of line</td></tr>
|
||||
<tr><td>Ctrl+P</td><td>One line up</td></tr>
|
||||
<tr><td>Ctrl+N</td><td>One line down</td></tr>
|
||||
<tr><td>Ctrl+<b>↑</b></td><td>To previous block</td></tr>
|
||||
<tr><td>Ctrl+<b>↓</b></td><td>To next block</td></tr>
|
||||
<tr><td>Ctrl+<b>↑</b></td><td>To previous block</td></tr>
|
||||
<tr><td>Ctrl+<b>↓</b></td><td>To next block</td></tr>
|
||||
<tr><td>Ctrl+Y</td><td>One page up</td></tr>
|
||||
<tr><td>Ctrl+V</td><td>One page down</td></tr>
|
||||
<tr><td>Alt+\</td><td>To top of buffer</td></tr>
|
||||
@@ -98,8 +98,8 @@
|
||||
<table><tbody>
|
||||
<tr><td>Alt+G </td><td>Go to specified line</td></tr>
|
||||
<tr><td>Alt+]</td><td>Go to complementary bracket</td></tr>
|
||||
<tr><td>Alt+<b>↑</b></td><td>Scroll viewport up</td></tr>
|
||||
<tr><td>Alt+<b>↓</b></td><td>Scroll viewport down</td></tr>
|
||||
<tr><td>Alt+<b>↑</b></td><td>Scroll viewport up</td></tr>
|
||||
<tr><td>Alt+<b>↓</b></td><td>Scroll viewport down</td></tr>
|
||||
<tr><td>Alt+<</td><td>Switch to preceding buffer</td></tr>
|
||||
<tr><td>Alt+></td><td>Switch to succeeding buffer</td></tr>
|
||||
</tbody></table>
|
||||
@@ -108,7 +108,7 @@
|
||||
<b>Information</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+C </td><td>Report cursor position</td></tr>
|
||||
<tr><td>Alt+D</td><td>Report word/line/char count</td></tr>
|
||||
<tr><td>Alt+D</td><td>Report line/word/character count</td></tr>
|
||||
<tr><td>Ctrl+G</td><td>Display help text</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
|
||||
<blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program "establishes a full duplex terminal connection to a remote host", and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote>
|
||||
<h3><a name="1.4"></a>1.4. What is the current version of nano?</h3>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>5.2</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>5.6</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<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%">
|
||||
|
||||
51
doc/nano.1
51
doc/nano.1
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 5.2" "August 2020"
|
||||
.TH NANO 1 "version 5.6" "February 2021"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, inspired by Pico
|
||||
@@ -165,7 +165,7 @@ and place it at that position again upon reopening such a file.
|
||||
.TP
|
||||
.BR "\-Q ""\fIregex\fB""" ", " "\-\-quotestr=""" \fIregex """
|
||||
Set the regular expression for matching the quoting part of a line.
|
||||
The default value is \fB"^([\ \\t]*([!#%:;>|}]|//))+"\fP.
|
||||
The default value is "\fB^([\ \\t]*([!#%:;>|}]|//))+\fR".
|
||||
(Note that \fB\\t\fP stands for an actual Tab.)
|
||||
This makes it possible to rejustify blocks of quoted text when composing
|
||||
email, and to rewrap blocks of line comments when writing source code.
|
||||
@@ -187,12 +187,12 @@ the screen's edge, by using also \fB\-\-atblanks\fR.)
|
||||
.TP
|
||||
.BR \-T\ \fInumber ", " \-\-tabsize= \fInumber
|
||||
Set the size (width) of a tab to \fInumber\fP columns. The value of
|
||||
\fInumber\fP must be greater than 0. The default value is 8.
|
||||
\fInumber\fR must be greater than 0. The default value is \fB8\fR.
|
||||
.TP
|
||||
.BR \-U ", " \-\-quickblank
|
||||
Do quick status-bar blanking: status-bar messages will disappear after 1
|
||||
keystroke instead of 25. Note that option \fB\-c\fR (\fB\-\-constantshow\fR)
|
||||
overrides this.
|
||||
Make status-bar messages disappear after 1 keystroke instead of after 20.
|
||||
Note that options \fB\-c\fR (\fB\-\-constantshow\fR)
|
||||
and \fB\-_\fR (\fB\-\-minibar\fR) override this.
|
||||
.TP
|
||||
.BR \-V ", " \-\-version
|
||||
Show the current version number and exit.
|
||||
@@ -295,11 +295,11 @@ Set the target width for justifying and automatic hard-wrapping at this
|
||||
\fInumber\fR of columns. If the value is 0 or less, wrapping will occur
|
||||
at the width of the screen minus \fInumber\fR columns, allowing the wrap
|
||||
point to vary along with the width of the screen if the screen is resized.
|
||||
The default value is \-8.
|
||||
The default value is \fB\-8\fR.
|
||||
.TP
|
||||
.B "\-s ""\fIprogram\fR [\fIargument \fR...]\fB""\fR, \fB\-\-speller=""\fIprogram\fR [\fIargument \fR...]\fB"""
|
||||
Use this command to perform spell checking and correcting, instead of
|
||||
using the built-in corrector that calls \fBhunspell\fR or GNU \fBspell\fR.
|
||||
using the built-in corrector that calls \fBhunspell\fR(1) or \fBspell\fR(1).
|
||||
.TP
|
||||
.BR \-t ", " \-\-saveonexit
|
||||
Save a changed buffer without prompting (when exiting with \fB^X\fR).
|
||||
@@ -319,7 +319,6 @@ unless \fB\-\-restricted\fR is given too.
|
||||
Do not automatically hard-wrap the current line when it becomes overlong.
|
||||
This is the default. (This option is the opposite of \fB\-b\fR
|
||||
(\fB\-\-breaklonglines\fR) -- the last one given takes effect.)
|
||||
|
||||
.TP
|
||||
.BR \-x ", " \-\-nohelp
|
||||
Don't show the two help lines at the bottom of the screen.
|
||||
@@ -329,6 +328,35 @@ Make Ctrl+Right and Ctrl+Delete stop at word ends instead of beginnings.
|
||||
.TP
|
||||
.BR \-z ", " \-\-suspendable
|
||||
Allow the user to suspend the editor (with \fB^Z\fR by default).
|
||||
.TP
|
||||
.BR \-% ", " \-\-stateflags
|
||||
Use the top-right corner of the screen for showing some state flags:
|
||||
\fBI\fR when auto-indenting, \fBM\fR when the mark is on, \fBL\fR when
|
||||
hard-wrapping (breaking long lines), \fBR\fR when recording a macro,
|
||||
and \fBS\fR when soft-wrapping.
|
||||
When the buffer is modified, a star (\fB*\fR) is shown after the
|
||||
filename in the center of the title bar.
|
||||
.TP
|
||||
.BR \-_ ", " \-\-minibar
|
||||
Suppress the title bar and instead show information about
|
||||
the current buffer at the bottom of the screen, in the space
|
||||
for the status bar. In this "minibar" the file name is shown
|
||||
on the left, followed by an asterisk if the buffer has been modified.
|
||||
On the right are displayed the current line and column number, the
|
||||
code of the character under the cursor (in Unicode format: U+xxxx),
|
||||
the same flags as are shown by \fB\-\-stateflags\fR, and a percentage
|
||||
that expresses how far the cursor is into the file (linewise).
|
||||
When a file is loaded or saved, and also when switching between buffers,
|
||||
the number of lines in the buffer is displayed after the file name.
|
||||
This number is cleared upon the next keystroke, or replaced with an
|
||||
[i/n] counter when multiple buffers are open.
|
||||
The line plus column numbers and the character code are displayed only when
|
||||
\fB\-\-constantshow\fR is used, and can be toggled on and off with \fBM-C\fR.
|
||||
The state flags are displayed only when \fB\-\-stateflags\fR is used.
|
||||
.TP
|
||||
.BR \-! ", " \-\-magic
|
||||
When neither the file's name nor its first line give a clue,
|
||||
try using libmagic to determine the applicable syntax.
|
||||
|
||||
.SH TOGGLES
|
||||
Several of the above options can be switched on and off also while
|
||||
@@ -351,6 +379,9 @@ exists), either \fI~/.nanorc\fR or \fI$XDG_CONFIG_HOME/nano/nanorc\fR
|
||||
or \fI~/.config/nano/nanorc\fR, whichever is encountered first. See
|
||||
.BR nanorc (5)
|
||||
for more information on the possible contents of those files.
|
||||
.sp
|
||||
See \fI/usr/share/nano/\fR and \fI/usr/share/nano/extra/\fR
|
||||
for available syntax-coloring definitions.
|
||||
|
||||
.SH NOTES
|
||||
If no alternative spell checker command is specified on the command
|
||||
|
||||
165
doc/nano.texi
165
doc/nano.texi
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 5.2
|
||||
@set UPDATED August 2020
|
||||
@set VERSION 5.6
|
||||
@set UPDATED February 2021
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 5.2
|
||||
@subtitle version 5.6
|
||||
|
||||
@author Chris Allegretta
|
||||
@page
|
||||
@@ -33,7 +33,7 @@ This manual documents the GNU @command{nano} editor.
|
||||
This manual is part of the GNU @command{nano} distribution.@*
|
||||
|
||||
@sp 4
|
||||
Copyright @copyright{} 1999-2009, 2014-2020 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1999-2009, 2014-2021 Free Software Foundation, Inc.
|
||||
|
||||
@sp 1
|
||||
This document is dual-licensed. You may distribute and/or modify it
|
||||
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
|
||||
@node Top
|
||||
@top
|
||||
|
||||
This manual documents the GNU @command{nano} editor, version 5.2.
|
||||
This manual documents the GNU @command{nano} editor, version 5.6.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@@ -99,14 +99,14 @@ Pico differ.
|
||||
Starting with version 4.0, @command{nano} no longer hard-wraps an overlong
|
||||
line by default. It further uses linewise scrolling by default, and by
|
||||
default includes the line below the title bar into the editing area.
|
||||
|
||||
If you want the old, Pico behavior back, you can use the
|
||||
following options: @option{--breaklonglines},
|
||||
@option{--jumpyscrolling}, and @option{--emptyline}
|
||||
(or @option{-bje} for short).
|
||||
(or @option{-bje}).
|
||||
|
||||
Please report bugs via @url{https://savannah.gnu.org/bugs/?group=nano}.
|
||||
|
||||
For background information see @url{https://nano-editor.org/}.
|
||||
|
||||
@node Invoking
|
||||
@chapter Invoking
|
||||
@@ -252,7 +252,7 @@ and place it at that position again upon reopening such a file.
|
||||
@item -Q "@var{regex}"
|
||||
@itemx --quotestr="@var{regex}"
|
||||
Set the regular expression for matching the quoting part of a line.
|
||||
The default value is @t{"^([@w{ }\t]*([!#%:;>|@}]|//))+"}.
|
||||
The default value is "@t{^([@w{ }\t]*([!#%:;>|@}]|//))+}".
|
||||
(Note that @code{\t} stands for a literal Tab character.)
|
||||
This makes it possible to rejustify blocks of quoted text when composing
|
||||
email, and to rewrap blocks of line comments when writing source code.
|
||||
@@ -281,9 +281,9 @@ Set the displayed tab length to @var{number} columns. The value of
|
||||
|
||||
@item -U
|
||||
@itemx --quickblank
|
||||
Do quick status-bar blanking: status-bar messages will disappear after 1
|
||||
keystroke instead of 25. Note that option @option{-c}
|
||||
(@option{--constantshow}) overrides this.
|
||||
Make status-bar messages disappear after 1 keystroke instead of after 20.
|
||||
Note that options @option{-c} (@option{--constantshow})
|
||||
and @option{-_} (@option{--minibar}) override this.
|
||||
|
||||
@item -V
|
||||
@itemx --version
|
||||
@@ -468,6 +468,38 @@ Make Ctrl+Right and Ctrl+Delete stop at word ends instead of beginnings.
|
||||
Enable the ability to suspend @command{nano} using the system's suspend
|
||||
keystroke (usually @kbd{^Z}).
|
||||
|
||||
@item -%
|
||||
@itemx --stateflags
|
||||
Use the top-right corner of the screen for showing some state flags:
|
||||
@code{I} when auto-indenting, @code{M} when the mark is on, @code{L} when
|
||||
hard-wrapping (breaking long lines), @code{R} when recording a macro,
|
||||
and @code{S} when soft-wrapping.
|
||||
When the buffer is modified, a star (@code{*}) is shown after the
|
||||
filename in the center of the title bar.
|
||||
|
||||
@item -_
|
||||
@itemx --minibar
|
||||
Suppress the title bar and instead show information about
|
||||
the current buffer at the bottom of the screen, in the space
|
||||
for the status bar. In this "minibar" the file name is shown
|
||||
on the left, followed by an asterisk if the buffer has been modified.
|
||||
On the right are displayed the current line and column number, the
|
||||
code of the character under the cursor (in Unicode format: U+xxxx),
|
||||
the same flags as are shown by @code{--stateflags}, and a percentage
|
||||
that expresses how far the cursor is into the file (linewise).
|
||||
When a file is loaded or saved, and also when switching between buffers,
|
||||
the number of lines in the buffer is displayed after the file name.
|
||||
This number is cleared upon the next keystroke, or replaced with an
|
||||
[i/n] counter when multiple buffers are open.
|
||||
The line plus column numbers and the character code are displayed only when
|
||||
@code{--constantshow} is used, and can be toggled on and off with @key{M-C}.
|
||||
The state flags are displayed only when @code{--stateflags} is used.
|
||||
|
||||
@item -!
|
||||
@itemx --magic
|
||||
When neither the file's name nor its first line give a clue,
|
||||
try using libmagic to determine the applicable syntax.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@@ -537,23 +569,22 @@ and then pressing the desired key.
|
||||
@node The Cutbuffer
|
||||
@section The Cutbuffer
|
||||
|
||||
Text can be cut from a file, a whole line at a time, by using the 'Cut Text'
|
||||
command (default key binding: @kbd{^K}). The cut line is stored in
|
||||
the cutbuffer. Consecutive strokes of @kbd{^K} will add each cut line
|
||||
to this buffer, but a @kbd{^K}
|
||||
Text can be cut from a file a whole line at a time with @kbd{^K}.
|
||||
The cut line is stored in the cutbuffer. Consecutive strokes of @kbd{^K}
|
||||
will add each cut line to this buffer, but a @kbd{^K}
|
||||
after any other keystroke will overwrite the entire cutbuffer.
|
||||
|
||||
The contents of the cutbuffer can be pasted back into the file with the
|
||||
'Uncut Text' command (default key binding: @kbd{^U}).
|
||||
The contents of the cutbuffer can be pasted at the current cursor position
|
||||
with @kbd{^U}.
|
||||
|
||||
A line of text can be copied into the cutbuffer (without cutting it) with
|
||||
the 'Copy Text' command (default key binding: @kbd{M-6}).
|
||||
A line of text can be copied into the cutbuffer (without cutting it)
|
||||
with @kbd{M-6}.
|
||||
|
||||
@node The Mark
|
||||
@section The Mark
|
||||
|
||||
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
|
||||
Text can be selected by first 'setting the Mark' with @kbd{^6}
|
||||
or @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.
|
||||
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
|
||||
@@ -564,8 +595,8 @@ while using the cursor keys. Holding down the @kbd{Ctrl} or @kbd{Alt}
|
||||
key too will increase the stride. 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}.
|
||||
Cutting or copying selected text toggles off the mark automatically.
|
||||
If needed, it can be toggled off manually with another @kbd{^6} or @kbd{M-A}.
|
||||
|
||||
@node Screen Layout
|
||||
@section Screen Layout
|
||||
@@ -805,7 +836,7 @@ Set the characters treated as closing brackets when justifying
|
||||
paragraphs. This may not include blank characters. Only closing
|
||||
punctuation (see @code{set punct}), optionally followed by the specified
|
||||
closing brackets, can end sentences. The default value is
|
||||
@t{""')>]@}"}.
|
||||
"@t{"')>]@}}".
|
||||
|
||||
@item set breaklonglines
|
||||
Automatically hard-wrap the current line when it becomes overlong.
|
||||
@@ -861,10 +892,20 @@ if your terminal can do those.
|
||||
Draw a vertical stripe at the given column, to help judge the width of the
|
||||
text. (The color of the stripe can be changed with @code{set stripecolor}.)
|
||||
|
||||
@item set highlightcolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for highlighting a search match.
|
||||
The default value is @t{black,lightyellow}.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set historylog
|
||||
Save the last hundred search strings and replacement strings and
|
||||
executed commands, so they can be easily reused in later sessions.
|
||||
|
||||
@item set indicator
|
||||
Display a "scrollbar" on the righthand side of the edit window.
|
||||
It shows the position of the viewport in the buffer
|
||||
and how much of the buffer is covered by the viewport.
|
||||
|
||||
@item set jumpyscrolling
|
||||
Scroll the buffer contents per half-screen instead of per line.
|
||||
|
||||
@@ -880,12 +921,35 @@ Display line numbers to the left of the text area.
|
||||
@item set locking
|
||||
Enable vim-style lock-files for when editing files.
|
||||
|
||||
@item set magic
|
||||
When neither the file's name nor its first line give a clue,
|
||||
try using libmagic to determine the applicable syntax.
|
||||
(Calling libmagic can be relatively time consuming.
|
||||
It is therefore not done by default.)
|
||||
|
||||
@anchor{@code{set matchbrackets}}
|
||||
@item set matchbrackets "@var{characters}"
|
||||
Specify the opening and closing brackets that can be found by bracket
|
||||
searches. This may not include blank characters. The opening set must
|
||||
come before the closing set, and the two sets must be in the same order.
|
||||
The default value is @t{"(<[@{)>]@}"}.
|
||||
The default value is "@t{(<[@{)>]@}}".
|
||||
|
||||
@item set minibar
|
||||
Suppress the title bar and instead show information about
|
||||
the current buffer at the bottom of the screen, in the space
|
||||
for the status bar. In this "minibar" the file name is shown
|
||||
on the left, followed by an asterisk if the buffer has been modified.
|
||||
On the right are displayed the current line and column number, the
|
||||
code of the character under the cursor (in Unicode format: U+xxxx),
|
||||
the same flags as are shown by @code{set stateflags}, and a percentage
|
||||
that expresses how far the cursor is into the file (linewise).
|
||||
When a file is loaded or saved, and also when switching between buffers,
|
||||
the number of lines in the buffer is displayed after the file name.
|
||||
This number is cleared upon the next keystroke, or replaced with an
|
||||
[i/n] counter when multiple buffers are open.
|
||||
The line plus column numbers and the character code are displayed only when
|
||||
@code{set constantshow} is used, and can be toggled on and off with @key{M-C}.
|
||||
The state flags are displayed only when @code{set stateflags} is used.
|
||||
|
||||
@item set morespace
|
||||
Deprecated option since it has become the default setting.
|
||||
@@ -932,25 +996,25 @@ The cursor position is remembered for the 200 most-recently edited files.
|
||||
@item set preserve
|
||||
Preserve the XON and XOFF keys (@kbd{^Q} and @kbd{^S}).
|
||||
|
||||
@item set indicator
|
||||
Display a "scrollbar" on the righthand side of the edit window.
|
||||
It shows the position of the viewport in the buffer
|
||||
and how much of the buffer is covered by the viewport.
|
||||
@item set promptcolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for the prompt bar.
|
||||
(When this option is not specified, the colors of the title bar are used.)
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set punct "@var{characters}"
|
||||
Set the characters treated as closing punctuation when justifying
|
||||
paragraphs. This may not include blank characters. Only the
|
||||
specified closing punctuation, optionally followed by closing brackets
|
||||
(see @code{set brackets}), can end sentences.
|
||||
The default value is @t{"!.?"}.
|
||||
The default value is "@t{!.?}".
|
||||
|
||||
@item set quickblank
|
||||
Do quick status-bar blanking: status-bar messages will disappear after 1
|
||||
keystroke instead of 25. Note that @option{constantshow} overrides this.
|
||||
Make status-bar messages disappear after 1 keystroke instead of after 20.
|
||||
Note that options @option{constantshow} and @option{minibar} override this.
|
||||
|
||||
@item set quotestr "@var{regex}"
|
||||
Set the regular expression for matching the quoting part of a line.
|
||||
The default value is @t{"^([@w{ }\t]*([!#%:;>|@}]|//))+"}.
|
||||
The default value is "@t{^([@w{ }\t]*([!#%:;>|@}]|//))+}".
|
||||
(Note that @code{\t} stands for a literal Tab character.)
|
||||
This makes it possible to rejustify blocks of quoted text when composing
|
||||
email, and to rewrap blocks of line comments when writing source code.
|
||||
@@ -974,6 +1038,12 @@ Regular expressions in @command{nano} are of the extended type (ERE).
|
||||
Save a changed buffer automatically on exit (@kbd{^X}); don't prompt.
|
||||
(The old form of this option, @code{set tempfile}, is deprecated.)
|
||||
|
||||
@item set scrollercolor @var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for the indicator alias "scrollbar".
|
||||
(On terminal emulators that link to a libvte older than version 0.55,
|
||||
using a background color here does not work correctly.)
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set selectedcolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for selected text.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
@@ -1003,6 +1073,14 @@ the screen's edge, by using also @code{set atblanks}.)
|
||||
Use the given program to do spell checking and correcting.
|
||||
@xref{@option{--speller}} for details.
|
||||
|
||||
@item set stateflags
|
||||
Use the top-right corner of the screen for showing some state flags:
|
||||
@code{I} when auto-indenting, @code{M} when the mark is on, @code{L} when
|
||||
hard-wrapping (breaking long lines), @code{R} when recording a macro,
|
||||
and @code{S} when soft-wrapping.
|
||||
When the buffer is modified, a star (@code{*}) is shown after the
|
||||
filename in the center of the title bar.
|
||||
|
||||
@item set statuscolor [bold,][italic,]@var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for the status bar.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
@@ -1034,11 +1112,6 @@ Save a file by default in Unix format. This overrides nano's
|
||||
default behavior of saving a file in the format that it had.
|
||||
(This option has no effect when you also use @code{set noconvert}.)
|
||||
|
||||
@item set view
|
||||
Disallow file modification: read-only mode.
|
||||
This mode allows the user to open also other files for viewing,
|
||||
unless @option{--restricted} is given on the command line.
|
||||
|
||||
@anchor{Whitespace}
|
||||
@item set whitespace "@var{characters}"
|
||||
Set the two characters used to indicate the presence of tabs and
|
||||
@@ -1070,6 +1143,9 @@ powerful enough to fully parse a file. Nevertheless, regular
|
||||
expressions can do a lot and are easy to make, so they are a
|
||||
good fit for a small editor like @command{nano}.
|
||||
|
||||
See @file{/usr/share/nano/} and @file{/usr/share/nano/extra/}
|
||||
for the syntax-coloring definitions that are available out of the box.
|
||||
|
||||
All regular expressions in @command{nano} are POSIX extended regular expressions
|
||||
(ERE). This means that @code{.}, @code{?}, @code{*}, @code{+}, @code{^},
|
||||
@code{$}, and several other characters are special.
|
||||
@@ -1137,7 +1213,7 @@ characters after the pipe are appended at the end of the line. If no pipe
|
||||
character is present, the full string is prepended; for example, @t{"#"} for
|
||||
Python files. If empty double quotes are specified, the comment/uncomment
|
||||
functions are disabled; for example, @t{""} for JSON.
|
||||
The default value is @t{"#"}.
|
||||
The default value is "@t{#}".
|
||||
|
||||
@item tabgives "@var{string}"
|
||||
Make the <Tab> key produce the given @var{string}. Useful for languages like
|
||||
@@ -1600,8 +1676,9 @@ is the beginning of a paragraph.
|
||||
Toggles whether cutting text will cut the whole line or just from the current cursor
|
||||
position to the end of the line.
|
||||
|
||||
@item nowrap
|
||||
@item breaklonglines
|
||||
Toggles whether long lines will be hard-wrapped to the next line.
|
||||
(The old name of this function, 'nowrap', is deprecated.)
|
||||
|
||||
@item tabstospaces
|
||||
Toggles whether typed tabs will be converted to spaces.
|
||||
@@ -1884,8 +1961,8 @@ Exclude Native Language support. This will disable the use of any
|
||||
available GNU @command{nano} translations.
|
||||
|
||||
@item --enable-utf8
|
||||
Include support for reading and writing Unicode files. This will require
|
||||
either a wide version of curses, or a UTF-8-enabled version of Slang.
|
||||
Include support for reading and writing Unicode files.
|
||||
This requires a wide version of the curses library.
|
||||
|
||||
@item --disable-utf8
|
||||
Exclude support for reading and writing Unicode files. Normally the
|
||||
@@ -1896,10 +1973,6 @@ You can use this or the previous option to override that detection.
|
||||
Use the file with the given @var{name} (in the user's home directory)
|
||||
as nano's settings file, instead of the default @code{.nanorc}.
|
||||
|
||||
@item --with-slang
|
||||
Compile @command{nano} against Slang instead of against ncurses or other
|
||||
curses libraries.
|
||||
|
||||
@end table
|
||||
|
||||
@html
|
||||
|
||||
100
doc/nanorc.5
100
doc/nanorc.5
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 2003-2011, 2013-2020 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 2003-2011, 2013-2021 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 5.2" "August 2020"
|
||||
.TH NANORC 5 "version 5.6" "February 2021"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
@@ -65,7 +65,6 @@ Quotes inside the \fIcharacters\fR parameters below should not be escaped.
|
||||
The last double quote on the line will be seen as the closing quote.
|
||||
.sp
|
||||
The supported commands and arguments are:
|
||||
|
||||
.TP 3
|
||||
.B set afterends
|
||||
Make Ctrl+Right and Ctrl+Delete stop at word ends instead of beginnings.
|
||||
@@ -108,7 +107,7 @@ beginning of a paragraph (unless auto-indenting is on).
|
||||
Set the characters treated as closing brackets when justifying
|
||||
paragraphs. This may not include blank characters. Only closing
|
||||
punctuation (see \fBset punct\fP), optionally followed by the specified
|
||||
closing brackets, can end sentences. The default value is "\fB"')>]}\fP".
|
||||
closing brackets, can end sentences. The default value is "\fB\(dq')>]}\fR".
|
||||
.TP
|
||||
.B set breaklonglines
|
||||
Automatically hard-wrap the current line when it becomes overlong.
|
||||
@@ -139,7 +138,7 @@ point to vary along with the width of the screen if the screen is resized.
|
||||
The default value is \fB\-8\fR.
|
||||
.TP
|
||||
.B set functioncolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Specify the color combination to use for the function descriptions
|
||||
Use this color combination for the concise function descriptions
|
||||
in the two help lines at the bottom of the screen.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
@@ -147,6 +146,11 @@ See \fBset titlecolor\fR for more details.
|
||||
Draw a vertical stripe at the given column, to help judge the width of the
|
||||
text. (The color of the stripe can be changed with \fBset stripecolor\fR.)
|
||||
.TP
|
||||
.B set highlightcolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Use this color combination for highlighting a search match.
|
||||
The default value is \fBblack,lightyellow\fR.
|
||||
See \fBset titlecolor\fR for valid color names.
|
||||
.TP
|
||||
.B set historylog
|
||||
Save the last hundred search strings and replacement strings and
|
||||
executed commands, so they can be easily reused in later sessions.
|
||||
@@ -160,7 +164,7 @@ and how much of the buffer is covered by the viewport.
|
||||
Scroll the buffer contents per half-screen instead of per line.
|
||||
.TP
|
||||
.B set keycolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Specify the color combination to use for the shortcut key combos
|
||||
Use this color combination for the shortcut key combos
|
||||
in the two help lines at the bottom of the screen.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
@@ -171,12 +175,35 @@ Display line numbers to the left of the text area.
|
||||
.B set locking
|
||||
Enable vim-style lock-files for when editing files.
|
||||
.TP
|
||||
.B set magic
|
||||
When neither the file's name nor its first line give a clue,
|
||||
try using libmagic to determine the applicable syntax.
|
||||
(Calling libmagic can be relatively time consuming.
|
||||
It is therefore not done by default.)
|
||||
.TP
|
||||
.BI "set matchbrackets """ characters """
|
||||
Specify the opening and closing brackets that can be found by bracket
|
||||
searches. This may not include blank characters. The opening set must
|
||||
come before the closing set, and the two sets must be in the same order.
|
||||
The default value is "\fB(<[{)>]}\fP".
|
||||
.TP
|
||||
.B set minibar
|
||||
Suppress the title bar and instead show information about
|
||||
the current buffer at the bottom of the screen, in the space
|
||||
for the status bar. In this "minibar" the file name is shown
|
||||
on the left, followed by an asterisk if the buffer has been modified.
|
||||
On the right are displayed the current line and column number, the
|
||||
code of the character under the cursor (in Unicode format: U+xxxx),
|
||||
the same flags as are shown by \fBset stateflags\fR, and a percentage
|
||||
that expresses how far the cursor is into the file (linewise).
|
||||
When a file is loaded or saved, and also when switching between buffers,
|
||||
the number of lines in the buffer is displayed after the file name.
|
||||
This number is cleared upon the next keystroke, or replaced with an
|
||||
[i/n] counter when multiple buffers are open.
|
||||
The line plus column numbers and the character code are displayed only when
|
||||
\fBset constantshow\fR is used, and can be toggled on and off with \fBM-C\fR.
|
||||
The state flags are displayed only when \fBset stateflags\fR is used.
|
||||
.TP
|
||||
.B set morespace
|
||||
Deprecated option since it has become the default setting.
|
||||
When needed, use \fBunset emptyline\fR instead.
|
||||
@@ -209,7 +236,7 @@ Deprecated option since it has become the default setting.
|
||||
When needed, use \fBunset breaklonglines\fR instead.
|
||||
.TP
|
||||
.B set numbercolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Specify the color combination to use for line numbers.
|
||||
Use this color combination for line numbers.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.B set operatingdir "\fIdirectory\fP"
|
||||
@@ -225,6 +252,11 @@ The cursor position is remembered for the 200 most-recently edited files.
|
||||
.B set preserve
|
||||
Preserve the XON and XOFF keys (\fB^Q\fR and \fB^S\fR).
|
||||
.TP
|
||||
.B set promptcolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Use this color combination for the prompt bar.
|
||||
(When this option is not specified, the colors of the title bar are used.)
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.BI "set punct """ characters """
|
||||
Set the characters treated as closing punctuation when justifying
|
||||
paragraphs. This may not include blank characters. Only the
|
||||
@@ -232,8 +264,8 @@ specfified closing punctuation, optionally followed by closing brackets
|
||||
(see \fBbrackets\fP), can end sentences. The default value is "\fB!.?\fP".
|
||||
.TP
|
||||
.B set quickblank
|
||||
Do quick status-bar blanking: status-bar messages will disappear after 1
|
||||
keystroke instead of 25. The option \fBconstantshow\fR overrides this.
|
||||
Make status-bar messages disappear after 1 keystroke instead of after 20.
|
||||
Note that options \fBconstantshow\fR and \fBminibar\fR override this.
|
||||
.TP
|
||||
.BI "set quotestr """ regex """
|
||||
Set the regular expression for matching the quoting part of a line.
|
||||
@@ -261,8 +293,14 @@ Regular expressions in \fBnano\fR are of the extended type (ERE).
|
||||
Save a changed buffer automatically on exit (\fB^X\fR); don't prompt.
|
||||
(The old form of this option, \fBset tempfile\fR, is deprecated.)
|
||||
.TP
|
||||
.B set scrollercolor \fIfgcolor\fB,\fIbgcolor\fR
|
||||
Use this color combination for the indicator alias "scrollbar".
|
||||
(On terminal emulators that link to a libvte older than version 0.55,
|
||||
using a background color here does not work correctly.)
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.B set selectedcolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Specify the color combination to use for selected text.
|
||||
Use this color combination for selected text.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.B set showcursor
|
||||
@@ -287,14 +325,22 @@ the screen's edge, by using also \fBset atblanks\fR.)
|
||||
.TP
|
||||
.B set speller """\fIprogram\fR [\fIargument \fR...]\fB"""
|
||||
Use the given \fIprogram\fR to do spell checking and correcting, instead of
|
||||
using the built-in corrector that calls \fBhunspell\fR or GNU \fBspell\fR.
|
||||
using the built-in corrector that calls \fBhunspell\fR(1) or \fBspell\fR(1).
|
||||
.TP
|
||||
.B set stateflags
|
||||
Use the top-right corner of the screen for showing some state flags:
|
||||
\fBI\fR when auto-indenting, \fBM\fR when the mark is on, \fBL\fR when
|
||||
hard-wrapping (breaking long lines), \fBR\fR when recording a macro,
|
||||
and \fBS\fR when soft-wrapping.
|
||||
When the buffer is modified, a star (\fB*\fR) is shown after the
|
||||
filename in the center of the title bar.
|
||||
.TP
|
||||
.B set statuscolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Specify the color combination to use for the status bar.
|
||||
Use this color combination for the status bar.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.B set stripecolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Specify the color combination to use for the vertical guiding stripe.
|
||||
Use this color combination for the vertical guiding stripe.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.B set suspendable
|
||||
@@ -308,7 +354,7 @@ greater than 0. The default value is \fB8\fR.
|
||||
Convert typed tabs to spaces.
|
||||
.TP
|
||||
.B set titlecolor \fR[\fBbold,\fR][\fBitalic,\fR]\fIfgcolor\fB,\fIbgcolor\fR
|
||||
Specify the color combination to use for the title bar.
|
||||
Use this color combination for the title bar.
|
||||
Valid names for the foreground and background colors are:
|
||||
.BR red ", " green ", " blue ", " magenta ", " yellow ", " cyan ", "
|
||||
.BR white ", and " black .
|
||||
@@ -333,11 +379,6 @@ Save a file by default in Unix format. This overrides nano's
|
||||
default behavior of saving a file in the format that it had.
|
||||
(This option has no effect when you also use \fBset noconvert\fR.)
|
||||
.TP
|
||||
.B set view
|
||||
Disallow file modification: read-only mode.
|
||||
This mode allows the user to open also other files for viewing,
|
||||
unless \fB\-\-restricted\fR is given on the command line.
|
||||
.TP
|
||||
.BI "set whitespace """ characters """
|
||||
Set the two characters used to indicate the presence of tabs and
|
||||
spaces. They must be single-column characters. The default pair
|
||||
@@ -386,13 +427,13 @@ Start the definition of a syntax with this \fIname\fR.
|
||||
All subsequent \fBcolor\fR and other such commands
|
||||
will be added to this syntax, until a new \fBsyntax\fR
|
||||
command is encountered.
|
||||
|
||||
.sp
|
||||
When \fBnano\fR is run, this syntax will be automatically
|
||||
activated if the current filename matches the extended regular
|
||||
expression \fIfileregex\fR. Or the syntax can be explicitly
|
||||
activated by using the \fB\-Y\fR or \fB\-\-syntax\fR
|
||||
command-line option followed by the \fIname\fR.
|
||||
|
||||
.sp
|
||||
The syntax \fBdefault\fP is special: it takes no \fIfileregex\fR,
|
||||
and applies to files that don't match any syntax's regexes.
|
||||
The syntax \fBnone\fP is reserved; specifying it on the command line
|
||||
@@ -529,11 +570,10 @@ no longer be the case, for all letters.
|
||||
where \fIN\fR is a numeric value from 1 to 24.
|
||||
Example: F10.
|
||||
(Often, \fBF13\fR to \fBF24\fR can be typed as \fBF1\fR to \fBF12\fR with Shift.)
|
||||
|
||||
.TP
|
||||
.BR Ins " or " Del .
|
||||
.RE
|
||||
|
||||
.sp
|
||||
Rebinding \fB^M\fR (Enter) or \fB^I\fR (Tab) is probably not a good idea.
|
||||
Rebinding \fB^[\fR (Esc) is not possible, because its keycode
|
||||
is the starter byte of Meta keystrokes and escape sequences.
|
||||
@@ -626,8 +666,8 @@ Prompts for a program to execute. The program's output will be inserted
|
||||
into the current buffer (or into a new buffer when \fBM-F\fR is toggled).
|
||||
.TP
|
||||
.B speller
|
||||
Invokes a spell-checking program, either the default \fBhunspell\fR or GNU
|
||||
\fBspell\fR, or the one defined by \fB\-\-speller\fR or \fBset speller\fR.
|
||||
Invokes a spell-checking program, either the default \fBhunspell\fR(1) or GNU
|
||||
\fBspell\fR(1), or the one defined by \fB\-\-speller\fR or \fBset speller\fR.
|
||||
.TP
|
||||
.B formatter
|
||||
Invokes a full-buffer-processing program (if the active syntax defines one).
|
||||
@@ -880,8 +920,9 @@ is the beginning of a paragraph.
|
||||
Toggles whether cutting text will cut the whole line or just from the current cursor
|
||||
position to the end of the line.
|
||||
.TP
|
||||
.B nowrap
|
||||
.B breaklonglines
|
||||
Toggles whether long lines will be hard-wrapped to the next line.
|
||||
(The old name of this function, 'nowrap', is deprecated.)
|
||||
.TP
|
||||
.B tabstospaces
|
||||
Toggles whether typed tabs will be converted to spaces.
|
||||
@@ -961,6 +1002,13 @@ System-wide configuration file.
|
||||
.TP
|
||||
.IR ~/.nanorc " or " $XDG_CONFIG_HOME/nano/nanorc " or " ~/.config/nano/nanorc
|
||||
Per-user configuration file.
|
||||
.TP
|
||||
.I /usr/share/nano/*
|
||||
Syntax definitions for the syntax coloring of common file types
|
||||
(and for less common file types in the \fIextra/\fR subdirectory).
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR nano (1)
|
||||
.TP
|
||||
.I https://nano-editor.org/cheatsheet.html
|
||||
An overview of the default key bindings.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (C) 2002-2007, 2014-2020 Free Software Foundation, Inc.
|
||||
.\" Copyright (C) 2002-2007, 2014-2021 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This document is dual-licensed. You may distribute and/or modify it
|
||||
.\" under the terms of either of the following licenses:
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 5.2" "August 2020"
|
||||
.TH RNANO 1 "version 5.6" "February 2021"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
|
||||
@@ -44,8 +44,7 @@
|
||||
## Do case-sensitive searches by default.
|
||||
# set casesensitive
|
||||
|
||||
## Constantly display the cursor position in the status bar. Note that
|
||||
## this overrides "quickblank".
|
||||
## Constantly display the cursor position in the status bar or minibar.
|
||||
# set constantshow
|
||||
|
||||
## Use cut-from-cursor-to-end-of-line by default.
|
||||
@@ -76,11 +75,17 @@
|
||||
## no plans to implement vim-style undo state in these files.
|
||||
# set locking
|
||||
|
||||
## Fall back to slow libmagic to try and determine an applicable syntax.
|
||||
# set magic
|
||||
|
||||
## The opening and closing brackets that can be found by bracket
|
||||
## searches. They cannot contain blank characters. The former set must
|
||||
## come before the latter set, and both must be in the same order.
|
||||
# set matchbrackets "(<[{)>]}"
|
||||
|
||||
## Suppress title bar and show file name and editor state at the bottom.
|
||||
# set minibar
|
||||
|
||||
## Enable mouse support, if available for your system. When enabled,
|
||||
## mouse clicks can be used to place the cursor, set the mark (with a
|
||||
## double click), and execute shortcuts. The mouse will work in the X
|
||||
@@ -118,8 +123,7 @@
|
||||
## sentences.
|
||||
# set punct "!.?"
|
||||
|
||||
## Do quick status-bar blanking. Status-bar messages will disappear after
|
||||
## 1 keystroke instead of 26. Note that "constantshow" overrides this.
|
||||
## Make status-bar messages disappear after 1 keystroke instead of after 20.
|
||||
# set quickblank
|
||||
|
||||
## The regular expression that matches quoting characters in email
|
||||
@@ -159,6 +163,10 @@
|
||||
## does not have a default value.
|
||||
# set speller "aspell -x -c"
|
||||
|
||||
## Use the end of the title bar for some state flags: I = auto-indenting,
|
||||
## M = mark, L = hard-wrapping long lines, R = recording, S = soft-wrapping.
|
||||
# set stateflags
|
||||
|
||||
## Allow nano to be suspended (with ^Z by default).
|
||||
# set suspendable
|
||||
## (The old form of this option, 'set suspend', is deprecated.)
|
||||
@@ -172,9 +180,6 @@
|
||||
## Snip whitespace at the end of lines when justifying or hard-wrapping.
|
||||
# set trimblanks
|
||||
|
||||
## Disallow file modification. Why would you want this in an rcfile? ;)
|
||||
# set view
|
||||
|
||||
## The two single-column characters used to display the first characters
|
||||
## of tabs and spaces. 187 in ISO 8859-1 (0000BB in Unicode) and 183 in
|
||||
## ISO-8859-1 (0000B7 in Unicode) seem to be good values for these.
|
||||
@@ -196,22 +201,30 @@
|
||||
## of a single character, and without affecting the cutbuffer).
|
||||
# set zap
|
||||
|
||||
## Paint the interface elements of nano. These are examples;
|
||||
## by default there are no colors, except for errorcolor.
|
||||
|
||||
## Paint the interface elements of nano. These are examples; there are
|
||||
## no colors by default, except for errorcolor and highlightcolor.
|
||||
# set titlecolor bold,lightwhite,blue
|
||||
# set promptcolor lightwhite,lightblack
|
||||
# set statuscolor bold,lightwhite,green
|
||||
# set errorcolor bold,lightwhite,red
|
||||
# set selectedcolor lightwhite,magenta
|
||||
# set highlightcolor black,lime
|
||||
# set stripecolor ,yellow
|
||||
# set scrollercolor cyan
|
||||
# set numbercolor cyan
|
||||
# set keycolor cyan
|
||||
# set functioncolor green
|
||||
|
||||
## In root's .nanorc you might want to use:
|
||||
# set titlecolor bold,lightwhite,magenta
|
||||
# set promptcolor black,yellow
|
||||
# set statuscolor bold,lightwhite,magenta
|
||||
# set errorcolor bold,lightwhite,red
|
||||
# set selectedcolor lightwhite,cyan
|
||||
# set highlightcolor black,orange
|
||||
# set stripecolor ,yellow
|
||||
# set scrollercolor magenta
|
||||
# set numbercolor magenta
|
||||
# set keycolor lightmagenta
|
||||
# set functioncolor magenta
|
||||
@@ -220,7 +233,7 @@
|
||||
## === Syntax coloring ===
|
||||
## For all details, see 'man nanorc', section SYNTAX HIGHLIGHTING.
|
||||
|
||||
## To include all existing syntax definitions, you can do:
|
||||
## To include most of the existing syntax definitions, you can do:
|
||||
# include "@PKGDATADIR@/*.nanorc"
|
||||
|
||||
## Or you can select just the ones you need. For example:
|
||||
@@ -229,7 +242,8 @@
|
||||
# include "@PKGDATADIR@/sh.nanorc"
|
||||
|
||||
## In @PKGDATADIR@/extra/ you can find some syntaxes that are
|
||||
## specific for certain distros or for less common languages.
|
||||
## specific for certain distros or for some less common languages.
|
||||
|
||||
|
||||
## If <Tab> should always produce four spaces when editing a Python file,
|
||||
## independent of the settings of 'tabsize' and 'tabstospaces':
|
||||
|
||||
1261
po/nano.pot
1261
po/nano.pot
File diff suppressed because it is too large
Load Diff
1281
po/pt_BR.po
1281
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,11 @@ for pofile in *.po; do
|
||||
msgattrib --no-obsolete --no-fuzzy $pofile >trimmed.po || exit 4
|
||||
mv trimmed.po $pofile || exit 4
|
||||
done
|
||||
echo
|
||||
|
||||
if grep "[[:cntrl:]]" ./*.po; then
|
||||
echo "*** PO file contains control character"; exit 5;
|
||||
fi
|
||||
|
||||
# If needed, fix a problem in the Makefile template.
|
||||
grep -q '^datarootdir' Makefile.in.in || \
|
||||
|
||||
1271
po/zh_CN.po
1271
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1273
po/zh_TW.po
1273
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION="5.2"
|
||||
VERSION="5.6"
|
||||
|
||||
./configure -C --enable-tiny && make && ./configure -C &&
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ CLEANFILES = revision.h
|
||||
if BUILDING_FROM_GIT
|
||||
SOMETHING = "REVISION \"`git describe --tags 2>/dev/null`\""
|
||||
else
|
||||
SOMETHING = "NOTHING \"from tarball\""
|
||||
SOMETHING = "PLAINBUILD \"from tarball\""
|
||||
endif
|
||||
|
||||
nano.o: revision.h
|
||||
|
||||
779
src/browser.c
779
src/browser.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* browser.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2016 Benno Schulenberg *
|
||||
* Copyright (C) 2001-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2016, 2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
static char **filelist = NULL;
|
||||
/* The list of files to display in the file browser. */
|
||||
static size_t filelist_len = 0;
|
||||
static size_t list_length = 0;
|
||||
/* The number of files in the list. */
|
||||
static size_t width = 0;
|
||||
/* The number of files that we can display per screen row. */
|
||||
@@ -39,6 +39,360 @@ static size_t longest = 0;
|
||||
static size_t selected = 0;
|
||||
/* The currently selected filename in the list; zero-based. */
|
||||
|
||||
/* Set filelist to the list of files contained in the directory path,
|
||||
* set list_length to the number of files in that list, set longest to
|
||||
* the width in columns of the longest filename in that list (between 15
|
||||
* and COLS), and set width to the number of files that we can display
|
||||
* per screen row. And sort the list too. */
|
||||
void read_the_list(const char *path, DIR *dir)
|
||||
{
|
||||
size_t path_len = strlen(path), index = 0;
|
||||
const struct dirent *nextdir;
|
||||
|
||||
longest = 0;
|
||||
|
||||
/* Find the length of the longest filename in the current folder. */
|
||||
while ((nextdir = readdir(dir)) != NULL) {
|
||||
size_t name_len = breadth(nextdir->d_name);
|
||||
|
||||
if (name_len > longest)
|
||||
longest = name_len;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
/* Put 10 characters' worth of blank space between columns of filenames
|
||||
* in the list whenever possible, as Pico does. */
|
||||
longest += 10;
|
||||
|
||||
/* If needed, make room for ".. (parent dir)". */
|
||||
if (longest < 15)
|
||||
longest = 15;
|
||||
/* Make sure we're not wider than the window. */
|
||||
if (longest > COLS)
|
||||
longest = COLS;
|
||||
|
||||
rewinddir(dir);
|
||||
|
||||
free_chararray(filelist, list_length);
|
||||
|
||||
list_length = index;
|
||||
index = 0;
|
||||
|
||||
filelist = nmalloc(list_length * sizeof(char *));
|
||||
|
||||
while ((nextdir = readdir(dir)) != NULL && index < list_length) {
|
||||
/* Don't show the "." entry. */
|
||||
if (strcmp(nextdir->d_name, ".") == 0)
|
||||
continue;
|
||||
|
||||
filelist[index] = nmalloc(path_len + strlen(nextdir->d_name) + 1);
|
||||
sprintf(filelist[index], "%s%s", path, nextdir->d_name);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
/* Maybe the number of files in the directory decreased between the
|
||||
* first time we scanned and the second time. index is the actual
|
||||
* length of the file list, so record it. */
|
||||
list_length = index;
|
||||
|
||||
/* Sort the list of names. */
|
||||
qsort(filelist, list_length, sizeof(char *), diralphasort);
|
||||
|
||||
/* Calculate how many files fit on a line -- feigning room for two
|
||||
* spaces beyond the right edge, and adding two spaces of padding
|
||||
* between columns. */
|
||||
width = (COLS + 2) / (longest + 2);
|
||||
}
|
||||
|
||||
/* Look for needle. If we find it, set selected to its location.
|
||||
* Note that needle must be an exact match for a file in the list. */
|
||||
void browser_select_dirname(const char *needle)
|
||||
{
|
||||
size_t looking_at = 0;
|
||||
|
||||
for (; looking_at < list_length; looking_at++) {
|
||||
if (strcmp(filelist[looking_at], needle) == 0) {
|
||||
selected = looking_at;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the sought name isn't found, move the highlight so that the
|
||||
* changed selection will be noticed. */
|
||||
if (looking_at == list_length) {
|
||||
--selected;
|
||||
|
||||
/* Make sure we stay within the available range. */
|
||||
if (selected >= list_length)
|
||||
selected = list_length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Display at most a screenful of filenames from the gleaned filelist. */
|
||||
void browser_refresh(void)
|
||||
{
|
||||
int row = 0, col = 0;
|
||||
/* The current row and column while the list is getting displayed. */
|
||||
int the_row = 0, the_column = 0;
|
||||
/* The row and column of the selected item. */
|
||||
char *info;
|
||||
/* The additional information that we'll display about a file. */
|
||||
|
||||
titlebar(present_path);
|
||||
blank_edit();
|
||||
|
||||
for (size_t index = selected - selected % (editwinrows * width);
|
||||
index < list_length && row < editwinrows; index++) {
|
||||
const char *thename = tail(filelist[index]);
|
||||
/* The filename we display, minus the path. */
|
||||
size_t namelen = breadth(thename);
|
||||
/* The length of the filename in columns. */
|
||||
size_t infolen;
|
||||
/* The length of the file information in columns. */
|
||||
size_t infomaxlen = 7;
|
||||
/* The maximum length of the file information in columns:
|
||||
* normally seven, but will be twelve for "(parent dir)". */
|
||||
bool dots = (COLS >= 15 && namelen >= longest - infomaxlen);
|
||||
/* Whether to put an ellipsis before the filename? We don't
|
||||
* waste space on dots when there are fewer than 15 columns. */
|
||||
char *disp = display_string(thename, dots ?
|
||||
namelen + infomaxlen + 4 - longest : 0, longest, FALSE, FALSE);
|
||||
/* The filename (or a fragment of it) in displayable format.
|
||||
* When a fragment, account for dots plus one space padding. */
|
||||
struct stat state;
|
||||
|
||||
/* If this is the selected item, draw its highlighted bar upfront, and
|
||||
* remember its location to be able to place the cursor on it. */
|
||||
if (index == selected) {
|
||||
wattron(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
mvwprintw(edit, row, col, "%*s", longest, " ");
|
||||
the_row = row;
|
||||
the_column = col;
|
||||
}
|
||||
|
||||
/* If the name is too long, we display something like "...ename". */
|
||||
if (dots)
|
||||
mvwaddstr(edit, row, col, "...");
|
||||
mvwaddstr(edit, row, dots ? col + 3 : col, disp);
|
||||
|
||||
col += longest;
|
||||
|
||||
/* Show information about the file: "--" for symlinks (except when
|
||||
* they point to a directory) and for files that have disappeared,
|
||||
* "(dir)" for directories, and the file size for normal files. */
|
||||
if (lstat(filelist[index], &state) == -1 || S_ISLNK(state.st_mode)) {
|
||||
if (stat(filelist[index], &state) == -1 || !S_ISDIR(state.st_mode))
|
||||
info = copy_of("--");
|
||||
else
|
||||
/* TRANSLATORS: Try to keep this at most 7 characters. */
|
||||
info = copy_of(_("(dir)"));
|
||||
} else if (S_ISDIR(state.st_mode)) {
|
||||
if (strcmp(thename, "..") == 0) {
|
||||
/* TRANSLATORS: Try to keep this at most 12 characters. */
|
||||
info = copy_of(_("(parent dir)"));
|
||||
infomaxlen = 12;
|
||||
} else
|
||||
info = copy_of(_("(dir)"));
|
||||
} else {
|
||||
off_t result = state.st_size;
|
||||
char modifier;
|
||||
|
||||
info = nmalloc(infomaxlen + 1);
|
||||
|
||||
/* Massage the file size into a human-readable form. */
|
||||
if (state.st_size < (1 << 10))
|
||||
modifier = ' '; /* bytes */
|
||||
else if (state.st_size < (1 << 20)) {
|
||||
result >>= 10;
|
||||
modifier = 'K'; /* kilobytes */
|
||||
} else if (state.st_size < (1 << 30)) {
|
||||
result >>= 20;
|
||||
modifier = 'M'; /* megabytes */
|
||||
} else {
|
||||
result >>= 30;
|
||||
modifier = 'G'; /* gigabytes */
|
||||
}
|
||||
|
||||
/* Show the size if less than a terabyte, else show "(huge)". */
|
||||
if (result < (1 << 10))
|
||||
sprintf(info, "%4ju %cB", (intmax_t)result, modifier);
|
||||
else
|
||||
/* TRANSLATORS: Try to keep this at most 7 characters.
|
||||
* If necessary, you can leave out the parentheses. */
|
||||
info = mallocstrcpy(info, _("(huge)"));
|
||||
}
|
||||
|
||||
/* Make sure info takes up no more than infomaxlen columns. */
|
||||
infolen = breadth(info);
|
||||
if (infolen > infomaxlen) {
|
||||
info[actual_x(info, infomaxlen)] = '\0';
|
||||
infolen = infomaxlen;
|
||||
}
|
||||
|
||||
mvwaddstr(edit, row, col - infolen, info);
|
||||
|
||||
/* If this is the selected item, finish its highlighting. */
|
||||
if (index == selected)
|
||||
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
|
||||
free(disp);
|
||||
free(info);
|
||||
|
||||
/* Add some space between the columns. */
|
||||
col += 2;
|
||||
|
||||
/* If the next entry will not fit on this row, move to next row. */
|
||||
if (col > COLS - longest) {
|
||||
row++;
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If requested, put the cursor on the selected item and switch it on. */
|
||||
if (ISSET(SHOW_CURSOR)) {
|
||||
wmove(edit, the_row, the_column);
|
||||
curs_set(1);
|
||||
}
|
||||
|
||||
wnoutrefresh(edit);
|
||||
}
|
||||
|
||||
/* Look for the given needle in the list of files. If forwards is TRUE,
|
||||
* search forward in the list; otherwise, search backward. */
|
||||
void findfile(const char *needle, bool forwards)
|
||||
{
|
||||
size_t looking_at = selected;
|
||||
/* The location in the file list of the filename we're looking at. */
|
||||
const char *thename;
|
||||
/* The plain filename, without the path. */
|
||||
unsigned stash[sizeof(flags) / sizeof(flags[0])];
|
||||
/* A storage place for the current flag settings. */
|
||||
|
||||
/* Save the settings of all flags. */
|
||||
memcpy(stash, flags, sizeof(flags));
|
||||
|
||||
/* Search forward, case insensitive, and without regexes. */
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
UNSET(CASE_SENSITIVE);
|
||||
UNSET(USE_REGEXP);
|
||||
|
||||
/* Step through each filename in the list until a match is found or
|
||||
* we've come back to the point where we started. */
|
||||
while (TRUE) {
|
||||
if (forwards) {
|
||||
if (looking_at++ == list_length - 1) {
|
||||
looking_at = 0;
|
||||
statusbar(_("Search Wrapped"));
|
||||
}
|
||||
} else {
|
||||
if (looking_at-- == 0) {
|
||||
looking_at = list_length - 1;
|
||||
statusbar(_("Search Wrapped"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the bare filename, without the path. */
|
||||
thename = tail(filelist[looking_at]);
|
||||
|
||||
/* If the needle matches, we're done. And if we're back at the file
|
||||
* where we started, it is the only occurrence. */
|
||||
if (strstrwrapper(thename, needle, thename)) {
|
||||
if (looking_at == selected)
|
||||
statusbar(_("This is the only occurrence"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we're back at the beginning and didn't find any match... */
|
||||
if (looking_at == selected) {
|
||||
not_found_msg(needle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the settings of all flags. */
|
||||
memcpy(flags, stash, sizeof(flags));
|
||||
|
||||
/* Select the one we've found. */
|
||||
selected = looking_at;
|
||||
}
|
||||
|
||||
/* Prepare the prompt and ask the user what to search for; then search for it.
|
||||
* If forwards is TRUE, search forward in the list; otherwise, search backward. */
|
||||
void search_filename(bool forwards)
|
||||
{
|
||||
char *thedefault;
|
||||
int response;
|
||||
|
||||
/* If something was searched for before, show it between square brackets. */
|
||||
if (*last_search != '\0') {
|
||||
char *disp = display_string(last_search, 0, COLS / 3, FALSE, FALSE);
|
||||
|
||||
thedefault = nmalloc(strlen(disp) + 7);
|
||||
/* We use (COLS / 3) here because we need to see more on the line. */
|
||||
sprintf(thedefault, " [%s%s]", disp,
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
thedefault = copy_of("");
|
||||
|
||||
/* Now ask what to search for. */
|
||||
response = do_prompt(MWHEREISFILE, "", &search_history,
|
||||
browser_refresh, "%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: A modifier of the Search prompt. */
|
||||
!forwards ? _(" [Backwards]") : "", thedefault);
|
||||
free(thedefault);
|
||||
|
||||
/* If the user cancelled, or typed <Enter> on a blank answer and
|
||||
* nothing was searched for yet during this session, get out. */
|
||||
if (response == -1 || (response == -2 && *last_search == '\0')) {
|
||||
statusbar(_("Cancelled"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the user typed an answer, remember it. */
|
||||
if (*answer != '\0') {
|
||||
last_search = mallocstrcpy(last_search, answer);
|
||||
#ifdef ENABLE_HISTORIES
|
||||
update_history(&search_history, answer);
|
||||
#endif
|
||||
}
|
||||
|
||||
findfile(last_search, forwards);
|
||||
}
|
||||
|
||||
/* Search again without prompting for the last given search string,
|
||||
* either forwards or backwards. */
|
||||
void research_filename(bool forwards)
|
||||
{
|
||||
#ifdef ENABLE_HISTORIES
|
||||
/* If nothing was searched for yet, take the last item from history. */
|
||||
if (*last_search == '\0' && searchbot->prev != NULL)
|
||||
last_search = mallocstrcpy(last_search, searchbot->prev->data);
|
||||
#endif
|
||||
|
||||
if (*last_search == '\0')
|
||||
statusbar(_("No current search pattern"));
|
||||
else {
|
||||
wipe_statusbar();
|
||||
findfile(last_search, forwards);
|
||||
}
|
||||
}
|
||||
|
||||
/* Strip one element from the end of path, and return the stripped path.
|
||||
* The returned string is dynamically allocated, and should be freed. */
|
||||
char *strip_last_component(const char *path)
|
||||
{
|
||||
char *copy = copy_of(path);
|
||||
char *last_slash = strrchr(copy, '/');
|
||||
|
||||
if (last_slash != NULL)
|
||||
*last_slash = '\0';
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* Allow the user to browse through the directories in the filesystem,
|
||||
* starting at the given path. */
|
||||
char *browse(char *path)
|
||||
@@ -133,8 +487,8 @@ char *browse(char *path)
|
||||
selected--;
|
||||
|
||||
/* If we're beyond the list, select the last filename. */
|
||||
if (selected > filelist_len - 1)
|
||||
selected = filelist_len - 1;
|
||||
if (selected > list_length - 1)
|
||||
selected = list_length - 1;
|
||||
|
||||
/* If we selected the same filename as last time, fake a
|
||||
* press of the Enter key so that the file is read in. */
|
||||
@@ -161,46 +515,42 @@ char *browse(char *path)
|
||||
kbinput = KEY_WINCH;
|
||||
#endif
|
||||
} else if (func == do_help) {
|
||||
#ifdef ENABLE_HELP
|
||||
do_help();
|
||||
#ifndef NANO_TINY
|
||||
/* The window dimensions might have changed, so act as if. */
|
||||
kbinput = KEY_WINCH;
|
||||
#endif
|
||||
#else
|
||||
say_there_is_no_help();
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
} else if (func == do_toggle_void) {
|
||||
TOGGLE(NO_HELP);
|
||||
window_init();
|
||||
kbinput = KEY_WINCH;
|
||||
#endif
|
||||
} else if (func == do_search_forward) {
|
||||
do_filesearch(FORWARD);
|
||||
} else if (func == do_search_backward) {
|
||||
do_filesearch(BACKWARD);
|
||||
search_filename(BACKWARD);
|
||||
} else if (func == do_search_forward) {
|
||||
search_filename(FORWARD);
|
||||
} else if (func == do_findprevious) {
|
||||
do_fileresearch(BACKWARD);
|
||||
research_filename(BACKWARD);
|
||||
} else if (func == do_findnext) {
|
||||
do_fileresearch(FORWARD);
|
||||
research_filename(FORWARD);
|
||||
} else if (func == do_left) {
|
||||
if (selected > 0)
|
||||
selected--;
|
||||
} else if (func == do_right) {
|
||||
if (selected < filelist_len - 1)
|
||||
if (selected < list_length - 1)
|
||||
selected++;
|
||||
} else if (func == to_prev_word) {
|
||||
selected -= (selected % width);
|
||||
} else if (func == to_next_word) {
|
||||
selected += width - 1 - (selected % width);
|
||||
if (selected >= filelist_len)
|
||||
selected = filelist_len - 1;
|
||||
if (selected >= list_length)
|
||||
selected = list_length - 1;
|
||||
} else if (func == do_up) {
|
||||
if (selected >= width)
|
||||
selected -= width;
|
||||
} else if (func == do_down) {
|
||||
if (selected + width <= filelist_len - 1)
|
||||
if (selected + width <= list_length - 1)
|
||||
selected += width;
|
||||
} else if (func == to_prev_block) {
|
||||
selected = ((selected / (editwinrows * width)) *
|
||||
@@ -209,9 +559,9 @@ char *browse(char *path)
|
||||
selected = ((selected / (editwinrows * width)) *
|
||||
editwinrows * width) + selected % width +
|
||||
editwinrows * width - width;
|
||||
if (selected >= filelist_len)
|
||||
selected = (filelist_len / width) * width + selected % width;
|
||||
if (selected >= filelist_len)
|
||||
if (selected >= list_length)
|
||||
selected = (list_length / width) * width + selected % width;
|
||||
if (selected >= list_length)
|
||||
selected -= width;
|
||||
} else if (func == do_page_up) {
|
||||
if (selected < width)
|
||||
@@ -221,17 +571,17 @@ char *browse(char *path)
|
||||
else
|
||||
selected -= editwinrows * width;
|
||||
} else if (func == do_page_down) {
|
||||
if (selected + width >= filelist_len - 1)
|
||||
selected = filelist_len - 1;
|
||||
else if (selected + editwinrows * width >= filelist_len)
|
||||
selected = (selected + editwinrows * width - filelist_len) %
|
||||
width + filelist_len - width;
|
||||
if (selected + width >= list_length - 1)
|
||||
selected = list_length - 1;
|
||||
else if (selected + editwinrows * width >= list_length)
|
||||
selected = (selected + editwinrows * width - list_length) %
|
||||
width + list_length - width;
|
||||
else
|
||||
selected += editwinrows * width;
|
||||
} else if (func == to_first_file) {
|
||||
selected = 0;
|
||||
} else if (func == to_last_file) {
|
||||
selected = filelist_len - 1;
|
||||
selected = list_length - 1;
|
||||
} else if (func == goto_dir) {
|
||||
/* Ask for the directory to go to. */
|
||||
if (do_prompt(MGOTODIR, "", NULL,
|
||||
@@ -245,7 +595,7 @@ char *browse(char *path)
|
||||
|
||||
/* If the given path is relative, join it with the current path. */
|
||||
if (*path != '/') {
|
||||
path = charealloc(path, strlen(present_path) +
|
||||
path = nrealloc(path, strlen(present_path) +
|
||||
strlen(answer) + 1);
|
||||
sprintf(path, "%s%s", present_path, answer);
|
||||
}
|
||||
@@ -265,7 +615,7 @@ char *browse(char *path)
|
||||
|
||||
/* In case the specified directory cannot be entered, select it
|
||||
* (if it is in the current list) so it will be highlighted. */
|
||||
for (size_t j = 0; j < filelist_len; j++)
|
||||
for (size_t j = 0; j < list_length; j++)
|
||||
if (strcmp(filelist[j], path) == 0)
|
||||
selected = j;
|
||||
|
||||
@@ -339,9 +689,9 @@ char *browse(char *path)
|
||||
|
||||
free(path);
|
||||
|
||||
free_chararray(filelist, filelist_len);
|
||||
free_chararray(filelist, list_length);
|
||||
filelist = NULL;
|
||||
filelist_len = 0;
|
||||
list_length = 0;
|
||||
|
||||
return chosen;
|
||||
}
|
||||
@@ -359,7 +709,7 @@ char *browse_in(const char *inpath)
|
||||
path = free_and_assign(path, strip_last_component(path));
|
||||
|
||||
if (stat(path, &fileinfo) == -1 || !S_ISDIR(fileinfo.st_mode)) {
|
||||
char *currentdir = charalloc(PATH_MAX + 1);
|
||||
char *currentdir = nmalloc(PATH_MAX + 1);
|
||||
|
||||
path = free_and_assign(path, getcwd(currentdir, PATH_MAX + 1));
|
||||
|
||||
@@ -383,369 +733,4 @@ char *browse_in(const char *inpath)
|
||||
return browse(path);
|
||||
}
|
||||
|
||||
/* Set filelist to the list of files contained in the directory path,
|
||||
* set filelist_len to the number of files in that list, set longest to
|
||||
* the width in columns of the longest filename in that list (between 15
|
||||
* and COLS), and set width to the number of files that we can display
|
||||
* per screen row. And sort the list too. */
|
||||
void read_the_list(const char *path, DIR *dir)
|
||||
{
|
||||
const struct dirent *nextdir;
|
||||
size_t i = 0, path_len = strlen(path);
|
||||
|
||||
longest = 0;
|
||||
|
||||
/* Find the length of the longest filename in the current folder. */
|
||||
while ((nextdir = readdir(dir)) != NULL) {
|
||||
size_t name_len = breadth(nextdir->d_name);
|
||||
|
||||
if (name_len > longest)
|
||||
longest = name_len;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Put 10 characters' worth of blank space between columns of filenames
|
||||
* in the list whenever possible, as Pico does. */
|
||||
longest += 10;
|
||||
|
||||
/* If needed, make room for ".. (parent dir)". */
|
||||
if (longest < 15)
|
||||
longest = 15;
|
||||
/* Make sure we're not wider than the window. */
|
||||
if (longest > COLS)
|
||||
longest = COLS;
|
||||
|
||||
rewinddir(dir);
|
||||
|
||||
free_chararray(filelist, filelist_len);
|
||||
|
||||
filelist_len = i;
|
||||
|
||||
filelist = (char **)nmalloc(filelist_len * sizeof(char *));
|
||||
|
||||
i = 0;
|
||||
|
||||
while ((nextdir = readdir(dir)) != NULL && i < filelist_len) {
|
||||
/* Don't show the "." entry. */
|
||||
if (strcmp(nextdir->d_name, ".") == 0)
|
||||
continue;
|
||||
|
||||
filelist[i] = charalloc(path_len + strlen(nextdir->d_name) + 1);
|
||||
sprintf(filelist[i], "%s%s", path, nextdir->d_name);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Maybe the number of files in the directory changed between the
|
||||
* first time we scanned and the second. i is the actual length of
|
||||
* filelist, so record it. */
|
||||
filelist_len = i;
|
||||
|
||||
/* Sort the list of names. */
|
||||
qsort(filelist, filelist_len, sizeof(char *), diralphasort);
|
||||
|
||||
/* Calculate how many files fit on a line -- feigning room for two
|
||||
* spaces beyond the right edge, and adding two spaces of padding
|
||||
* between columns. */
|
||||
width = (COLS + 2) / (longest + 2);
|
||||
}
|
||||
|
||||
/* Display at most a screenful of filenames from the gleaned filelist. */
|
||||
void browser_refresh(void)
|
||||
{
|
||||
int row = 0, col = 0;
|
||||
/* The current row and column while the list is getting displayed. */
|
||||
int the_row = 0, the_column = 0;
|
||||
/* The row and column of the selected item. */
|
||||
char *info;
|
||||
/* The additional information that we'll display about a file. */
|
||||
|
||||
titlebar(present_path);
|
||||
blank_edit();
|
||||
|
||||
for (size_t index = selected - selected % (editwinrows * width);
|
||||
index < filelist_len && row < editwinrows; index++) {
|
||||
const char *thename = tail(filelist[index]);
|
||||
/* The filename we display, minus the path. */
|
||||
size_t namelen = breadth(thename);
|
||||
/* The length of the filename in columns. */
|
||||
size_t infolen;
|
||||
/* The length of the file information in columns. */
|
||||
size_t infomaxlen = 7;
|
||||
/* The maximum length of the file information in columns:
|
||||
* normally seven, but will be twelve for "(parent dir)". */
|
||||
bool dots = (COLS >= 15 && namelen >= longest - infomaxlen);
|
||||
/* Whether to put an ellipsis before the filename? We don't
|
||||
* waste space on dots when there are fewer than 15 columns. */
|
||||
char *disp = display_string(thename, dots ?
|
||||
namelen + infomaxlen + 4 - longest : 0, longest, FALSE, FALSE);
|
||||
/* The filename (or a fragment of it) in displayable format.
|
||||
* When a fragment, account for dots plus one space padding. */
|
||||
struct stat state;
|
||||
|
||||
/* If this is the selected item, draw its highlighted bar upfront, and
|
||||
* remember its location to be able to place the cursor on it. */
|
||||
if (index == selected) {
|
||||
wattron(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
mvwprintw(edit, row, col, "%*s", longest, " ");
|
||||
the_row = row;
|
||||
the_column = col;
|
||||
}
|
||||
|
||||
/* If the name is too long, we display something like "...ename". */
|
||||
if (dots)
|
||||
mvwaddstr(edit, row, col, "...");
|
||||
mvwaddstr(edit, row, dots ? col + 3 : col, disp);
|
||||
|
||||
col += longest;
|
||||
|
||||
/* Show information about the file: "--" for symlinks (except when
|
||||
* they point to a directory) and for files that have disappeared,
|
||||
* "(dir)" for directories, and the file size for normal files. */
|
||||
if (lstat(filelist[index], &state) == -1 || S_ISLNK(state.st_mode)) {
|
||||
if (stat(filelist[index], &state) == -1 || !S_ISDIR(state.st_mode))
|
||||
info = copy_of("--");
|
||||
else
|
||||
/* TRANSLATORS: Try to keep this at most 7 characters. */
|
||||
info = copy_of(_("(dir)"));
|
||||
} else if (S_ISDIR(state.st_mode)) {
|
||||
if (strcmp(thename, "..") == 0) {
|
||||
/* TRANSLATORS: Try to keep this at most 12 characters. */
|
||||
info = copy_of(_("(parent dir)"));
|
||||
infomaxlen = 12;
|
||||
} else
|
||||
info = copy_of(_("(dir)"));
|
||||
} else {
|
||||
off_t result = state.st_size;
|
||||
char modifier;
|
||||
|
||||
info = charalloc(infomaxlen + 1);
|
||||
|
||||
/* Massage the file size into a human-readable form. */
|
||||
if (state.st_size < (1 << 10))
|
||||
modifier = ' '; /* bytes */
|
||||
else if (state.st_size < (1 << 20)) {
|
||||
result >>= 10;
|
||||
modifier = 'K'; /* kilobytes */
|
||||
} else if (state.st_size < (1 << 30)) {
|
||||
result >>= 20;
|
||||
modifier = 'M'; /* megabytes */
|
||||
} else {
|
||||
result >>= 30;
|
||||
modifier = 'G'; /* gigabytes */
|
||||
}
|
||||
|
||||
/* Show the size if less than a terabyte, else show "(huge)". */
|
||||
if (result < (1 << 10))
|
||||
sprintf(info, "%4ju %cB", (intmax_t)result, modifier);
|
||||
else
|
||||
/* TRANSLATORS: Try to keep this at most 7 characters.
|
||||
* If necessary, you can leave out the parentheses. */
|
||||
info = mallocstrcpy(info, _("(huge)"));
|
||||
}
|
||||
|
||||
/* Make sure info takes up no more than infomaxlen columns. */
|
||||
infolen = breadth(info);
|
||||
if (infolen > infomaxlen) {
|
||||
info[actual_x(info, infomaxlen)] = '\0';
|
||||
infolen = infomaxlen;
|
||||
}
|
||||
|
||||
mvwaddstr(edit, row, col - infolen, info);
|
||||
|
||||
/* If this is the selected item, finish its highlighting. */
|
||||
if (index == selected)
|
||||
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
|
||||
free(disp);
|
||||
free(info);
|
||||
|
||||
/* Add some space between the columns. */
|
||||
col += 2;
|
||||
|
||||
/* If the next entry will not fit on this row, move to next row. */
|
||||
if (col > COLS - longest) {
|
||||
row++;
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If requested, put the cursor on the selected item and switch it on. */
|
||||
if (ISSET(SHOW_CURSOR)) {
|
||||
wmove(edit, the_row, the_column);
|
||||
curs_set(1);
|
||||
}
|
||||
|
||||
wnoutrefresh(edit);
|
||||
}
|
||||
|
||||
/* Look for needle. If we find it, set selected to its location.
|
||||
* Note that needle must be an exact match for a file in the list. */
|
||||
void browser_select_dirname(const char *needle)
|
||||
{
|
||||
size_t looking_at = 0;
|
||||
|
||||
for (; looking_at < filelist_len; looking_at++) {
|
||||
if (strcmp(filelist[looking_at], needle) == 0) {
|
||||
selected = looking_at;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the sought name isn't found, move the highlight so that the
|
||||
* changed selection will be noticed. */
|
||||
if (looking_at == filelist_len) {
|
||||
--selected;
|
||||
|
||||
/* Make sure we stay within the available range. */
|
||||
if (selected >= filelist_len)
|
||||
selected = filelist_len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare the prompt and ask the user what to search for. If forwards is
|
||||
* TRUE, search forward in the list; otherwise, search backward. Return -2
|
||||
* for a blank answer, -1 for Cancel, 0 when we have a string, and a
|
||||
* positive value when some function was run. */
|
||||
int filesearch_init(bool forwards)
|
||||
{
|
||||
char *thedefault;
|
||||
int response;
|
||||
|
||||
/* If something was searched for before, show it between square brackets. */
|
||||
if (*last_search != '\0') {
|
||||
char *disp = display_string(last_search, 0, COLS / 3, FALSE, FALSE);
|
||||
|
||||
thedefault = charalloc(strlen(disp) + 7);
|
||||
/* We use (COLS / 3) here because we need to see more on the line. */
|
||||
sprintf(thedefault, " [%s%s]", disp,
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
thedefault = copy_of("");
|
||||
|
||||
/* Now ask what to search for. */
|
||||
response = do_prompt(MWHEREISFILE, "", &search_history,
|
||||
browser_refresh, "%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: A modifier of the Search prompt. */
|
||||
!forwards ? _(" [Backwards]") : "", thedefault);
|
||||
free(thedefault);
|
||||
|
||||
/* If only Enter was pressed but we have a previous string, it's okay. */
|
||||
if (response == -2 && *last_search != '\0')
|
||||
return 0;
|
||||
|
||||
/* Otherwise negative responses are a bailout. */
|
||||
if (response < 0)
|
||||
statusbar(_("Cancelled"));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/* Look for the given needle in the list of files. If forwards is TRUE,
|
||||
* search forward in the list; otherwise, search backward. */
|
||||
void findfile(const char *needle, bool forwards)
|
||||
{
|
||||
size_t looking_at = selected;
|
||||
/* The location in the file list of the filename we're looking at. */
|
||||
const char *thename;
|
||||
/* The plain filename, without the path. */
|
||||
unsigned stash[sizeof(flags) / sizeof(flags[0])];
|
||||
/* A storage place for the current flag settings. */
|
||||
|
||||
/* Save the settings of all flags. */
|
||||
memcpy(stash, flags, sizeof(flags));
|
||||
|
||||
/* Search forward, case insensitive, and without regexes. */
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
UNSET(CASE_SENSITIVE);
|
||||
UNSET(USE_REGEXP);
|
||||
|
||||
/* Step through each filename in the list until a match is found or
|
||||
* we've come back to the point where we started. */
|
||||
while (TRUE) {
|
||||
if (forwards) {
|
||||
if (looking_at++ == filelist_len - 1) {
|
||||
looking_at = 0;
|
||||
statusbar(_("Search Wrapped"));
|
||||
}
|
||||
} else {
|
||||
if (looking_at-- == 0) {
|
||||
looking_at = filelist_len - 1;
|
||||
statusbar(_("Search Wrapped"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the bare filename, without the path. */
|
||||
thename = tail(filelist[looking_at]);
|
||||
|
||||
/* If the needle matches, we're done. And if we're back at the file
|
||||
* where we started, it is the only occurrence. */
|
||||
if (strstrwrapper(thename, needle, thename)) {
|
||||
if (looking_at == selected)
|
||||
statusbar(_("This is the only occurrence"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we're back at the beginning and didn't find any match... */
|
||||
if (looking_at == selected) {
|
||||
not_found_msg(needle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the settings of all flags. */
|
||||
memcpy(flags, stash, sizeof(flags));
|
||||
|
||||
/* Select the one we've found. */
|
||||
selected = looking_at;
|
||||
}
|
||||
|
||||
/* Search for a filename. If forwards is TRUE, search forward in the list;
|
||||
* otherwise, search backward.*/
|
||||
void do_filesearch(bool forwards)
|
||||
{
|
||||
/* If the user cancelled or jumped to first or last file, don't search. */
|
||||
if (filesearch_init(forwards) != 0)
|
||||
return;
|
||||
|
||||
/* If answer is now "", copy last_search into answer. */
|
||||
if (*answer == '\0')
|
||||
answer = mallocstrcpy(answer, last_search);
|
||||
else
|
||||
last_search = mallocstrcpy(last_search, answer);
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
/* If answer is not empty, add the string to the search history list. */
|
||||
if (*answer != '\0')
|
||||
update_history(&search_history, answer);
|
||||
#endif
|
||||
|
||||
findfile(answer, forwards);
|
||||
}
|
||||
|
||||
/* Search again without prompting for the last given search string,
|
||||
* either forwards or backwards. */
|
||||
void do_fileresearch(bool forwards)
|
||||
{
|
||||
if (*last_search == '\0')
|
||||
statusbar(_("No current search pattern"));
|
||||
else
|
||||
findfile(last_search, forwards);
|
||||
}
|
||||
|
||||
/* Strip one element from the end of path, and return the stripped path.
|
||||
* The returned string is dynamically allocated, and should be freed. */
|
||||
char *strip_last_component(const char *path)
|
||||
{
|
||||
char *copy = copy_of(path);
|
||||
char *last_slash = strrchr(copy, '/');
|
||||
|
||||
if (last_slash != NULL)
|
||||
*last_slash = '\0';
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_BROWSER */
|
||||
|
||||
38
src/chars.c
38
src/chars.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* chars.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2019 Benno Schulenberg *
|
||||
* Copyright (C) 2001-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -179,8 +179,8 @@ char control_mbrep(const char *c, bool isdata)
|
||||
/* Return the width in columns of the given (multibyte) character. */
|
||||
int mbwidth(const char *c)
|
||||
{
|
||||
/* Ask for the width only when the character isn't plain ASCII. */
|
||||
if ((signed char)*c <= 0) {
|
||||
/* Only characters beyond U+02FF can be other than one column wide. */
|
||||
if ((unsigned char)*c > 0xCB) {
|
||||
wchar_t wc;
|
||||
int width;
|
||||
|
||||
@@ -197,12 +197,18 @@ int mbwidth(const char *c)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return TRUE when the given character occupies zero cells. */
|
||||
bool is_zerowidth(const char *ch)
|
||||
{
|
||||
return (use_utf8 && mbwidth(ch) == 0);
|
||||
}
|
||||
|
||||
/* Convert the given Unicode value to a multibyte character, if possible.
|
||||
* If the conversion succeeds, return the (dynamically allocated) multibyte
|
||||
* character and its length. Otherwise, return a length of zero. */
|
||||
char *make_mbchar(long code, int *length)
|
||||
{
|
||||
char *mb_char = charalloc(MAXCHARLEN);
|
||||
char *mb_char = nmalloc(MAXCHARLEN);
|
||||
|
||||
*length = wctomb(mb_char, (wchar_t)code);
|
||||
|
||||
@@ -221,7 +227,7 @@ int char_length(const char *pointer)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
/* If possibly a multibyte character, get its length; otherwise, it's 1. */
|
||||
if ((signed char)*pointer < 0) {
|
||||
if ((unsigned char)*pointer > 0xC1) {
|
||||
int length = mblen(pointer, MAXCHARLEN);
|
||||
|
||||
return (length < 0 ? 1 : length);
|
||||
@@ -237,7 +243,7 @@ size_t mbstrlen(const char *pointer)
|
||||
|
||||
while (*pointer != '\0') {
|
||||
#ifdef ENABLE_UTF8
|
||||
if ((signed char)*pointer < 0) {
|
||||
if ((unsigned char)*pointer > 0xC1) {
|
||||
int length = mblen(pointer, MAXCHARLEN);
|
||||
|
||||
pointer += (length < 0 ? 1 : length);
|
||||
@@ -259,7 +265,7 @@ int collect_char(const char *string, char *thechar)
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
/* If this is a UTF-8 starter byte, get the number of bytes of the character. */
|
||||
if ((signed char)*string < 0) {
|
||||
if ((unsigned char)*string > 0xC1) {
|
||||
charlen = mblen(string, MAXCHARLEN);
|
||||
|
||||
/* When the multibyte sequence is invalid, only take the first byte. */
|
||||
@@ -374,6 +380,22 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n)
|
||||
wchar_t wc1, wc2;
|
||||
|
||||
while (*s1 != '\0' && *s2 != '\0' && n > 0) {
|
||||
if ((signed char)*s1 >= 0 && (signed char)*s2 >= 0) {
|
||||
if ('A' <= (*s1 & 0x5F) && (*s1 & 0x5F) <= 'Z') {
|
||||
if ('A' <= (*s2 & 0x5F) && (*s2 & 0x5F) <= 'Z') {
|
||||
if ((*s1 & 0x5F) != (*s2 & 0x5F))
|
||||
return ((*s1 & 0x5F) - (*s2 & 0x5F));
|
||||
} else
|
||||
return ((*s1 | 0x20) - *s2);
|
||||
} else if ('A' <= (*s2 & 0x5F) && (*s2 & 0x5F) <= 'Z')
|
||||
return (*s1 - (*s2 | 0x20));
|
||||
else if (*s1 != *s2)
|
||||
return (*s1 - *s2);
|
||||
|
||||
s1++; s2++; n--;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool bad1 = (mbtowc(&wc1, s1, MAXCHARLEN) < 0);
|
||||
bool bad2 = (mbtowc(&wc2, s2, MAXCHARLEN) < 0);
|
||||
|
||||
|
||||
143
src/color.c
143
src/color.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* color.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* Copyright (C) 2001-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017, 2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -29,15 +29,6 @@
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
/* For early versions of ncurses-6.0, use an additional A_PROTECT attribute
|
||||
* for all colors, in order to work around an ncurses miscoloring bug. */
|
||||
#if defined(NCURSES_VERSION_MAJOR) && (NCURSES_VERSION_MAJOR == 6) && \
|
||||
(NCURSES_VERSION_MINOR == 0) && (NCURSES_VERSION_PATCH < 20151017)
|
||||
#define A_BANDAID A_PROTECT
|
||||
#else
|
||||
#define A_BANDAID A_NORMAL
|
||||
#endif
|
||||
|
||||
static bool defaults_allowed = FALSE;
|
||||
/* Whether ncurses accepts -1 to mean "default color". */
|
||||
|
||||
@@ -61,17 +52,20 @@ void set_interface_colorpairs(void)
|
||||
combo->bg = COLOR_BLACK;
|
||||
}
|
||||
init_pair(index + 1, combo->fg, combo->bg);
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1) | A_BANDAID |
|
||||
combo->attributes;
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1) | combo->attributes;
|
||||
} else {
|
||||
if (index == FUNCTION_TAG)
|
||||
if (index == FUNCTION_TAG || index == SCROLL_BAR)
|
||||
interface_color_pair[index] = A_NORMAL;
|
||||
else if (index == GUIDE_STRIPE)
|
||||
interface_color_pair[index] = A_REVERSE;
|
||||
else if (index == HIGHLIGHTED) {
|
||||
init_pair(index + 1, COLOR_BLACK, COLOR_YELLOW + (COLORS > 15 ? 8 : 0));
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1);
|
||||
} else if (index == PROMPT_BAR)
|
||||
interface_color_pair[index] = interface_color_pair[TITLE_BAR];
|
||||
else if (index == ERROR_MESSAGE) {
|
||||
init_pair(index + 1, COLOR_WHITE, COLOR_RED);
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1) |
|
||||
A_BOLD | A_BANDAID;
|
||||
interface_color_pair[index] = COLOR_PAIR(index + 1) | A_BOLD;
|
||||
} else
|
||||
interface_color_pair[index] = hilite_attribute;
|
||||
}
|
||||
@@ -102,7 +96,7 @@ void set_syntax_colorpairs(syntaxtype *sntx)
|
||||
|
||||
ink->pairnum = (older != ink) ? older->pairnum : ++number;
|
||||
|
||||
ink->attributes |= COLOR_PAIR(ink->pairnum) | A_BANDAID;
|
||||
ink->attributes |= COLOR_PAIR(ink->pairnum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +123,7 @@ bool found_in_list(regexlisttype *head, const char *shibboleth)
|
||||
regex_t rgx;
|
||||
|
||||
for (item = head; item != NULL; item = item->next) {
|
||||
regcomp(&rgx, item->full_regex, NANO_REG_EXTENDED);
|
||||
regcomp(&rgx, item->full_regex, NANO_REG_EXTENDED | REG_NOSUB);
|
||||
|
||||
if (regexec(&rgx, shibboleth, 0, NULL, 0) == 0) {
|
||||
regfree(&rgx);
|
||||
@@ -189,8 +183,8 @@ void find_and_prime_applicable_syntax(void)
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBMAGIC
|
||||
/* If we still don't have an answer, try using magic. */
|
||||
if (sntx == NULL && !inhelp) {
|
||||
/* If we still don't have an answer, try using magic (when requested). */
|
||||
if (sntx == NULL && !inhelp && ISSET(USE_MAGIC)) {
|
||||
struct stat fileinfo;
|
||||
magic_t cookie = NULL;
|
||||
const char *magicstring = NULL;
|
||||
@@ -240,15 +234,6 @@ void find_and_prime_applicable_syntax(void)
|
||||
openfile->syntax = sntx;
|
||||
}
|
||||
|
||||
/* Allocate and initialize (for the given line) the cache for multiline info. */
|
||||
void set_up_multicache(linestruct *line)
|
||||
{
|
||||
line->multidata = (short *)nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
|
||||
for (short index = 0; index < openfile->syntax->nmultis; index++)
|
||||
line->multidata[index] = -1;
|
||||
}
|
||||
|
||||
/* 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(linestruct *line)
|
||||
@@ -262,8 +247,10 @@ void check_the_multis(linestruct *line)
|
||||
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0)
|
||||
return;
|
||||
|
||||
if (line->multidata == NULL)
|
||||
set_up_multicache(line);
|
||||
if (line->multidata == NULL) {
|
||||
refresh_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
for (ink = openfile->syntax->color; ink != NULL; ink = ink->next) {
|
||||
/* If it's not a multiline regex, skip. */
|
||||
@@ -275,19 +262,22 @@ void check_the_multis(linestruct *line)
|
||||
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 (line->multidata[ink->id] == NOTHING) {
|
||||
if (!astart)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] & (WHOLELINE|WOULDBE)) {
|
||||
if (!astart && !anend)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CSTARTENDHERE) {
|
||||
if (astart && anend && startmatch.rm_so < endmatch.rm_so)
|
||||
} else if (line->multidata[ink->id] == JUSTONTHIS) {
|
||||
if (astart && anend && regexec(ink->start, line->data + endmatch.rm_eo,
|
||||
1, &startmatch, 0) != 0)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CBEGINBEFORE) {
|
||||
if (!astart && anend)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == CENDAFTER) {
|
||||
} else if (line->multidata[ink->id] == STARTSHERE) {
|
||||
if (astart && !anend)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] == ENDSHERE) {
|
||||
if (!astart && anend)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* There is a mismatch, so something changed: repaint. */
|
||||
@@ -304,13 +294,18 @@ void precalc_multicolorinfo(void)
|
||||
regmatch_t startmatch, endmatch;
|
||||
linestruct *line, *tailline;
|
||||
|
||||
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0 ||
|
||||
openfile->filetop->multidata || ISSET(NO_SYNTAX))
|
||||
if (!openfile->syntax || openfile->syntax->nmultis == 0 || ISSET(NO_SYNTAX))
|
||||
return;
|
||||
|
||||
//#define TIMEPRECALC 123
|
||||
#ifdef TIMEPRECALC
|
||||
#include <time.h>
|
||||
clock_t start = clock();
|
||||
#endif
|
||||
|
||||
/* For each line, allocate cache space for the multiline-regex info. */
|
||||
for (line = openfile->filetop; line != NULL; line = line->next)
|
||||
set_up_multicache(line);
|
||||
line->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
|
||||
for (ink = openfile->syntax->color; ink != NULL; ink = ink->next) {
|
||||
/* If this is not a multi-line regex, skip it. */
|
||||
@@ -321,66 +316,68 @@ void precalc_multicolorinfo(void)
|
||||
int index = 0;
|
||||
|
||||
/* Assume nothing applies until proven otherwise below. */
|
||||
line->multidata[ink->id] = CNONE;
|
||||
line->multidata[ink->id] = NOTHING;
|
||||
|
||||
/* 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) {
|
||||
/* 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;
|
||||
/* If there is an end match on this same 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] = JUSTONTHIS;
|
||||
|
||||
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 the total match has zero length, force an advance. */
|
||||
if (startmatch.rm_eo - startmatch.rm_so + endmatch.rm_eo == 0) {
|
||||
/* When at end-of-line, there is no other start. */
|
||||
if (line->data[index] == '\0')
|
||||
break;
|
||||
index = step_right(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;
|
||||
while (tailline && regexec(ink->end, tailline->data,
|
||||
1, &endmatch, 0) != 0)
|
||||
tailline = tailline->next;
|
||||
}
|
||||
|
||||
/* When there is no end match, mark relevant lines as such. */
|
||||
if (tailline == NULL) {
|
||||
line->multidata[ink->id] = CWOULDBE;
|
||||
for (; line->next != NULL; line = line->next)
|
||||
line->multidata[ink->id] = WOULDBE;
|
||||
line->multidata[ink->id] = WOULDBE;
|
||||
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;
|
||||
/* We found it, we found it, la lala lala. Mark the lines. */
|
||||
line->multidata[ink->id] = STARTSHERE;
|
||||
|
||||
// Note that this also advances the line in the main loop.
|
||||
for (line = line->next; line != tailline; line = line->next)
|
||||
line->multidata[ink->id] = CWHOLELINE;
|
||||
line->multidata[ink->id] = WHOLELINE;
|
||||
|
||||
tailline->multidata[ink->id] = CBEGINBEFORE;
|
||||
tailline->multidata[ink->id] = ENDSHERE;
|
||||
|
||||
/* Begin looking for a new start after the end match. */
|
||||
/* Look for a possible new start after the end match. */
|
||||
index = endmatch.rm_eo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TIMEPRECALC
|
||||
statusline(INFO, "Precalculation: %.1f ms", 1000 * (double)(clock() - start) / CLOCKS_PER_SEC);
|
||||
napms(1200);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
32
src/cut.c
32
src/cut.c
@@ -1,9 +1,9 @@
|
||||
/**************************************************************************
|
||||
* cut.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014 Mark Majeres *
|
||||
* Copyright (C) 2016, 2018, 2019 Benno Schulenberg *
|
||||
* Copyright (C) 2016, 2018-2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -88,7 +88,7 @@ void do_deletion(undo_type action)
|
||||
openfile->current->has_anchor |= joining->has_anchor;
|
||||
#endif
|
||||
/* Add the content of the next line to that of the current one. */
|
||||
openfile->current->data = charealloc(openfile->current->data,
|
||||
openfile->current->data = nrealloc(openfile->current->data,
|
||||
strlen(openfile->current->data) + strlen(joining->data) + 1);
|
||||
strcat(openfile->current->data, joining->data);
|
||||
|
||||
@@ -121,7 +121,14 @@ void do_delete(void)
|
||||
zap_text();
|
||||
else
|
||||
#endif
|
||||
{
|
||||
do_deletion(DEL);
|
||||
#ifdef ENABLE_UTF8
|
||||
while (openfile->current->data[openfile->current_x] != '\0' &&
|
||||
is_zerowidth(openfile->current->data + openfile->current_x))
|
||||
do_deletion(DEL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Backspace over one character. That is, move the cursor left one
|
||||
@@ -133,7 +140,10 @@ void do_backspace(void)
|
||||
zap_text();
|
||||
else
|
||||
#endif
|
||||
if (openfile->current_x > 0 || openfile->current != openfile->filetop) {
|
||||
if (openfile->current_x > 0) {
|
||||
openfile->current_x = step_left(openfile->current->data, openfile->current_x);
|
||||
do_deletion(BACK);
|
||||
} else if (openfile->current != openfile->filetop) {
|
||||
do_left();
|
||||
do_deletion(BACK);
|
||||
}
|
||||
@@ -289,7 +299,7 @@ void extract_segment(linestruct *top, size_t top_x, linestruct *bot, size_t bot_
|
||||
if (bot->next)
|
||||
bot->next->prev = top;
|
||||
|
||||
top->data = charealloc(top->data, top_x + strlen(bot->data + bot_x) + 1);
|
||||
top->data = nrealloc(top->data, top_x + strlen(bot->data + bot_x) + 1);
|
||||
strcpy(top->data + top_x, bot->data + bot_x);
|
||||
|
||||
last = bot;
|
||||
@@ -308,7 +318,7 @@ void extract_segment(linestruct *top, size_t top_x, linestruct *bot, size_t bot_
|
||||
cutbuffer = taken;
|
||||
cutbottom = last;
|
||||
} else {
|
||||
cutbottom->data = charealloc(cutbottom->data,
|
||||
cutbottom->data = nrealloc(cutbottom->data,
|
||||
strlen(cutbottom->data) + strlen(taken->data) + 1);
|
||||
strcat(cutbottom->data, taken->data);
|
||||
|
||||
@@ -375,7 +385,7 @@ void ingraft_buffer(linestruct *topline)
|
||||
|
||||
if (extralen > 0) {
|
||||
/* Insert the text of topline at the current cursor position. */
|
||||
line->data = charealloc(line->data, length + extralen + 1);
|
||||
line->data = nrealloc(line->data, length + extralen + 1);
|
||||
memmove(line->data + xpos + extralen, line->data + xpos, length - xpos + 1);
|
||||
strncpy(line->data + xpos, topline->data, extralen);
|
||||
}
|
||||
@@ -401,7 +411,7 @@ void ingraft_buffer(linestruct *topline)
|
||||
/* Add the text after the cursor position at the end of botline. */
|
||||
length = strlen(botline->data);
|
||||
extralen = strlen(tailtext);
|
||||
botline->data = charealloc(botline->data, length + extralen + 1);
|
||||
botline->data = nrealloc(botline->data, length + extralen + 1);
|
||||
strcpy(botline->data + length, tailtext);
|
||||
|
||||
/* Put the cursor at the end of the grafted text. */
|
||||
@@ -702,7 +712,7 @@ void paste_text(void)
|
||||
/* The leftedge where we started the paste. */
|
||||
|
||||
if (cutbuffer == NULL) {
|
||||
statusbar(_("Cutbuffer is empty"));
|
||||
statusline(AHEM, _("Cutbuffer is empty"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -724,6 +734,10 @@ void paste_text(void)
|
||||
/* If we pasted less than a screenful, don't center the cursor. */
|
||||
if (less_than_a_screenful(was_lineno, was_leftedge))
|
||||
focusing = FALSE;
|
||||
#ifdef ENABLE_COLOR
|
||||
else
|
||||
precalc_multicolorinfo();
|
||||
#endif
|
||||
|
||||
/* Set the desired x position to where the pasted text ends. */
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* definitions.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -41,10 +41,55 @@
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
/* Set a default value for PATH_MAX if there isn't one. */
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include <dirent.h>
|
||||
#include <regex.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* Prefer wide ncurses over normal ncurses over curses. */
|
||||
#if defined(HAVE_NCURSESW_NCURSES_H)
|
||||
#include <ncursesw/ncurses.h>
|
||||
#elif defined(HAVE_NCURSES_H)
|
||||
#include <ncurses.h>
|
||||
#else
|
||||
#include <curses.h>
|
||||
#endif
|
||||
|
||||
/* Native language support. */
|
||||
#ifdef ENABLE_NLS
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
#define _(string) gettext(string)
|
||||
#define P_(singular, plural, number) ngettext(singular, plural, number)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#define P_(singular, plural, number) (number == 1 ? singular : plural)
|
||||
#endif
|
||||
/* For marking a string on which gettext() will be called later. */
|
||||
#define gettext_noop(string) (string)
|
||||
#define N_(string) gettext_noop(string)
|
||||
|
||||
/* If we aren't using an ncurses with mouse support, then
|
||||
* exclude the mouse routines, as they are useless then. */
|
||||
#ifndef NCURSES_MOUSE_VERSION
|
||||
#undef ENABLE_MOUSE
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_WRAPPING) || defined(ENABLE_JUSTIFY)
|
||||
#define ENABLED_WRAPORJUSTIFY 1
|
||||
#endif
|
||||
|
||||
/* Suppress warnings for __attribute__((warn_unused_result)). */
|
||||
#define IGNORE_CALL_RESULT(call) do { if (call) {} } while(0)
|
||||
|
||||
@@ -56,74 +101,6 @@
|
||||
#define ISSET(flag) ((FLAGS(flag) & FLAGMASK(flag)) != 0)
|
||||
#define TOGGLE(flag) FLAGS(flag) ^= FLAGMASK(flag)
|
||||
|
||||
/* Macros for allocation of character strings. */
|
||||
#define charalloc(howmuch) (char *)nmalloc(howmuch)
|
||||
#define charealloc(ptr, howmuch) (char *)nrealloc(ptr, howmuch)
|
||||
|
||||
/* In UTF-8 a character is at most six bytes long. */
|
||||
#ifdef ENABLE_UTF8
|
||||
#define MAXCHARLEN 6
|
||||
#else
|
||||
#define MAXCHARLEN 1
|
||||
#endif
|
||||
|
||||
/* Set a default value for PATH_MAX if there isn't one. */
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#ifdef USE_SLANG
|
||||
/* Slang support. */
|
||||
#include <slcurses.h>
|
||||
/* Slang curses emulation brain damage, part 3: Slang doesn't define the
|
||||
* curses equivalents of the Insert or Delete keys. */
|
||||
#define KEY_DC SL_KEY_DELETE
|
||||
#define KEY_IC SL_KEY_IC
|
||||
/* Ncurses support. */
|
||||
#elif defined(HAVE_NCURSESW_NCURSES_H)
|
||||
#include <ncursesw/ncurses.h>
|
||||
#elif defined(HAVE_NCURSES_H)
|
||||
#include <ncurses.h>
|
||||
#else
|
||||
/* Curses support. */
|
||||
#include <curses.h>
|
||||
#endif /* CURSES_H */
|
||||
|
||||
#if defined(NCURSES_VERSION_MAJOR) && (NCURSES_VERSION_MAJOR < 6)
|
||||
#define USING_OLD_NCURSES yes
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
/* Native language support. */
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
#define _(string) gettext(string)
|
||||
#define P_(singular, plural, number) ngettext(singular, plural, number)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#define P_(singular, plural, number) (number == 1 ? singular : plural)
|
||||
#endif
|
||||
#define gettext_noop(string) (string)
|
||||
#define N_(string) gettext_noop(string)
|
||||
/* Mark a string that will be sent to gettext() later. */
|
||||
|
||||
#include <dirent.h>
|
||||
#include <regex.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* If we aren't using an ncurses with mouse support, exclude any
|
||||
* mouse routines, as they are useless then. */
|
||||
#ifndef NCURSES_MOUSE_VERSION
|
||||
#undef ENABLE_MOUSE
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_WRAPPING) || defined(ENABLE_JUSTIFY)
|
||||
#define ENABLED_WRAPORJUSTIFY 1
|
||||
#endif
|
||||
|
||||
#define BACKWARD FALSE
|
||||
#define FORWARD TRUE
|
||||
|
||||
@@ -134,12 +111,138 @@
|
||||
#define REPLACING 1
|
||||
#define INREGION 2
|
||||
|
||||
/* In UTF-8 a character is at most six bytes long. */
|
||||
#ifdef ENABLE_UTF8
|
||||
#define MAXCHARLEN 6
|
||||
#else
|
||||
#define MAXCHARLEN 1
|
||||
#endif
|
||||
|
||||
/* The default width of a tab in spaces. */
|
||||
#define WIDTH_OF_TAB 8
|
||||
|
||||
/* The default number of columns from end of line where wrapping occurs. */
|
||||
#define COLUMNS_FROM_EOL 8
|
||||
|
||||
/* The default comment character when a syntax does not specify any. */
|
||||
#define GENERAL_COMMENT_CHARACTER "#"
|
||||
|
||||
/* The maximum number of search/replace history strings saved. */
|
||||
#define MAX_SEARCH_HISTORY 100
|
||||
|
||||
/* The largest size_t number that doesn't have the high bit set. */
|
||||
#define HIGHEST_POSITIVE ((~(size_t)0) >> 1)
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
#define THE_DEFAULT -1
|
||||
#define BAD_COLOR -2
|
||||
|
||||
/* Flags for indicating how a multiline regex pair apply to a line. */
|
||||
#define NOTHING (1<<1)
|
||||
/* The start/end regexes don't cover this line at all. */
|
||||
#define STARTSHERE (1<<2)
|
||||
/* The start regex matches on this line, the end regex on a later one. */
|
||||
#define WHOLELINE (1<<3)
|
||||
/* The start regex matches on an earlier line, the end regex on a later one. */
|
||||
#define ENDSHERE (1<<4)
|
||||
/* The start regex matches on an earlier line, the end regex on this one. */
|
||||
#define JUSTONTHIS (1<<5)
|
||||
/* Both the start and end regexes match within this line. */
|
||||
#define WOULDBE (1<<6)
|
||||
/* An unpaired start match is on or before this line. */
|
||||
#endif
|
||||
|
||||
#define STANDARD_INPUT 0
|
||||
/* Basic control codes. */
|
||||
#define ESC_CODE 0x1B
|
||||
#define DEL_CODE 0x7F
|
||||
|
||||
/* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
|
||||
#define CONTROL_LEFT 0x401
|
||||
#define CONTROL_RIGHT 0x402
|
||||
#define CONTROL_UP 0x403
|
||||
#define CONTROL_DOWN 0x404
|
||||
#define CONTROL_HOME 0x405
|
||||
#define CONTROL_END 0x406
|
||||
#define CONTROL_DELETE 0x40D
|
||||
#define SHIFT_CONTROL_LEFT 0x411
|
||||
#define SHIFT_CONTROL_RIGHT 0x412
|
||||
#define SHIFT_CONTROL_UP 0x413
|
||||
#define SHIFT_CONTROL_DOWN 0x414
|
||||
#define SHIFT_CONTROL_HOME 0x415
|
||||
#define SHIFT_CONTROL_END 0x416
|
||||
#define CONTROL_SHIFT_DELETE 0x41D
|
||||
#define ALT_LEFT 0x421
|
||||
#define ALT_RIGHT 0x422
|
||||
#define ALT_UP 0x423
|
||||
#define ALT_DOWN 0x424
|
||||
#define ALT_PAGEUP 0x427
|
||||
#define ALT_PAGEDOWN 0x428
|
||||
#define ALT_INSERT 0x42C
|
||||
#define ALT_DELETE 0x42D
|
||||
#define SHIFT_ALT_LEFT 0x431
|
||||
#define SHIFT_ALT_RIGHT 0x432
|
||||
#define SHIFT_ALT_UP 0x433
|
||||
#define SHIFT_ALT_DOWN 0x434
|
||||
//#define SHIFT_LEFT 0x451
|
||||
//#define SHIFT_RIGHT 0x452
|
||||
#define SHIFT_UP 0x453
|
||||
#define SHIFT_DOWN 0x454
|
||||
#define SHIFT_HOME 0x455
|
||||
#define SHIFT_END 0x456
|
||||
#define SHIFT_PAGEUP 0x457
|
||||
#define SHIFT_PAGEDOWN 0x458
|
||||
#define SHIFT_DELETE 0x45D
|
||||
#define SHIFT_TAB 0x45F
|
||||
|
||||
/* A special keycode for when <Tab> is pressed while the mark is on. */
|
||||
#define INDENT_KEY 0x4F1
|
||||
|
||||
/* A special keycode to signal the beginning and end of a bracketed paste. */
|
||||
#define BRACKETED_PASTE_MARKER 0x4FB
|
||||
|
||||
/* A special keycode for when a key produces an unknown escape sequence. */
|
||||
#define FOREIGN_SEQUENCE 0x4FC
|
||||
|
||||
/* A special keycode for plugging into the input stream after a suspension. */
|
||||
#define KEY_FLUSH KEY_F0
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* A special keycode for when we get a SIGWINCH (a window resize). */
|
||||
#define KEY_WINCH -2
|
||||
|
||||
/* Some extra flags for the undo function. */
|
||||
#define WAS_BACKSPACE_AT_EOF (1<<1)
|
||||
#define WAS_WHOLE_LINE (1<<2)
|
||||
#define INCLUDED_LAST_LINE (1<<3)
|
||||
#define MARK_WAS_SET (1<<4)
|
||||
#define CURSOR_WAS_AT_HEAD (1<<5)
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Identifiers for the different menus. */
|
||||
#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 MEXECUTE (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 Browser and YesNo. */
|
||||
#define MMOST (MMAIN|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE|MWRITEFILE|MINSERTFILE|\
|
||||
MEXECUTE|MWHEREISFILE|MGOTODIR|MFINDINHELP|MSPELL|MLINTER)
|
||||
#ifndef NANO_TINY
|
||||
#define MSOME MMOST|MBROWSER
|
||||
#else
|
||||
#define MSOME MMAIN|MBROWSER
|
||||
#endif
|
||||
|
||||
/* Enumeration types. */
|
||||
typedef enum {
|
||||
@@ -147,17 +250,13 @@ typedef enum {
|
||||
} format_type;
|
||||
|
||||
typedef enum {
|
||||
VACUUM, HUSH, NOTICE, MILD, ALERT
|
||||
VACUUM, HUSH, REMARK, INFO, NOTICE, AHEM, MILD, ALERT
|
||||
} message_type;
|
||||
|
||||
typedef enum {
|
||||
OVERWRITE, APPEND, PREPEND
|
||||
} kind_of_writing_type;
|
||||
|
||||
typedef enum {
|
||||
SOFTMARK, HARDMARK
|
||||
} mark_type;
|
||||
|
||||
typedef enum {
|
||||
CENTERING, FLOWING, STATIONARY
|
||||
} update_type;
|
||||
@@ -176,6 +275,78 @@ typedef enum {
|
||||
COUPLE_BEGIN, COUPLE_END, OTHER
|
||||
} undo_type;
|
||||
|
||||
/* The elements of the interface that can be colored differently. */
|
||||
enum {
|
||||
TITLE_BAR = 0,
|
||||
LINE_NUMBER,
|
||||
GUIDE_STRIPE,
|
||||
SCROLL_BAR,
|
||||
SELECTED_TEXT,
|
||||
HIGHLIGHTED,
|
||||
PROMPT_BAR,
|
||||
STATUS_BAR,
|
||||
ERROR_MESSAGE,
|
||||
KEY_COMBO,
|
||||
FUNCTION_TAG,
|
||||
NUMBER_OF_ELEMENTS
|
||||
};
|
||||
|
||||
/* Enumeration used in the flags array. See the definition of FLAGMASK. */
|
||||
enum {
|
||||
DONTUSE = 0,
|
||||
CASE_SENSITIVE,
|
||||
CONSTANT_SHOW,
|
||||
NO_HELP,
|
||||
SUSPENDABLE,
|
||||
NO_WRAP,
|
||||
AUTOINDENT,
|
||||
VIEW_MODE,
|
||||
USE_MOUSE,
|
||||
USE_REGEXP,
|
||||
SAVE_ON_EXIT,
|
||||
CUT_FROM_CURSOR,
|
||||
BACKWARDS_SEARCH,
|
||||
MULTIBUFFER,
|
||||
SMOOTH_SCROLL,
|
||||
REBIND_DELETE,
|
||||
RAW_SEQUENCES,
|
||||
NO_CONVERT,
|
||||
MAKE_BACKUP,
|
||||
INSECURE_BACKUP,
|
||||
NO_SYNTAX,
|
||||
PRESERVE,
|
||||
HISTORYLOG,
|
||||
RESTRICTED,
|
||||
SMART_HOME,
|
||||
WHITESPACE_DISPLAY,
|
||||
MORE_SPACE,
|
||||
TABS_TO_SPACES,
|
||||
QUICK_BLANK,
|
||||
WORD_BOUNDS,
|
||||
NO_NEWLINES,
|
||||
BOLD_TEXT,
|
||||
SOFTWRAP,
|
||||
POSITIONLOG,
|
||||
LOCKING,
|
||||
NOREAD_MODE,
|
||||
MAKE_IT_UNIX,
|
||||
TRIM_BLANKS,
|
||||
SHOW_CURSOR,
|
||||
LINE_NUMBERS,
|
||||
NO_PAUSES,
|
||||
AT_BLANKS,
|
||||
AFTER_ENDS,
|
||||
LET_THEM_ZAP,
|
||||
BREAK_LONG_LINES,
|
||||
JUMPY_SCROLLING,
|
||||
EMPTY_LINE,
|
||||
INDICATOR,
|
||||
BOOKSTYLE,
|
||||
STATEFLAGS,
|
||||
USE_MAGIC,
|
||||
MINIBAR
|
||||
};
|
||||
|
||||
/* Structure types. */
|
||||
#ifdef ENABLE_COLOR
|
||||
typedef struct colortype {
|
||||
@@ -222,7 +393,7 @@ typedef struct syntaxtype {
|
||||
/* File where the syntax is defined, or NULL if not an included file. */
|
||||
size_t lineno;
|
||||
/* The line number where the 'syntax' command was found. */
|
||||
struct augmentstruct *augmentations;
|
||||
augmentstruct *augmentations;
|
||||
/* List of extendsyntax commands to apply when loaded. */
|
||||
regexlisttype *extensions;
|
||||
/* The list of extensions that this syntax applies to. */
|
||||
@@ -262,20 +433,6 @@ typedef struct lintstruct {
|
||||
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. */
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* More structure types. */
|
||||
@@ -345,11 +502,11 @@ typedef struct undostruct {
|
||||
#ifdef ENABLE_HISTORIES
|
||||
typedef struct poshiststruct {
|
||||
char *filename;
|
||||
/* The file. */
|
||||
ssize_t lineno;
|
||||
/* Line number we left off on. */
|
||||
ssize_t xno;
|
||||
/* The x position in the file we left off on. */
|
||||
/* The full path plus name of the file. */
|
||||
ssize_t linenumber;
|
||||
/* The line where the cursor was when we closed the file. */
|
||||
ssize_t columnnumber;
|
||||
/* The column where the cursor was. */
|
||||
struct poshiststruct *next;
|
||||
/* The next item of position history. */
|
||||
} poshiststruct;
|
||||
@@ -388,8 +545,8 @@ typedef struct openfilestruct {
|
||||
/* 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. */
|
||||
bool softmark;
|
||||
/* Whether a marked region was made by holding Shift. */
|
||||
format_type fmt;
|
||||
/* The file's format -- Unix or DOS or Mac. */
|
||||
char *lock_filename;
|
||||
@@ -453,8 +610,6 @@ typedef struct keystruct {
|
||||
typedef struct funcstruct {
|
||||
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
|
||||
@@ -466,8 +621,8 @@ typedef struct funcstruct {
|
||||
#endif
|
||||
bool viewok;
|
||||
/* Is this function allowed when in view mode? */
|
||||
long toggle;
|
||||
/* If this is a toggle, which toggle to affect. */
|
||||
int menus;
|
||||
/* In what menus this function applies. */
|
||||
struct funcstruct *next;
|
||||
/* Next item in the list. */
|
||||
} funcstruct;
|
||||
@@ -478,185 +633,3 @@ typedef struct completion_word {
|
||||
struct completion_word *next;
|
||||
} completion_word;
|
||||
#endif
|
||||
|
||||
/* The elements of the interface that can be colored differently. */
|
||||
enum
|
||||
{
|
||||
TITLE_BAR = 0,
|
||||
LINE_NUMBER,
|
||||
GUIDE_STRIPE,
|
||||
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,
|
||||
SUSPENDABLE,
|
||||
NO_WRAP,
|
||||
AUTOINDENT,
|
||||
VIEW_MODE,
|
||||
USE_MOUSE,
|
||||
USE_REGEXP,
|
||||
SAVE_ON_EXIT,
|
||||
CUT_FROM_CURSOR,
|
||||
BACKWARDS_SEARCH,
|
||||
MULTIBUFFER,
|
||||
SMOOTH_SCROLL,
|
||||
REBIND_DELETE,
|
||||
RAW_SEQUENCES,
|
||||
NO_CONVERT,
|
||||
MAKE_BACKUP,
|
||||
INSECURE_BACKUP,
|
||||
NO_SYNTAX,
|
||||
PRESERVE,
|
||||
HISTORYLOG,
|
||||
RESTRICTED,
|
||||
SMART_HOME,
|
||||
WHITESPACE_DISPLAY,
|
||||
MORE_SPACE,
|
||||
TABS_TO_SPACES,
|
||||
QUICK_BLANK,
|
||||
WORD_BOUNDS,
|
||||
NO_NEWLINES,
|
||||
BOLD_TEXT,
|
||||
SOFTWRAP,
|
||||
POSITIONLOG,
|
||||
LOCKING,
|
||||
NOREAD_MODE,
|
||||
MAKE_IT_UNIX,
|
||||
TRIM_BLANKS,
|
||||
SHOW_CURSOR,
|
||||
LINE_NUMBERS,
|
||||
NO_PAUSES,
|
||||
AT_BLANKS,
|
||||
AFTER_ENDS,
|
||||
LET_THEM_ZAP,
|
||||
BREAK_LONG_LINES,
|
||||
JUMPY_SCROLLING,
|
||||
EMPTY_LINE,
|
||||
INDICATOR,
|
||||
BOOKSTYLE
|
||||
};
|
||||
|
||||
/* 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 MEXECUTE (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 Browser and YesNo. */
|
||||
#define MMOST (MMAIN|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE|MWRITEFILE|MINSERTFILE|\
|
||||
MEXECUTE|MWHEREISFILE|MGOTODIR|MFINDINHELP|MSPELL|MLINTER)
|
||||
#ifndef NANO_TINY
|
||||
#define MSOME MMOST|MBROWSER
|
||||
#else
|
||||
#define MSOME MMAIN|MBROWSER
|
||||
#endif
|
||||
|
||||
/* Basic control codes. */
|
||||
#define ESC_CODE 0x1B
|
||||
#define DEL_CODE 0x7F
|
||||
|
||||
/* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
|
||||
#define CONTROL_LEFT 0x401
|
||||
#define CONTROL_RIGHT 0x402
|
||||
#define CONTROL_UP 0x403
|
||||
#define CONTROL_DOWN 0x404
|
||||
#define CONTROL_HOME 0x405
|
||||
#define CONTROL_END 0x406
|
||||
#define CONTROL_DELETE 0x40D
|
||||
#define SHIFT_CONTROL_LEFT 0x411
|
||||
#define SHIFT_CONTROL_RIGHT 0x412
|
||||
#define SHIFT_CONTROL_UP 0x413
|
||||
#define SHIFT_CONTROL_DOWN 0x414
|
||||
#define SHIFT_CONTROL_HOME 0x415
|
||||
#define SHIFT_CONTROL_END 0x416
|
||||
#define CONTROL_SHIFT_DELETE 0x41D
|
||||
#define ALT_LEFT 0x421
|
||||
#define ALT_RIGHT 0x422
|
||||
#define ALT_UP 0x423
|
||||
#define ALT_DOWN 0x424
|
||||
#define ALT_PAGEUP 0x427
|
||||
#define ALT_PAGEDOWN 0x428
|
||||
#define ALT_INSERT 0x42C
|
||||
#define ALT_DELETE 0x42D
|
||||
#define SHIFT_ALT_LEFT 0x431
|
||||
#define SHIFT_ALT_RIGHT 0x432
|
||||
#define SHIFT_ALT_UP 0x433
|
||||
#define SHIFT_ALT_DOWN 0x434
|
||||
//#define SHIFT_LEFT 0x451
|
||||
//#define SHIFT_RIGHT 0x452
|
||||
#define SHIFT_UP 0x453
|
||||
#define SHIFT_DOWN 0x454
|
||||
#define SHIFT_HOME 0x455
|
||||
#define SHIFT_END 0x456
|
||||
#define SHIFT_PAGEUP 0x457
|
||||
#define SHIFT_PAGEDOWN 0x458
|
||||
#define SHIFT_DELETE 0x45D
|
||||
#define SHIFT_TAB 0x45F
|
||||
|
||||
/* A special keycode for when <Tab> is pressed while the mark is on. */
|
||||
#define INDENT_KEY 0x4F1
|
||||
|
||||
/* A special keycode to signal the beginning and end of a bracketed paste. */
|
||||
#define BRACKETED_PASTE_MARKER 0x4FB
|
||||
|
||||
/* A special keycode for when a key produces an unknown escape sequence. */
|
||||
#define FOREIGN_SEQUENCE 0x4FC
|
||||
|
||||
#ifdef USE_SLANG
|
||||
#ifdef ENABLE_UTF8
|
||||
#define KEY_BAD 0xFF /* Clipped error code. */
|
||||
#endif
|
||||
#define KEY_FLUSH 0x91 /* User-definable control code. */
|
||||
#else
|
||||
#define KEY_FLUSH KEY_F0 /* Nonexistent function key. */
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* An imaginary key for when we get a SIGWINCH (window resize). */
|
||||
#define KEY_WINCH -2
|
||||
|
||||
/* Some extra flags for the undo function. */
|
||||
#define WAS_BACKSPACE_AT_EOF (1<<1)
|
||||
#define WAS_WHOLE_LINE (1<<2)
|
||||
#define INCLUDED_LAST_LINE (1<<3)
|
||||
#define MARK_WAS_SET (1<<4)
|
||||
#define CURSOR_WAS_AT_HEAD (1<<5)
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* The default number of columns from end of line where wrapping occurs. */
|
||||
#define COLUMNS_FROM_EOL 8
|
||||
|
||||
/* The default width of a tab in spaces. */
|
||||
#define WIDTH_OF_TAB 8
|
||||
|
||||
/* The default comment character when a syntax does not specify any. */
|
||||
#define GENERAL_COMMENT_CHARACTER "#"
|
||||
|
||||
/* The maximum number of search/replace history strings saved, not
|
||||
* counting the blank lines at their ends. */
|
||||
#define MAX_SEARCH_HISTORY 100
|
||||
|
||||
/* The largest size_t number that doesn't have the high bit set. */
|
||||
#define HIGHEST_POSITIVE ((~(size_t)0) >> 1)
|
||||
|
||||
202
src/files.c
202
src/files.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* files.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -81,6 +81,7 @@ void make_new_buffer(void)
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
openfile->mark = NULL;
|
||||
openfile->softmark = FALSE;
|
||||
|
||||
openfile->fmt = NIX_FILE;
|
||||
|
||||
@@ -97,6 +98,26 @@ void make_new_buffer(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the given file name in a way that fits within the given space. */
|
||||
char *crop_to_fit(const char *name, int room)
|
||||
{
|
||||
char *clipped;
|
||||
|
||||
if (breadth(name) <= room)
|
||||
return display_string(name, 0, room, FALSE, FALSE);
|
||||
|
||||
if (room < 4)
|
||||
return copy_of("_");
|
||||
|
||||
clipped = display_string(name, breadth(name) - room + 3, room, FALSE, FALSE);
|
||||
|
||||
clipped = nrealloc(clipped, strlen(clipped) + 4);
|
||||
memmove(clipped + 3, clipped, strlen(clipped) + 1);
|
||||
clipped[0] = '.'; clipped[1] = '.'; clipped[2] = '.';
|
||||
|
||||
return clipped;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Delete the lockfile. Return TRUE on success, and FALSE otherwise. */
|
||||
bool delete_lockfile(const char *lockfilename)
|
||||
@@ -159,7 +180,7 @@ bool write_lockfile(const char *lockfilename, const char *filename, bool modifie
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lockdata = charalloc(LOCKSIZE);
|
||||
lockdata = nmalloc(LOCKSIZE);
|
||||
memset(lockdata, 0, LOCKSIZE);
|
||||
|
||||
/* This is the lock data we will store (other bytes remain 0x00):
|
||||
@@ -212,7 +233,7 @@ char *do_lockfile(const char *filename, bool ask_the_user)
|
||||
char *secondcopy = copy_of(filename);
|
||||
size_t locknamesize = strlen(filename) + strlen(locking_prefix) +
|
||||
strlen(locking_suffix) + 3;
|
||||
char *lockfilename = charalloc(locknamesize);
|
||||
char *lockfilename = nmalloc(locknamesize);
|
||||
struct stat fileinfo;
|
||||
|
||||
snprintf(lockfilename, locknamesize, "%s/%s%s%s", dirname(namecopy),
|
||||
@@ -225,7 +246,7 @@ char *do_lockfile(const char *filename, bool ask_the_user)
|
||||
else if (stat(lockfilename, &fileinfo) != -1) {
|
||||
char *lockbuf, *question, *pidstring, *postedname, *promptstr;
|
||||
static char lockprog[11], lockuser[17];
|
||||
int lockfd, lockpid, room, choice;
|
||||
int lockfd, lockpid, choice;
|
||||
ssize_t readamt;
|
||||
|
||||
if ((lockfd = open(lockfilename, O_RDONLY)) < 0) {
|
||||
@@ -235,7 +256,7 @@ char *do_lockfile(const char *filename, bool ask_the_user)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lockbuf = charalloc(LOCKSIZE);
|
||||
lockbuf = nmalloc(LOCKSIZE);
|
||||
|
||||
readamt = read(lockfd, lockbuf, LOCKSIZE);
|
||||
|
||||
@@ -258,7 +279,7 @@ char *do_lockfile(const char *filename, bool ask_the_user)
|
||||
lockuser[16] = '\0';
|
||||
free(lockbuf);
|
||||
|
||||
pidstring = charalloc(11);
|
||||
pidstring = nmalloc(11);
|
||||
sprintf (pidstring, "%u", (unsigned int)lockpid);
|
||||
|
||||
/* Display newlines in filenames as ^J. */
|
||||
@@ -266,23 +287,12 @@ char *do_lockfile(const char *filename, bool ask_the_user)
|
||||
|
||||
/* TRANSLATORS: The second %s is the name of the user, the third that of the editor. */
|
||||
question = _("File %s is being edited by %s (with %s, PID %s); open anyway?");
|
||||
room = COLS - breadth(question) + 7 - breadth(lockuser) -
|
||||
breadth(lockprog) - breadth(pidstring);
|
||||
if (room < 4)
|
||||
postedname = copy_of("_");
|
||||
else if (room < breadth(filename)) {
|
||||
char *fragment = display_string(filename,
|
||||
breadth(filename) - room + 3, room, FALSE, FALSE);
|
||||
postedname = charalloc(strlen(fragment) + 4);
|
||||
strcpy(postedname, "...");
|
||||
strcat(postedname, fragment);
|
||||
free(fragment);
|
||||
} else
|
||||
postedname = display_string(filename, 0, room, FALSE, FALSE);
|
||||
postedname = crop_to_fit(filename, COLS - breadth(question) - breadth(lockuser) -
|
||||
breadth(lockprog) - breadth(pidstring) + 7);
|
||||
|
||||
/* Allow extra space for username (14), program name (8), PID (8),
|
||||
* and terminating \0 (1), minus the %s (2) for the file name. */
|
||||
promptstr = charalloc(strlen(question) + 29 + strlen(postedname));
|
||||
promptstr = nmalloc(strlen(question) + 29 + strlen(postedname));
|
||||
sprintf(promptstr, question, postedname, lockuser, lockprog, pidstring);
|
||||
free(postedname);
|
||||
free(pidstring);
|
||||
@@ -314,7 +324,7 @@ char *do_lockfile(const char *filename, bool ask_the_user)
|
||||
void stat_with_alloc(const char *filename, struct stat **pstat)
|
||||
{
|
||||
if (*pstat == NULL)
|
||||
*pstat = (struct stat *)nmalloc(sizeof(struct stat));
|
||||
*pstat = nmalloc(sizeof(struct stat));
|
||||
|
||||
if (stat(filename, *pstat) != 0) {
|
||||
free(*pstat);
|
||||
@@ -488,7 +498,8 @@ void prepare_for_display(void)
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
/* Precalculate the data for any multiline coloring regexes. */
|
||||
precalc_multicolorinfo();
|
||||
if (!openfile->filetop->multidata)
|
||||
precalc_multicolorinfo();
|
||||
have_palette = FALSE;
|
||||
#endif
|
||||
refresh_needed = TRUE;
|
||||
@@ -500,7 +511,13 @@ void mention_name_and_linecount(void)
|
||||
{
|
||||
size_t count = openfile->filebot->lineno -
|
||||
(openfile->filebot->data[0] == '\0' ? 1 : 0);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(MINIBAR)) {
|
||||
report_size = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (openfile->fmt != NIX_FILE)
|
||||
/* TRANSLATORS: First %s is file name, second %s is file format. */
|
||||
statusline(HUSH, P_("%s -- %zu line (%s)", "%s -- %zu lines (%s)", count),
|
||||
@@ -519,7 +536,7 @@ void redecorate_after_switch(void)
|
||||
{
|
||||
/* If only one file buffer is open, there is nothing to update. */
|
||||
if (openfile == openfile->next) {
|
||||
statusbar(_("No more open file buffers"));
|
||||
statusline(AHEM, _("No more open file buffers"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -615,7 +632,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
/* The length of the current line of the file. */
|
||||
size_t bufsize = LUMPSIZE;
|
||||
/* The size of the line buffer; increased as needed. */
|
||||
char *buf = charalloc(bufsize);
|
||||
char *buf = nmalloc(bufsize);
|
||||
/* The buffer in which we assemble each line of the file. */
|
||||
linestruct *topline;
|
||||
/* The top of the new buffer where we store the read file. */
|
||||
@@ -689,7 +706,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
* decreasing it -- it gets freed when reading is finished. */
|
||||
if (len == bufsize) {
|
||||
bufsize += LUMPSIZE;
|
||||
buf = charealloc(buf, bufsize);
|
||||
buf = nrealloc(buf, bufsize);
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -719,15 +736,15 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
|
||||
#ifndef NANO_TINY
|
||||
block_sigwinch(FALSE);
|
||||
#endif
|
||||
|
||||
/* When reading from stdin, restore the terminal and reenter curses mode. */
|
||||
if (isendwin()) {
|
||||
if (!isatty(STANDARD_INPUT))
|
||||
if (!isatty(STDIN_FILENO))
|
||||
reconnect_and_store_state();
|
||||
terminal_init();
|
||||
doupdate();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there was a real error during the reading, let the user know. */
|
||||
if (ferror(f) && errornumber != EINTR && errornumber != 0)
|
||||
@@ -802,6 +819,10 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
/* If we inserted less than a screenful, don't center the cursor. */
|
||||
if (undoable && less_than_a_screenful(was_lineno, was_leftedge))
|
||||
focusing = FALSE;
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (undoable)
|
||||
precalc_multicolorinfo();
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (undoable)
|
||||
@@ -831,7 +852,7 @@ int open_file(const char *filename, bool new_one, FILE **f)
|
||||
free(full_filename);
|
||||
|
||||
if (new_one) {
|
||||
statusbar(_("New File"));
|
||||
statusline(REMARK, _("New File"));
|
||||
return 0;
|
||||
} else {
|
||||
statusline(ALERT, _("File \"%s\" not found"), filename);
|
||||
@@ -889,7 +910,7 @@ char *get_next_filename(const char *name, const char *suffix)
|
||||
|
||||
/* Reserve space for: the name plus the suffix plus a dot plus
|
||||
* possibly five digits plus a null byte. */
|
||||
buf = charalloc(wholenamelen + 7);
|
||||
buf = nmalloc(wholenamelen + 7);
|
||||
sprintf(buf, "%s%s", name, suffix);
|
||||
|
||||
while (TRUE) {
|
||||
@@ -916,7 +937,7 @@ static pid_t pid_of_command = -1;
|
||||
/* The PID of a forked process -- needed when wanting to abort it. */
|
||||
|
||||
/* Send an unconditional kill signal to the running external command. */
|
||||
RETSIGTYPE cancel_the_command(int signal)
|
||||
void cancel_the_command(int signal)
|
||||
{
|
||||
kill(pid_of_command, SIGKILL);
|
||||
}
|
||||
@@ -966,13 +987,16 @@ bool execute_command(const char *command)
|
||||
close(from_fd[0]);
|
||||
|
||||
/* Connect the write end of the output pipe to the process' output streams. */
|
||||
dup2(from_fd[1], fileno(stdout));
|
||||
dup2(from_fd[1], fileno(stderr));
|
||||
if (dup2(from_fd[1], STDOUT_FILENO) < 0)
|
||||
exit(3);
|
||||
if (dup2(from_fd[1], STDERR_FILENO) < 0)
|
||||
exit(4);
|
||||
|
||||
/* If the parent sends text, connect the read end of the
|
||||
* feeding pipe to the child's input stream. */
|
||||
if (should_pipe) {
|
||||
dup2(to_fd[0], fileno(stdin));
|
||||
if (dup2(to_fd[0], STDIN_FILENO) < 0)
|
||||
exit(5);
|
||||
close(to_fd[1]);
|
||||
}
|
||||
|
||||
@@ -980,7 +1004,7 @@ bool execute_command(const char *command)
|
||||
execl(theshell, tail(theshell), "-c", should_pipe ? &command[1] : command, NULL);
|
||||
|
||||
/* If the exec call returns, there was an error. */
|
||||
exit(1);
|
||||
exit(6);
|
||||
}
|
||||
|
||||
/* Parent: close the unused write end of the pipe. */
|
||||
@@ -1307,7 +1331,7 @@ char *get_full_path(const char *origpath)
|
||||
if (origpath == NULL)
|
||||
return NULL;
|
||||
|
||||
allocation = charalloc(PATH_MAX + 1);
|
||||
allocation = nmalloc(PATH_MAX + 1);
|
||||
here = getcwd(allocation, PATH_MAX + 1);
|
||||
|
||||
/* If getting the current directory failed, go up one level and try again,
|
||||
@@ -1321,7 +1345,7 @@ char *get_full_path(const char *origpath)
|
||||
/* If we found a directory, make sure its path ends in a slash. */
|
||||
if (here != NULL) {
|
||||
if (strcmp(here, "/") != 0) {
|
||||
here = charealloc(here, strlen(here) + 2);
|
||||
here = nrealloc(here, strlen(here) + 2);
|
||||
strcat(here, "/");
|
||||
}
|
||||
} else {
|
||||
@@ -1340,7 +1364,7 @@ char *get_full_path(const char *origpath)
|
||||
size_t length = strlen(target);
|
||||
|
||||
if (target[length - 1] != '/') {
|
||||
target = charealloc(target, length + 2);
|
||||
target = nrealloc(target, length + 2);
|
||||
strcat(target, "/");
|
||||
}
|
||||
}
|
||||
@@ -1367,14 +1391,14 @@ char *get_full_path(const char *origpath)
|
||||
} else {
|
||||
free(target);
|
||||
|
||||
allocation = charalloc(PATH_MAX + 1);
|
||||
allocation = nmalloc(PATH_MAX + 1);
|
||||
target = getcwd(allocation, PATH_MAX + 1);
|
||||
|
||||
/* If we got a result, make sure it ends in a slash.
|
||||
* Otherwise, ensure that we return NULL. */
|
||||
if (target != NULL) {
|
||||
if (strcmp(target, "/") != 0) {
|
||||
target = charealloc(target, strlen(target) + 2);
|
||||
target = nrealloc(target, strlen(target) + 2);
|
||||
strcat(target, "/");
|
||||
}
|
||||
} else {
|
||||
@@ -1393,7 +1417,7 @@ char *get_full_path(const char *origpath)
|
||||
/* If we were given more than a bare path, concatenate the target path
|
||||
* with the filename portion to get the full, absolute file path. */
|
||||
if (!path_only && target != NULL) {
|
||||
target = charealloc(target, strlen(target) + strlen(just_filename) + 1);
|
||||
target = nrealloc(target, strlen(target) + strlen(just_filename) + 1);
|
||||
strcat(target, just_filename);
|
||||
}
|
||||
|
||||
@@ -1439,7 +1463,7 @@ char *safe_tempfile(FILE **stream)
|
||||
if (tempdir == NULL)
|
||||
tempdir = copy_of("/tmp/");
|
||||
|
||||
tempfile_name = charealloc(tempdir, strlen(tempdir) + 12);
|
||||
tempfile_name = nrealloc(tempdir, strlen(tempdir) + 12);
|
||||
strcat(tempfile_name, "nano.XXXXXX");
|
||||
|
||||
fd = mkstemp(tempfile_name);
|
||||
@@ -1465,7 +1489,7 @@ void init_operating_dir(void)
|
||||
die(_("Invalid operating directory: %s\n"), operating_dir);
|
||||
|
||||
free(operating_dir);
|
||||
operating_dir = charealloc(target, strlen(target) + 1);
|
||||
operating_dir = nrealloc(target, strlen(target) + 1);
|
||||
}
|
||||
|
||||
/* Check whether the given path is outside of the operating directory.
|
||||
@@ -1514,7 +1538,7 @@ void init_backup_dir(void)
|
||||
die(_("Invalid backup directory: %s\n"), backup_dir);
|
||||
|
||||
free(backup_dir);
|
||||
backup_dir = charealloc(target, strlen(target) + 1);
|
||||
backup_dir = nrealloc(target, strlen(target) + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1556,10 +1580,11 @@ int copy_file(FILE *inn, FILE *out, bool close_out)
|
||||
bool make_backup_of(char *realname)
|
||||
{
|
||||
FILE *original = NULL, *backup_file = NULL;
|
||||
int creation_flags, descriptor, verdict;
|
||||
static struct timespec filetime[2];
|
||||
int creation_flags, descriptor;
|
||||
bool second_attempt = FALSE;
|
||||
char *backupname = NULL;
|
||||
int verdict = 0;
|
||||
|
||||
/* Remember the original file's access and modification times. */
|
||||
filetime[0].tv_sec = openfile->statinfo->st_atime;
|
||||
@@ -1571,7 +1596,7 @@ bool make_backup_of(char *realname)
|
||||
* by appending a tilde to the original file name. Otherwise,
|
||||
* we create a numbered backup in the specified directory. */
|
||||
if (backup_dir == NULL) {
|
||||
backupname = charalloc(strlen(realname) + 2);
|
||||
backupname = nmalloc(strlen(realname) + 2);
|
||||
sprintf(backupname, "%s~", realname);
|
||||
} else {
|
||||
char *thename = get_full_path(realname);
|
||||
@@ -1586,7 +1611,7 @@ bool make_backup_of(char *realname)
|
||||
} else
|
||||
thename = copy_of(tail(realname));
|
||||
|
||||
backupname = charalloc(strlen(backup_dir) + strlen(thename) + 1);
|
||||
backupname = nmalloc(strlen(backup_dir) + strlen(thename) + 1);
|
||||
sprintf(backupname, "%s%s", backup_dir, thename);
|
||||
free(thename);
|
||||
|
||||
@@ -1678,7 +1703,7 @@ bool make_backup_of(char *realname)
|
||||
warn_and_briefly_pause(_("Trying again in your home directory"));
|
||||
currmenu = MMOST;
|
||||
|
||||
backupname = charalloc(strlen(homedir) + strlen(tail(realname)) + 9);
|
||||
backupname = nmalloc(strlen(homedir) + strlen(tail(realname)) + 9);
|
||||
sprintf(backupname, "%s/%s~XXXXXX", homedir, tail(realname));
|
||||
|
||||
descriptor = mkstemp(backupname);
|
||||
@@ -1977,8 +2002,13 @@ bool write_file(const char *name, FILE *thefile, bool tmp,
|
||||
titlebar(NULL);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(MINIBAR) && fullbuffer && !tmp)
|
||||
report_size = TRUE;
|
||||
else
|
||||
#endif
|
||||
if (!tmp)
|
||||
statusline(HUSH, P_("Wrote %zu line", "Wrote %zu lines",
|
||||
statusline(REMARK, P_("Wrote %zu line", "Wrote %zu lines",
|
||||
lineswritten), lineswritten);
|
||||
retval = TRUE;
|
||||
|
||||
@@ -2042,12 +2072,11 @@ bool write_marked_file(const char *name, FILE *stream, bool tmp,
|
||||
* the buffer is to be discarded. */
|
||||
int do_writeout(bool exiting, bool withprompt)
|
||||
{
|
||||
bool result = FALSE;
|
||||
kind_of_writing_type method = OVERWRITE;
|
||||
char *given;
|
||||
/* The filename we offer, or what the user typed so far. */
|
||||
bool maychange = (openfile->filename[0] == '\0');
|
||||
/* Whether it's okay to save the file under a different name. */
|
||||
kind_of_writing_type method = OVERWRITE;
|
||||
#ifdef ENABLE_EXTRA
|
||||
static bool did_credits = FALSE;
|
||||
#endif
|
||||
@@ -2104,7 +2133,8 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
|
||||
if (response < 0) {
|
||||
statusbar(_("Cancelled"));
|
||||
break;
|
||||
free(given);
|
||||
return 0;
|
||||
}
|
||||
|
||||
func = func_from_key(&response);
|
||||
@@ -2146,9 +2176,8 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (func == do_help) {
|
||||
if (func == do_help)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EXTRA
|
||||
/* If the user pressed Ctrl-X in the edit window, and answered "Y" at
|
||||
@@ -2161,8 +2190,10 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
did_credits = TRUE;
|
||||
} else
|
||||
/* TRANSLATORS: Concisely say the screen is too small. */
|
||||
statusbar(_("Too tiny"));
|
||||
break;
|
||||
statusline(AHEM, _("Too tiny"));
|
||||
|
||||
free(given);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2175,6 +2206,7 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
full_filename = get_full_path(openfile->filename);
|
||||
name_exists = (stat((full_answer == NULL) ?
|
||||
answer : full_answer, &st) != -1);
|
||||
|
||||
if (openfile->filename[0] == '\0')
|
||||
do_warning = name_exists;
|
||||
else
|
||||
@@ -2210,10 +2242,8 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
|
||||
if (name_exists) {
|
||||
char *question = _("File \"%s\" exists; OVERWRITE? ");
|
||||
char *name = display_string(answer, 0,
|
||||
COLS - breadth(question) + 1, FALSE, FALSE);
|
||||
char *message = charalloc(strlen(question) +
|
||||
strlen(name) + 1);
|
||||
char *name = crop_to_fit(answer, COLS - breadth(question) + 1);
|
||||
char *message = nmalloc(strlen(question) + strlen(name) + 1);
|
||||
|
||||
sprintf(message, question, name);
|
||||
|
||||
@@ -2261,23 +2291,19 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Here's where we allow the selected text to be written to
|
||||
* a separate file. If we're using restricted mode, this
|
||||
* function is disabled, since it allows reading from or
|
||||
* writing to files not specified on the command line. */
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->mark && !exiting && withprompt && !ISSET(RESTRICTED))
|
||||
result = write_marked_file(answer, NULL, FALSE, method);
|
||||
else
|
||||
#endif
|
||||
result = write_file(answer, NULL, FALSE, method, TRUE);
|
||||
|
||||
free(given);
|
||||
break;
|
||||
}
|
||||
|
||||
free(given);
|
||||
|
||||
return result ? 1 : 0;
|
||||
/* When the mark is on (and we've prompted for a name and we're
|
||||
* not exiting and we're not in restricted mode), then write out
|
||||
* the marked region; otherwise, write out the whole buffer. */
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->mark && withprompt && !exiting && !ISSET(RESTRICTED))
|
||||
return write_marked_file(answer, NULL, FALSE, method);
|
||||
else
|
||||
#endif
|
||||
return write_file(answer, NULL, FALSE, method, TRUE);
|
||||
}
|
||||
|
||||
/* Write the current buffer to disk, or discard it. */
|
||||
@@ -2330,7 +2356,7 @@ char *real_dir_from_tilde(const char *path)
|
||||
#endif
|
||||
}
|
||||
|
||||
retval = charalloc(strlen(tilded) + strlen(path + i) + 1);
|
||||
retval = nmalloc(strlen(tilded) + strlen(path + i) + 1);
|
||||
sprintf(retval, "%s%s", tilded, path + i);
|
||||
|
||||
free(tilded);
|
||||
@@ -2354,11 +2380,13 @@ int diralphasort(const void *va, const void *vb)
|
||||
if (!aisdir && bisdir)
|
||||
return 1;
|
||||
|
||||
/* Standard function brain damage: We should be sorting
|
||||
* alphabetically and case-insensitively according to the current
|
||||
* locale, but there's no standard strcasecoll() function, so we
|
||||
* have to use multibyte strcasecmp() instead. */
|
||||
return mbstrcasecmp(a, b);
|
||||
int difference = mbstrcasecmp(a, b);
|
||||
|
||||
/* If two names are equivalent when ignoring case, compare them bytewise. */
|
||||
if (difference == 0)
|
||||
return strcmp(a, b);
|
||||
else
|
||||
return difference;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2393,8 +2421,8 @@ char **username_completion(const char *morsel, size_t length, size_t *num_matche
|
||||
if (outside_of_confinement(userdata->pw_dir, TRUE))
|
||||
continue;
|
||||
#endif
|
||||
matches = (char **)nrealloc(matches, (*num_matches + 1) * sizeof(char *));
|
||||
matches[*num_matches] = charalloc(strlen(userdata->pw_name) + 2);
|
||||
matches = nrealloc(matches, (*num_matches + 1) * sizeof(char *));
|
||||
matches[*num_matches] = nmalloc(strlen(userdata->pw_name) + 2);
|
||||
sprintf(matches[*num_matches], "~%s", userdata->pw_name);
|
||||
++(*num_matches);
|
||||
}
|
||||
@@ -2442,7 +2470,7 @@ char **filename_completion(const char *morsel, size_t length, size_t *num_matche
|
||||
dirname = real_dir_from_tilde(dirname);
|
||||
/* A non-absolute path is relative to the current browser directory. */
|
||||
if (dirname[0] != '/') {
|
||||
dirname = charealloc(dirname, strlen(present_path) + strlen(wasdirname) + 1);
|
||||
dirname = nrealloc(dirname, strlen(present_path) + strlen(wasdirname) + 1);
|
||||
sprintf(dirname, "%s%s", present_path, wasdirname);
|
||||
}
|
||||
free(wasdirname);
|
||||
@@ -2468,7 +2496,7 @@ char **filename_completion(const char *morsel, size_t length, size_t *num_matche
|
||||
if (strncmp(entry->d_name, filename, filenamelen) == 0 &&
|
||||
strcmp(entry->d_name, ".") != 0 &&
|
||||
strcmp(entry->d_name, "..") != 0) {
|
||||
fullname = charealloc(fullname, strlen(dirname) +
|
||||
fullname = nrealloc(fullname, strlen(dirname) +
|
||||
strlen(entry->d_name) + 1);
|
||||
|
||||
sprintf(fullname, "%s%s", dirname, entry->d_name);
|
||||
@@ -2480,7 +2508,7 @@ char **filename_completion(const char *morsel, size_t length, size_t *num_matche
|
||||
if (currmenu == MGOTODIR && !is_dir(fullname))
|
||||
continue;
|
||||
|
||||
matches = (char **)nrealloc(matches, (*num_matches + 1) * sizeof(char *));
|
||||
matches = nrealloc(matches, (*num_matches + 1) * sizeof(char *));
|
||||
matches[*num_matches] = copy_of(entry->d_name);
|
||||
++(*num_matches);
|
||||
}
|
||||
@@ -2551,7 +2579,7 @@ char *input_tab(char *morsel, size_t *place, void (*refresh_func)(void), bool *l
|
||||
common_len += len1;
|
||||
}
|
||||
|
||||
shared = charalloc(length_of_path + common_len + 1);
|
||||
shared = nmalloc(length_of_path + common_len + 1);
|
||||
|
||||
strncpy(shared, morsel, length_of_path);
|
||||
strncpy(shared + length_of_path, matches[0], common_len);
|
||||
@@ -2560,7 +2588,7 @@ char *input_tab(char *morsel, size_t *place, void (*refresh_func)(void), bool *l
|
||||
shared[common_len] = '\0';
|
||||
|
||||
/* Cover also the case of the user specifying a relative path. */
|
||||
glued = charalloc(strlen(present_path) + common_len + 1);
|
||||
glued = nmalloc(strlen(present_path) + common_len + 1);
|
||||
sprintf(glued, "%s%s", present_path, shared);
|
||||
|
||||
if (num_matches == 1 && (is_dir(shared) || is_dir(glued)))
|
||||
@@ -2568,7 +2596,7 @@ char *input_tab(char *morsel, size_t *place, void (*refresh_func)(void), bool *l
|
||||
|
||||
/* If the matches have something in common, copy that part. */
|
||||
if (common_len != *place) {
|
||||
morsel = charealloc(morsel, common_len + 1);
|
||||
morsel = nrealloc(morsel, common_len + 1);
|
||||
strncpy(morsel, shared, common_len);
|
||||
morsel[common_len] = '\0';
|
||||
*place = common_len;
|
||||
|
||||
90
src/global.c
90
src/global.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* global.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -49,7 +49,8 @@ bool we_are_running = FALSE;
|
||||
/* Becomes TRUE as soon as all options and files have been read. */
|
||||
bool more_than_one = FALSE;
|
||||
/* Whether more than one buffer is or has been open. */
|
||||
|
||||
bool report_size = TRUE;
|
||||
/* Whether to show the number of lines when the minibar is used. */
|
||||
bool ran_a_tool = FALSE;
|
||||
/* Whether a tool has been run at the Execute-Command prompt. */
|
||||
|
||||
@@ -79,6 +80,8 @@ linestruct *pletion_line = NULL;
|
||||
bool also_the_last = FALSE;
|
||||
/* Whether indenting/commenting should include the last line of
|
||||
* the marked region. */
|
||||
bool hide_cursor = FALSE;
|
||||
/* Whether to suppress the cursor when highlighting a search match. */
|
||||
|
||||
char *answer = NULL;
|
||||
/* The answer string used by the status-bar prompt. */
|
||||
@@ -477,7 +480,8 @@ size_t shown_entries_for(int menu)
|
||||
}
|
||||
|
||||
/* When --saveonexit is not used, widen the grid of the WriteOut menu. */
|
||||
if (menu == MWRITEFILE && first_sc_for(menu, discard_buffer) == NULL)
|
||||
if (menu == MWRITEFILE && item == NULL &&
|
||||
first_sc_for(menu, discard_buffer) == NULL)
|
||||
count--;
|
||||
|
||||
return count;
|
||||
@@ -529,6 +533,7 @@ functionptrtype interpret(int *keycode)
|
||||
return do_findnext;
|
||||
|
||||
switch (tolower(*keycode)) {
|
||||
case 'b':
|
||||
case '-':
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
@@ -728,10 +733,11 @@ void shortcut_init(void)
|
||||
#endif
|
||||
|
||||
/* Start populating the different menus with functions. */
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
add_to_funcs(do_help, (MMOST | MBROWSER) & ~MFINDINHELP,
|
||||
/* TRANSLATORS: Try to keep the next thirteen strings at most 10 characters. */
|
||||
N_("Help"), WITHORSANS(help_gist), TOGETHER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_cancel, ((MMOST & ~MMAIN) | MYESNO),
|
||||
N_("Cancel"), WITHORSANS(cancel_gist), BLANKAFTER, VIEW);
|
||||
@@ -746,6 +752,15 @@ void shortcut_init(void)
|
||||
close_tag, WITHORSANS(exitbrowser_gist), TOGETHER, VIEW);
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_HELP
|
||||
add_to_funcs(full_refresh, MMAIN|MREPLACE, "Refresh", "x", 0, VIEW);
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(full_refresh, MINSERTFILE|MEXECUTE, "Refresh", "x", 0, VIEW);
|
||||
#endif
|
||||
add_to_funcs(flip_goto, MWHEREIS, "Go To Line", "x", 0, VIEW);
|
||||
add_to_funcs(flip_goto, MGOTOLINE, "Go To Text", "x", 0, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_writeout_void, MMAIN,
|
||||
N_("Write Out"), WITHORSANS(writeout_gist), TOGETHER, NOVIEW);
|
||||
|
||||
@@ -778,6 +793,16 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_replace, MMAIN,
|
||||
N_("Replace"), WITHORSANS(replace_gist), TOGETHER, NOVIEW);
|
||||
|
||||
#ifdef NANO_TINY
|
||||
add_to_funcs(do_search_backward, MHELP,
|
||||
N_("Where Was"), WITHORSANS(wherewas_gist), TOGETHER, VIEW);
|
||||
|
||||
add_to_funcs(do_findprevious, MMAIN|MHELP,
|
||||
N_("Previous"), WITHORSANS(findprev_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_findnext, MMAIN|MHELP,
|
||||
N_("Next"), WITHORSANS(findnext_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(cut_text, MMAIN,
|
||||
N_("Cut"), WITHORSANS(cut_gist), TOGETHER, NOVIEW);
|
||||
|
||||
@@ -796,6 +821,7 @@ void shortcut_init(void)
|
||||
}
|
||||
|
||||
add_to_funcs(report_cursor_position, MMAIN,
|
||||
/* TRANSLATORS: This refers to the position of the cursor. */
|
||||
N_("Location"), WITHORSANS(cursorpos_gist), TOGETHER, VIEW);
|
||||
|
||||
#if defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
|
||||
@@ -827,7 +853,6 @@ void shortcut_init(void)
|
||||
|
||||
add_to_funcs(flip_replace, MWHEREIS,
|
||||
N_("Replace"), WITHORSANS(replace_gist), BLANKAFTER, VIEW);
|
||||
|
||||
add_to_funcs(flip_replace, MREPLACE,
|
||||
N_("No Replace"), WITHORSANS(whereis_gist), BLANKAFTER, VIEW);
|
||||
|
||||
@@ -838,40 +863,49 @@ void shortcut_init(void)
|
||||
N_("Newer"), WITHORSANS(newer_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
add_to_funcs(flip_goto, MWHEREIS,
|
||||
N_("Go To Line"), WITHORSANS(gotoline_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
add_to_funcs(goto_dir, MBROWSER,
|
||||
/* TRANSLATORS: Try to keep the next seven strings at most 10 characters. */
|
||||
N_("Go To Dir"), WITHORSANS(gotodir_gist), TOGETHER, VIEW);
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
add_to_funcs(full_refresh, MBROWSER,
|
||||
N_("Refresh"), WITHORSANS(browserrefresh_gist), BLANKAFTER, VIEW);
|
||||
|
||||
#endif
|
||||
add_to_funcs(do_search_forward, MBROWSER,
|
||||
N_("Where Is"), WITHORSANS(browserwhereis_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_search_backward, MBROWSER,
|
||||
N_("Where Was"), WITHORSANS(browserwherewas_gist), TOGETHER, VIEW);
|
||||
|
||||
add_to_funcs(do_findprevious, MBROWSER,
|
||||
N_("Previous"), WITHORSANS(findprev_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_findnext, MBROWSER,
|
||||
N_("Next"), WITHORSANS(findnext_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
#ifdef NANO_TINY
|
||||
add_to_funcs(to_prev_word, MMAIN,
|
||||
"Prev Word", WITHORSANS(prevword_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(to_next_word, MMAIN,
|
||||
"Next Word", WITHORSANS(nextword_gist), BLANKAFTER, VIEW);
|
||||
#else
|
||||
add_to_funcs(do_find_bracket, MMAIN,
|
||||
N_("To Bracket"), WITHORSANS(bracket_gist), BLANKAFTER, VIEW);
|
||||
|
||||
add_to_funcs(do_search_backward, MMAIN|MHELP,
|
||||
/* TRANSLATORS: This starts a backward search. */
|
||||
N_("Where Was"), WITHORSANS(wherewas_gist), TOGETHER, VIEW);
|
||||
#else
|
||||
add_to_funcs(do_search_backward, MHELP,
|
||||
N_("Where Was"), WITHORSANS(wherewas_gist), TOGETHER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_findprevious, MMAIN|MBROWSER|MHELP,
|
||||
add_to_funcs(do_findprevious, MMAIN|MHELP,
|
||||
/* TRANSLATORS: This refers to searching the preceding occurrence. */
|
||||
N_("Previous"), WITHORSANS(findprev_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_findnext, MMAIN|MBROWSER|MHELP,
|
||||
add_to_funcs(do_findnext, MMAIN|MHELP,
|
||||
N_("Next"), WITHORSANS(findnext_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_left, MMAIN,
|
||||
/* TRANSLATORS: This means move the cursor one character back. */
|
||||
@@ -885,11 +919,13 @@ void shortcut_init(void)
|
||||
N_("Forward"), WITHORSANS(forwardfile_gist), TOGETHER, VIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(to_prev_word, MMAIN,
|
||||
/* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */
|
||||
N_("Prev Word"), WITHORSANS(prevword_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(to_next_word, MMAIN,
|
||||
N_("Next Word"), WITHORSANS(nextword_gist), TOGETHER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_home, MMAIN,
|
||||
N_("Home"), WITHORSANS(home_gist), TOGETHER, VIEW);
|
||||
@@ -913,7 +949,7 @@ void shortcut_init(void)
|
||||
N_("Next Block"), WITHORSANS(nextblock_gist), TOGETHER, VIEW);
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
add_to_funcs(to_para_begin, MMAIN|MGOTOLINE,
|
||||
/* TRANSLATORS: Try to keep these two strings at most 15 characters. */
|
||||
/* TRANSLATORS: Try to keep these two strings at most 16 characters. */
|
||||
N_("Begin of Paragr."), WITHORSANS(parabegin_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(to_para_end, MMAIN|MGOTOLINE,
|
||||
N_("End of Paragraph"), WITHORSANS(paraend_gist), BLANKAFTER, VIEW);
|
||||
@@ -982,8 +1018,10 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_verbatim_input, MMAIN,
|
||||
N_("Verbatim"), WITHORSANS(verbatim_gist), BLANKAFTER, NOVIEW);
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
add_to_funcs(full_refresh, MMAIN,
|
||||
N_("Refresh"), WITHORSANS(refresh_gist), TOGETHER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_suspend_void, MMAIN,
|
||||
N_("Suspend"), WITHORSANS(suspend_gist), BLANKAFTER, VIEW);
|
||||
@@ -1002,6 +1040,7 @@ void shortcut_init(void)
|
||||
add_to_funcs(complete_a_word, MMAIN,
|
||||
N_("Complete"), WITHORSANS(completion_gist), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(record_macro, MMAIN,
|
||||
N_("Record"), WITHORSANS(recordmacro_gist), TOGETHER, VIEW);
|
||||
@@ -1032,10 +1071,12 @@ void shortcut_init(void)
|
||||
#endif
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifdef NANO_TINY
|
||||
add_to_funcs(do_search_backward, MMAIN,
|
||||
N_("Where Was"), WITHORSANS(wherewas_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
add_to_funcs(do_center, MMAIN,
|
||||
N_("Center"), WITHORSANS(center_gist), BLANKAFTER, VIEW);
|
||||
@@ -1070,8 +1111,10 @@ void shortcut_init(void)
|
||||
N_("Formatter"), WITHORSANS(formatter_gist), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
add_to_funcs(flip_goto, MGOTOLINE,
|
||||
N_("Go To Text"), WITHORSANS(whereis_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(dos_format_void, MWRITEFILE,
|
||||
@@ -1108,6 +1151,7 @@ void shortcut_init(void)
|
||||
N_("Suspend"), WITHORSANS(suspend_gist), BLANKAFTER, VIEW);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
/* The file browser is only available when not in restricted mode. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
@@ -1124,6 +1168,7 @@ void shortcut_init(void)
|
||||
N_("First File"), WITHORSANS(firstfile_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(to_last_file, MBROWSER|MWHEREISFILE,
|
||||
N_("Last File"), WITHORSANS(lastfile_gist), BLANKAFTER, VIEW);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(to_prev_word, MBROWSER,
|
||||
N_("Left Column"), WITHORSANS(browserlefthand_gist), TOGETHER, VIEW);
|
||||
@@ -1203,7 +1248,12 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN|MHELP, "^End", CONTROL_END, to_last_line, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "M-W", 0, do_findnext, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER|MHELP, "M-Q", 0, do_findprevious, 0);
|
||||
#ifndef NANO_TINY
|
||||
#ifdef NANO_TINY
|
||||
add_to_sclist(MMAIN, "M-B", 0, to_prev_word, 0);
|
||||
add_to_sclist(MMAIN, "M-D", 0, to_prev_word, 0);
|
||||
add_to_sclist(MMAIN, "M-N", 0, to_next_word, 0);
|
||||
add_to_sclist(MMAIN, "M-F", 0, to_next_word, 0);
|
||||
#else
|
||||
add_to_sclist(MMAIN, "M-]", 0, do_find_bracket, 0);
|
||||
add_to_sclist(MMAIN, "M-A", 0, do_mark, 0);
|
||||
add_to_sclist(MMAIN, "^6", 0, do_mark, 0);
|
||||
@@ -1260,12 +1310,6 @@ void shortcut_init(void)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef NANO_TINY
|
||||
add_to_sclist(MMAIN, "M-B", 0, to_prev_word, 0);
|
||||
add_to_sclist(MMAIN, "M-D", 0, to_prev_word, 0);
|
||||
add_to_sclist(MMAIN, "M-F", 0, to_next_word, 0);
|
||||
add_to_sclist(MMAIN, "M-N", 0, to_next_word, 0);
|
||||
#endif
|
||||
add_to_sclist(MMOST, "M-Space", 0, to_prev_word, 0);
|
||||
add_to_sclist(MMOST, "^Space", 0, to_next_word, 0);
|
||||
add_to_sclist(MMOST, "^A", 0, do_home, 0);
|
||||
@@ -1325,6 +1369,8 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN, "M-T", 0, cut_till_eof, 0);
|
||||
add_to_sclist(MEXECUTE, "^V", 0, cut_till_eof, 0);
|
||||
add_to_sclist(MMAIN, "M-D", 0, do_wordlinechar_count, 0);
|
||||
#else
|
||||
add_to_sclist(MMAIN, "M-H", 0, do_help, 0);
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
add_to_sclist(MMAIN, "M-J", 0, do_full_justify, 0);
|
||||
|
||||
26
src/help.c
26
src/help.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* help.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2000-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2000-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2017 Rishabh Dave *
|
||||
* Copyright (C) 2014-2019 Benno Schulenberg *
|
||||
* *
|
||||
@@ -50,7 +50,7 @@ void help_init(void)
|
||||
char *ptr;
|
||||
|
||||
/* First, set up the initial help text for the current function. */
|
||||
if (currmenu == MWHEREIS || currmenu == MREPLACE || currmenu == MREPLACEWITH) {
|
||||
if (currmenu & (MWHEREIS|MREPLACE|MREPLACEWITH)) {
|
||||
htx[0] = N_("Search Command Help Text\n\n "
|
||||
"Enter the words or characters you would like to "
|
||||
"search for, and then press Enter. If there is a "
|
||||
@@ -240,7 +240,7 @@ void help_init(void)
|
||||
#endif
|
||||
|
||||
/* Allocate memory for the help text. */
|
||||
help_text = charalloc(allocsize + 1);
|
||||
help_text = nmalloc(allocsize + 1);
|
||||
|
||||
/* Now add the text we want. */
|
||||
strcpy(help_text, htx[0]);
|
||||
@@ -457,9 +457,13 @@ void show_help(void)
|
||||
|
||||
/* Show the cursor when we searched and found something. */
|
||||
kbinput = get_kbinput(edit, didfind == 1 || ISSET(SHOW_CURSOR));
|
||||
|
||||
didfind = 0;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
spotlighted = FALSE;
|
||||
hide_cursor = FALSE;
|
||||
|
||||
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) {
|
||||
beep();
|
||||
continue;
|
||||
@@ -475,14 +479,13 @@ void show_help(void)
|
||||
} else if (func == do_up || func == do_scroll_up) {
|
||||
do_scroll_up();
|
||||
} else if (func == do_down || func == do_scroll_down) {
|
||||
if (openfile->edittop->lineno + editwinrows - 1 <
|
||||
openfile->filebot->lineno)
|
||||
if (openfile->edittop->lineno + editwinrows - 1 < openfile->filebot->lineno)
|
||||
do_scroll_down();
|
||||
} else if (func == do_page_up || func == do_page_down ||
|
||||
func == to_first_line || func == to_last_line ||
|
||||
func == do_findprevious || func == do_findnext) {
|
||||
func == to_first_line || func == to_last_line) {
|
||||
func();
|
||||
} else if (func == do_search_forward || func == do_search_backward) {
|
||||
} else if (func == do_search_backward || func == do_search_forward ||
|
||||
func == do_findprevious || func == do_findnext) {
|
||||
func();
|
||||
bottombars(MHELP);
|
||||
#ifdef ENABLE_NANORC
|
||||
@@ -503,7 +506,6 @@ void show_help(void)
|
||||
} else
|
||||
unbound_key(kbinput);
|
||||
|
||||
currmenu = MHELP;
|
||||
edit_refresh();
|
||||
|
||||
location = 0;
|
||||
@@ -550,7 +552,7 @@ void show_help(void)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (oldmenu == MBROWSER || oldmenu == MWHEREISFILE || oldmenu == MGOTODIR)
|
||||
if (oldmenu & (MBROWSER|MWHEREISFILE|MGOTODIR))
|
||||
browser_refresh();
|
||||
else
|
||||
#endif
|
||||
@@ -568,8 +570,8 @@ void do_help(void)
|
||||
#ifdef ENABLE_HELP
|
||||
show_help();
|
||||
#else
|
||||
if (currmenu == MMAIN)
|
||||
say_there_is_no_help();
|
||||
if (currmenu & (MMAIN|MBROWSER))
|
||||
statusbar(_("^W = Ctrl+W M-W = Alt+W"));
|
||||
else
|
||||
beep();
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* history.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2003-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2003-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2017, 2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -299,17 +299,17 @@ void load_history(void)
|
||||
}
|
||||
|
||||
linestruct **history = &search_history;
|
||||
char *line = NULL;
|
||||
size_t buf_len = 0;
|
||||
char *stanza = NULL;
|
||||
size_t dummy = 0;
|
||||
ssize_t read;
|
||||
|
||||
/* Load the three history lists (first search, then replace, then execute)
|
||||
* from oldest entry to newest. Between two lists there is an empty line. */
|
||||
while ((read = getline(&line, &buf_len, histfile)) > 0) {
|
||||
line[--read] = '\0';
|
||||
while ((read = getline(&stanza, &dummy, histfile)) > 0) {
|
||||
stanza[--read] = '\0';
|
||||
if (read > 0) {
|
||||
recode_NUL_to_LF(line, read);
|
||||
update_history(history, line);
|
||||
recode_NUL_to_LF(stanza, read);
|
||||
update_history(history, stanza);
|
||||
} else if (history == &search_history)
|
||||
history = &replace_history;
|
||||
else
|
||||
@@ -320,7 +320,7 @@ void load_history(void)
|
||||
jot_error(N_("Error reading %s: %s"), histname, strerror(errno));
|
||||
|
||||
free(histname);
|
||||
free(line);
|
||||
free(stanza);
|
||||
|
||||
/* Reading in the lists has marked them as changed; undo this side effect. */
|
||||
history_changed = FALSE;
|
||||
@@ -361,7 +361,7 @@ void save_history(void)
|
||||
histfile = fopen(histname, "wb");
|
||||
|
||||
if (histfile == NULL) {
|
||||
jot_error(N_("Error writing %s: %s\n"), histname, strerror(errno));
|
||||
jot_error(N_("Error writing %s: %s"), histname, strerror(errno));
|
||||
free(histname);
|
||||
return;
|
||||
}
|
||||
@@ -371,10 +371,10 @@ void save_history(void)
|
||||
|
||||
if (!write_list(searchtop, histfile) || !write_list(replacetop, histfile) ||
|
||||
!write_list(executetop, histfile))
|
||||
jot_error(N_("Error writing %s: %s\n"), histname, strerror(errno));
|
||||
jot_error(N_("Error writing %s: %s"), histname, strerror(errno));
|
||||
|
||||
if (fclose(histfile) == EOF)
|
||||
jot_error(N_("Error writing %s: %s\n"), histname, strerror(errno));
|
||||
jot_error(N_("Error writing %s: %s"), histname, strerror(errno));
|
||||
|
||||
free(histname);
|
||||
}
|
||||
@@ -393,34 +393,35 @@ void load_poshistory(void)
|
||||
if (histfile == NULL)
|
||||
return;
|
||||
|
||||
char *line = NULL, *lineptr, *xptr;
|
||||
size_t buf_len = 0;
|
||||
ssize_t read, count = 0;
|
||||
struct stat fileinfo;
|
||||
poshiststruct *record_ptr = NULL, *newrecord;
|
||||
char *lineptr, *columnptr;
|
||||
char *stanza = NULL;
|
||||
size_t dummy = 0;
|
||||
|
||||
/* Read and parse each line, and store the extracted data. */
|
||||
while ((read = getline(&line, &buf_len, histfile)) > 5) {
|
||||
while ((read = getline(&stanza, &dummy, histfile)) > 5) {
|
||||
/* Decode NULs as embedded newlines. */
|
||||
recode_NUL_to_LF(line, read);
|
||||
recode_NUL_to_LF(stanza, read);
|
||||
|
||||
/* Find where the x index and line number are in the line. */
|
||||
xptr = revstrstr(line, " ", line + read - 3);
|
||||
if (xptr == NULL)
|
||||
/* Find the spaces before column number and line number. */
|
||||
columnptr = revstrstr(stanza, " ", stanza + read - 3);
|
||||
if (columnptr == NULL)
|
||||
continue;
|
||||
lineptr = revstrstr(line, " ", xptr - 2);
|
||||
lineptr = revstrstr(stanza, " ", columnptr - 2);
|
||||
if (lineptr == NULL)
|
||||
continue;
|
||||
|
||||
/* Now separate the three elements of the line. */
|
||||
*(xptr++) = '\0';
|
||||
*(columnptr++) = '\0';
|
||||
*(lineptr++) = '\0';
|
||||
|
||||
/* Create a new position record. */
|
||||
newrecord = (poshiststruct *)nmalloc(sizeof(poshiststruct));
|
||||
newrecord->filename = copy_of(line);
|
||||
newrecord->lineno = atoi(lineptr);
|
||||
newrecord->xno = atoi(xptr);
|
||||
newrecord = nmalloc(sizeof(poshiststruct));
|
||||
newrecord->filename = copy_of(stanza);
|
||||
newrecord->linenumber = atoi(lineptr);
|
||||
newrecord->columnnumber = atoi(columnptr);
|
||||
newrecord->next = NULL;
|
||||
|
||||
/* Add the record to the list. */
|
||||
@@ -445,7 +446,7 @@ void load_poshistory(void)
|
||||
if (fclose(histfile) == EOF)
|
||||
jot_error(N_("Error reading %s: %s"), poshistname, strerror(errno));
|
||||
|
||||
free(line);
|
||||
free(stanza);
|
||||
|
||||
if (stat(poshistname, &fileinfo) == 0)
|
||||
latest_timestamp = fileinfo.st_mtime;
|
||||
@@ -459,7 +460,7 @@ void save_poshistory(void)
|
||||
FILE *histfile = fopen(poshistname, "wb");
|
||||
|
||||
if (histfile == NULL) {
|
||||
jot_error(N_("Error writing %s: %s\n"), poshistname, strerror(errno));
|
||||
jot_error(N_("Error writing %s: %s"), poshistname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -472,9 +473,9 @@ void save_poshistory(void)
|
||||
|
||||
/* 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);
|
||||
path_and_place = nmalloc(strlen(posptr->filename) + 44);
|
||||
sprintf(path_and_place, "%s %zd %zd\n",
|
||||
posptr->filename, posptr->lineno, posptr->xno);
|
||||
posptr->filename, posptr->linenumber, posptr->columnnumber);
|
||||
length = strlen(path_and_place);
|
||||
|
||||
/* Encode newlines in filenames as NULs. */
|
||||
@@ -483,13 +484,13 @@ void save_poshistory(void)
|
||||
path_and_place[length - 1] = '\n';
|
||||
|
||||
if (fwrite(path_and_place, sizeof(char), length, histfile) < length)
|
||||
jot_error(N_("Error writing %s: %s\n"), poshistname, strerror(errno));
|
||||
jot_error(N_("Error writing %s: %s"), poshistname, strerror(errno));
|
||||
|
||||
free(path_and_place);
|
||||
}
|
||||
|
||||
if (fclose(histfile) == EOF)
|
||||
jot_error(N_("Error writing %s: %s\n"), poshistname, strerror(errno));
|
||||
jot_error(N_("Error writing %s: %s"), poshistname, strerror(errno));
|
||||
|
||||
if (stat(poshistname, &fileinfo) == 0)
|
||||
latest_timestamp = fileinfo.st_mtime;
|
||||
@@ -556,7 +557,7 @@ void update_poshistory(void)
|
||||
/* 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 = nmalloc(sizeof(poshiststruct));
|
||||
theone->filename = copy_of(fullpath);
|
||||
if (position_history == NULL)
|
||||
position_history = theone;
|
||||
@@ -573,8 +574,8 @@ void update_poshistory(void)
|
||||
}
|
||||
|
||||
/* Store the last cursor position. */
|
||||
theone->lineno = openfile->current->lineno;
|
||||
theone->xno = xplustabs() + 1;
|
||||
theone->linenumber = openfile->current->lineno;
|
||||
theone->columnnumber = xplustabs() + 1;
|
||||
theone->next = NULL;
|
||||
|
||||
free(fullpath);
|
||||
@@ -604,8 +605,8 @@ bool has_old_position(const char *file, ssize_t *line, ssize_t *column)
|
||||
if (posptr == NULL)
|
||||
return FALSE;
|
||||
|
||||
*line = posptr->lineno;
|
||||
*column = posptr->xno;
|
||||
*line = posptr->linenumber;
|
||||
*column = posptr->columnnumber;
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* ENABLE_HISTORIES */
|
||||
|
||||
39
src/move.c
39
src/move.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* move.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2018 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -115,6 +115,7 @@ void do_page_up(void)
|
||||
int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
|
||||
size_t leftedge, target_column;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* 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(JUMPY_SCROLLING)) {
|
||||
@@ -123,6 +124,7 @@ void do_page_up(void)
|
||||
openfile->current_y = 0;
|
||||
target_column = 0;
|
||||
} else
|
||||
#endif
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
|
||||
/* Move up the required number of lines or chunks. If we can't, we're
|
||||
@@ -145,6 +147,7 @@ void do_page_down(void)
|
||||
int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
|
||||
size_t leftedge, target_column;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* 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(JUMPY_SCROLLING)) {
|
||||
@@ -153,6 +156,7 @@ void do_page_down(void)
|
||||
openfile->current_y = 0;
|
||||
target_column = 0;
|
||||
} else
|
||||
#endif
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
|
||||
/* Move down the required number of lines or chunks. If we can't, we're
|
||||
@@ -287,6 +291,10 @@ void do_prev_word(bool allow_punct)
|
||||
/* If at the head of a line now, this surely is a word start. */
|
||||
if (openfile->current_x == 0)
|
||||
break;
|
||||
#ifdef ENABLE_UTF8
|
||||
} else if (is_zerowidth(openfile->current->data + openfile->current_x)) {
|
||||
; /* skip */
|
||||
#endif
|
||||
} else if (seen_a_word) {
|
||||
/* This is space now: we've overshot the start of the word. */
|
||||
step_forward = TRUE;
|
||||
@@ -335,11 +343,20 @@ bool do_next_word(bool after_ends, bool allow_punct)
|
||||
if (is_word_char(openfile->current->data + openfile->current_x,
|
||||
allow_punct))
|
||||
seen_word = TRUE;
|
||||
#ifdef ENABLE_UTF8
|
||||
else if (is_zerowidth(openfile->current->data + openfile->current_x))
|
||||
; /* skip */
|
||||
#endif
|
||||
else if (seen_word)
|
||||
break;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (is_zerowidth(openfile->current->data + openfile->current_x))
|
||||
; /* skip */
|
||||
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_char(openfile->current->data + openfile->current_x,
|
||||
@@ -577,10 +594,16 @@ void do_left(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
if (openfile->current_x > 0)
|
||||
if (openfile->current_x > 0) {
|
||||
openfile->current_x = step_left(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->filetop) {
|
||||
#ifdef ENABLE_UTF8
|
||||
while (openfile->current_x > 0 &&
|
||||
is_zerowidth(openfile->current->data + openfile->current_x))
|
||||
openfile->current_x = step_left(openfile->current->data,
|
||||
openfile->current_x);
|
||||
#endif
|
||||
} else if (openfile->current != openfile->filetop) {
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
}
|
||||
@@ -593,10 +616,16 @@ void do_right(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
if (openfile->current->data[openfile->current_x] != '\0')
|
||||
if (openfile->current->data[openfile->current_x] != '\0') {
|
||||
openfile->current_x = step_right(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
#ifdef ENABLE_UTF8
|
||||
while (openfile->current->data[openfile->current_x] != '\0' &&
|
||||
is_zerowidth(openfile->current->data + openfile->current_x))
|
||||
openfile->current_x = step_right(openfile->current->data,
|
||||
openfile->current_x);
|
||||
#endif
|
||||
} else if (openfile->current != openfile->filebot) {
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
|
||||
330
src/nano.c
330
src/nano.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* nano.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -197,28 +197,20 @@ void renumber_from(linestruct *line)
|
||||
/* Display a warning about a key disabled in view mode. */
|
||||
void print_view_warning(void)
|
||||
{
|
||||
statusbar(_("Key is invalid in view mode"));
|
||||
statusline(AHEM, _("Key is invalid in view mode"));
|
||||
}
|
||||
|
||||
/* When in restricted mode, show a warning and return TRUE. */
|
||||
bool in_restricted_mode(void)
|
||||
{
|
||||
if (ISSET(RESTRICTED)) {
|
||||
statusbar(_("This function is disabled in restricted mode"));
|
||||
statusline(AHEM, _("This function is disabled in restricted mode"));
|
||||
beep();
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_HELP
|
||||
/* Indicate that help texts are unavailable. */
|
||||
void say_there_is_no_help(void)
|
||||
{
|
||||
statusbar(_("Help is not available"));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure the cursor is visible, then exit from curses mode, disable
|
||||
* bracketed-paste mode, and restore the original terminal settings. */
|
||||
void restore_terminal(void)
|
||||
@@ -229,7 +221,7 @@ void restore_terminal(void)
|
||||
printf("\x1B[?2004l");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &original_state);
|
||||
}
|
||||
|
||||
/* Exit normally: restore terminal state and report any startup errors. */
|
||||
@@ -403,22 +395,28 @@ void window_init(void)
|
||||
delwin(bottomwin);
|
||||
}
|
||||
|
||||
topwin = NULL;
|
||||
|
||||
/* If the terminal is very flat, don't set up a title bar. */
|
||||
if (LINES < 3) {
|
||||
topwin = NULL;
|
||||
editwinrows = 1;
|
||||
/* Set up two subwindows. If the terminal is just one line,
|
||||
* edit window and status-bar window will cover each other. */
|
||||
edit = newwin(1, COLS, 0, 0);
|
||||
bottomwin = newwin(1, COLS, LINES - 1, 0);
|
||||
} else {
|
||||
int toprows = (!ISSET(EMPTY_LINE) ? 1 : (LINES < 6) ? 1 : 2);
|
||||
int bottomrows = (ISSET(NO_HELP) ? 1 : (LINES < 5) ? 1 : 3);
|
||||
int toprows = ((ISSET(EMPTY_LINE) && LINES > 5) ? 2 : 1);
|
||||
int bottomrows = ((ISSET(NO_HELP) || LINES < 5) ? 1 : 3);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(MINIBAR))
|
||||
toprows = 0;
|
||||
#endif
|
||||
editwinrows = LINES - toprows - bottomrows;
|
||||
|
||||
/* Set up the normal three subwindows. */
|
||||
topwin = newwin(toprows, COLS, 0, 0);
|
||||
if (toprows > 0)
|
||||
topwin = newwin(toprows, COLS, 0, 0);
|
||||
edit = newwin(editwinrows, COLS, toprows, 0);
|
||||
bottomwin = newwin(bottomrows, COLS, toprows + editwinrows, 0);
|
||||
}
|
||||
@@ -487,6 +485,7 @@ void print_opt(const char *shortflag, const char *longflag, const char *desc)
|
||||
void usage(void)
|
||||
{
|
||||
printf(_("Usage: nano [OPTIONS] [[+LINE[,COLUMN]] FILE]...\n\n"));
|
||||
#ifndef NANO_TINY
|
||||
/* TRANSLATORS: The next two strings are part of the --help output.
|
||||
* It's best to keep its lines within 80 characters. */
|
||||
printf(_("To place the cursor on a specific line of a file, put the line number with\n"
|
||||
@@ -494,7 +493,6 @@ void usage(void)
|
||||
printf(_("When a filename is '-', nano reads data from standard input.\n\n"));
|
||||
/* TRANSLATORS: The next three are column headers of the --help output. */
|
||||
print_opt(_("Option"), _("Long option"), N_("Meaning"));
|
||||
#ifndef NANO_TINY
|
||||
/* TRANSLATORS: The next forty or so strings are option descriptions
|
||||
* for the --help output. Try to keep them at most 40 characters. */
|
||||
print_opt("-A", "--smarthome", N_("Enable smart home key"));
|
||||
@@ -559,9 +557,9 @@ void usage(void)
|
||||
print_opt("-R", "--restricted", N_("Restrict access to the filesystem"));
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-S", "--softwrap", N_("Display overlong lines on multiple rows"));
|
||||
#endif
|
||||
print_opt(_("-T <number>"), _("--tabsize=<number>"),
|
||||
N_("Make a tab this number of columns wide"));
|
||||
#endif
|
||||
print_opt("-U", "--quickblank", N_("Wipe status bar upon next keystroke"));
|
||||
print_opt("-V", "--version", N_("Print version information and exit"));
|
||||
#ifndef NANO_TINY
|
||||
@@ -585,7 +583,9 @@ void usage(void)
|
||||
print_opt("-c", "--constantshow", N_("Constantly show cursor position"));
|
||||
print_opt("-d", "--rebinddelete",
|
||||
N_("Fix Backspace/Delete confusion problem"));
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-e", "--emptyline", N_("Keep the line below the title bar empty"));
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
print_opt(_("-f <file>"), _("--rcfile=<file>"),
|
||||
N_("Use only this file for configuring nano"));
|
||||
@@ -596,9 +596,7 @@ void usage(void)
|
||||
print_opt("-h", "--help", N_("Show this help text and exit"));
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-i", "--autoindent", N_("Automatically indent new lines"));
|
||||
#endif
|
||||
print_opt("-j", "--jumpyscrolling", N_("Scroll per half-screen, not per line"));
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-k", "--cutfromcursor", N_("Cut from cursor to end of line"));
|
||||
#endif
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
@@ -607,7 +605,9 @@ void usage(void)
|
||||
#ifdef ENABLE_MOUSE
|
||||
print_opt("-m", "--mouse", N_("Enable the use of the mouse"));
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-n", "--noread", N_("Do not read the file (only write it)"));
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
print_opt(_("-o <dir>"), _("--operatingdir=<dir>"),
|
||||
N_("Set operating directory"));
|
||||
@@ -639,11 +639,17 @@ void usage(void)
|
||||
#endif
|
||||
if (!ISSET(RESTRICTED))
|
||||
print_opt("-z", "--suspendable", N_("Enable suspension"));
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-%", "--stateflags", N_("Show some states on the title bar"));
|
||||
print_opt("-_", "--minibar", N_("Show a feedback bar at the bottom"));
|
||||
#endif
|
||||
#ifdef HAVE_LIBMAGIC
|
||||
print_opt("-!", "--magic", N_("Also try magic to determine syntax"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Display the current version of nano, the date and time it was
|
||||
* compiled, contact information for it, and the configuration options
|
||||
* it was compiled with. */
|
||||
/* Display the version number of this nano, a copyright notice, some contact
|
||||
* information, and the configuration options this nano was compiled with. */
|
||||
void version(void)
|
||||
{
|
||||
#ifdef REVISION
|
||||
@@ -651,10 +657,11 @@ void version(void)
|
||||
#else
|
||||
printf(_(" GNU nano, version %s\n"), VERSION);
|
||||
#endif
|
||||
printf(" (C) 1999-2011, 2013-2020 Free Software Foundation, Inc.\n");
|
||||
printf(_(" (C) 2014-%s the contributors to nano\n"), "2020");
|
||||
printf(_(" Email: nano@nano-editor.org Web: https://nano-editor.org/"));
|
||||
printf(_("\n Compiled options:"));
|
||||
#ifndef NANO_TINY
|
||||
printf(" (C) 1999-2011, 2013-2021 Free Software Foundation, Inc.\n");
|
||||
printf(_(" (C) 2014-%s the contributors to nano\n"), "2021");
|
||||
#endif
|
||||
printf(_(" Compiled options:"));
|
||||
|
||||
#ifdef NANO_TINY
|
||||
printf(" --enable-tiny");
|
||||
@@ -767,15 +774,12 @@ void version(void)
|
||||
printf(" --enable-utf8");
|
||||
#else
|
||||
printf(" --disable-utf8");
|
||||
#endif
|
||||
#ifdef USE_SLANG
|
||||
printf(" --with-slang");
|
||||
#endif
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Register that Ctrl+C was pressed during some system call. */
|
||||
RETSIGTYPE make_a_note(int signal)
|
||||
void make_a_note(int signal)
|
||||
{
|
||||
control_C_was_pressed = TRUE;
|
||||
}
|
||||
@@ -799,20 +803,20 @@ void restore_handler_for_Ctrl_C(void)
|
||||
disable_kb_interrupt();
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Reconnect standard input to the tty, and store its state. */
|
||||
void reconnect_and_store_state(void)
|
||||
{
|
||||
int thetty = open("/dev/tty", O_RDONLY);
|
||||
|
||||
if (thetty < 1)
|
||||
if (thetty < 0 || dup2(thetty, STDIN_FILENO) < 0)
|
||||
die(_("Could not reconnect stdin to keyboard\n"));
|
||||
|
||||
dup2(thetty, STANDARD_INPUT);
|
||||
close(thetty);
|
||||
|
||||
/* If input was not cut short, store the current state of the terminal. */
|
||||
if (!control_C_was_pressed)
|
||||
tcgetattr(0, &original_state);
|
||||
tcgetattr(STDIN_FILENO, &original_state);
|
||||
}
|
||||
|
||||
/* Read whatever comes from standard input into a new buffer. */
|
||||
@@ -823,7 +827,7 @@ bool scoop_stdin(void)
|
||||
restore_terminal();
|
||||
|
||||
/* When input comes from a terminal, show a helpful message. */
|
||||
if (isatty(STANDARD_INPUT))
|
||||
if (isatty(STDIN_FILENO))
|
||||
fprintf(stderr, _("Reading data from keyboard; "
|
||||
"type ^D or ^D^D to finish.\n"));
|
||||
|
||||
@@ -856,6 +860,7 @@ bool scoop_stdin(void)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Register half a dozen signal handlers. */
|
||||
void signal_init(void)
|
||||
@@ -882,25 +887,17 @@ void signal_init(void)
|
||||
sigaction(SIGWINCH, &deed, NULL);
|
||||
#endif
|
||||
|
||||
if (ISSET(SUSPENDABLE)) {
|
||||
/* Block all other signals in the suspend and continue handlers.
|
||||
* If we don't do this, other stuff interrupts them! */
|
||||
sigfillset(&deed.sa_mask);
|
||||
/* In the suspend and continue handlers, block all other signals.
|
||||
* If we don't do this, other stuff interrupts them! */
|
||||
sigfillset(&deed.sa_mask);
|
||||
#ifdef SIGTSTP
|
||||
/* Trap a normal suspend (^Z) so we can handle it ourselves. */
|
||||
deed.sa_handler = do_suspend;
|
||||
sigaction(SIGTSTP, &deed, NULL);
|
||||
deed.sa_handler = do_suspend;
|
||||
sigaction(SIGTSTP, &deed, NULL);
|
||||
#endif
|
||||
#ifdef SIGCONT
|
||||
deed.sa_handler = do_continue;
|
||||
sigaction(SIGCONT, &deed, NULL);
|
||||
deed.sa_handler = do_continue;
|
||||
sigaction(SIGCONT, &deed, NULL);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef SIGTSTP
|
||||
deed.sa_handler = SIG_IGN;
|
||||
sigaction(SIGTSTP, &deed, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(NANO_TINY) && !defined(DEBUG)
|
||||
if (getenv("NANO_NOCATCH") == NULL) {
|
||||
@@ -916,21 +913,21 @@ void signal_init(void)
|
||||
}
|
||||
|
||||
/* Handler for SIGHUP (hangup) and SIGTERM (terminate). */
|
||||
RETSIGTYPE handle_hupterm(int signal)
|
||||
void handle_hupterm(int signal)
|
||||
{
|
||||
die(_("Received SIGHUP or SIGTERM\n"));
|
||||
}
|
||||
|
||||
#if !defined(NANO_TINY) && !defined(DEBUG)
|
||||
/* Handler for SIGSEGV (segfault) and SIGABRT (abort). */
|
||||
RETSIGTYPE handle_crash(int signal)
|
||||
void handle_crash(int signal)
|
||||
{
|
||||
die(_("Sorry! Nano crashed! Code: %d. Please report a bug.\n"), signal);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handler for SIGTSTP (suspend). */
|
||||
RETSIGTYPE do_suspend(int signal)
|
||||
void do_suspend(int signal)
|
||||
{
|
||||
#ifdef ENABLE_MOUSE
|
||||
disable_mouse_support();
|
||||
@@ -955,18 +952,17 @@ RETSIGTYPE do_suspend(int signal)
|
||||
/* Put nano to sleep (if suspension is enabled). */
|
||||
void do_suspend_void(void)
|
||||
{
|
||||
if (ISSET(SUSPENDABLE))
|
||||
do_suspend(0);
|
||||
else {
|
||||
statusbar(_("Suspension is not enabled"));
|
||||
if (!ISSET(SUSPENDABLE)) {
|
||||
statusline(AHEM, _("Suspension is not enabled"));
|
||||
beep();
|
||||
}
|
||||
} else
|
||||
do_suspend(0);
|
||||
|
||||
ran_a_tool = TRUE;
|
||||
}
|
||||
|
||||
/* Handler for SIGCONT (continue after suspend). */
|
||||
RETSIGTYPE do_continue(int signal)
|
||||
void do_continue(int signal)
|
||||
{
|
||||
#ifdef ENABLE_MOUSE
|
||||
if (ISSET(USE_MOUSE))
|
||||
@@ -980,7 +976,8 @@ RETSIGTYPE do_continue(int signal)
|
||||
/* Put the terminal in the desired state again. */
|
||||
terminal_init();
|
||||
#endif
|
||||
/* Tickle the input routine so it will update the screen. */
|
||||
|
||||
/* Insert a fake keystroke, to neutralize a key-eating issue. */
|
||||
ungetch(KEY_FLUSH);
|
||||
}
|
||||
|
||||
@@ -1003,7 +1000,7 @@ void block_sigwinch(bool blockit)
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Handler for SIGWINCH (window size change). */
|
||||
RETSIGTYPE handle_sigwinch(int signal)
|
||||
void handle_sigwinch(int signal)
|
||||
{
|
||||
/* Let the input routine know that a SIGWINCH has occurred. */
|
||||
the_window_resized = TRUE;
|
||||
@@ -1068,8 +1065,6 @@ void regenerate_screen(void)
|
||||
/* Handle the global toggle specified in flag. */
|
||||
void do_toggle(int flag)
|
||||
{
|
||||
bool enabled;
|
||||
|
||||
if (flag == SUSPENDABLE && in_restricted_mode())
|
||||
return;
|
||||
|
||||
@@ -1086,9 +1081,6 @@ void do_toggle(int flag)
|
||||
mouse_init();
|
||||
break;
|
||||
#endif
|
||||
case SUSPENDABLE:
|
||||
signal_init();
|
||||
break;
|
||||
case SOFTWRAP:
|
||||
if (ISSET(SOFTWRAP))
|
||||
compute_the_extra_rows_per_line_from(openfile->filetop);
|
||||
@@ -1108,13 +1100,27 @@ void do_toggle(int flag)
|
||||
#endif
|
||||
}
|
||||
|
||||
enabled = ISSET(flag);
|
||||
if (!ISSET(MINIBAR) && ISSET(STATEFLAGS))
|
||||
if (flag == AUTOINDENT || flag == BREAK_LONG_LINES || flag == SOFTWRAP)
|
||||
titlebar(NULL);
|
||||
|
||||
if (flag == NO_HELP || flag == NO_SYNTAX)
|
||||
enabled = !enabled;
|
||||
if (ISSET(MINIBAR) && (flag == NO_HELP || flag == LINE_NUMBERS ))
|
||||
return;
|
||||
|
||||
statusline(HUSH, "%s %s", _(flagtostr(flag)),
|
||||
enabled ? _("enabled") : _("disabled"));
|
||||
if (flag == CONSTANT_SHOW)
|
||||
wipe_statusbar();
|
||||
else if (!ISSET(MINIBAR) || !ISSET(STATEFLAGS) || flag == SMART_HOME ||
|
||||
flag == NO_SYNTAX || flag == WHITESPACE_DISPLAY ||
|
||||
flag == CUT_FROM_CURSOR || flag == TABS_TO_SPACES ||
|
||||
flag == USE_MOUSE || flag == SUSPENDABLE) {
|
||||
bool enabled = ISSET(flag);
|
||||
|
||||
if (flag == NO_HELP || flag == NO_SYNTAX)
|
||||
enabled = !enabled;
|
||||
|
||||
statusline(REMARK, "%s %s", _(flagtostr(flag)),
|
||||
enabled ? _("enabled") : _("disabled"));
|
||||
}
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
@@ -1189,36 +1195,15 @@ void enable_flow_control(void)
|
||||
* control characters. */
|
||||
void terminal_init(void)
|
||||
{
|
||||
#ifdef USE_SLANG
|
||||
/* Slang curses emulation brain damage, part 2: Slang doesn't
|
||||
* implement raw(), nonl(), or noecho() properly, so there's no way
|
||||
* to properly reinitialize the terminal using them. We have to
|
||||
* disable the special control keys and interpretation of the flow
|
||||
* control characters using termios, save the terminal state after
|
||||
* the first call, and restore it on subsequent calls. */
|
||||
static struct termios desired_state;
|
||||
static bool have_new_state = FALSE;
|
||||
raw();
|
||||
nonl();
|
||||
noecho();
|
||||
|
||||
if (!have_new_state) {
|
||||
#endif
|
||||
raw();
|
||||
nonl();
|
||||
noecho();
|
||||
disable_extended_io();
|
||||
disable_extended_io();
|
||||
|
||||
if (ISSET(PRESERVE))
|
||||
enable_flow_control();
|
||||
#ifdef USE_SLANG
|
||||
else
|
||||
disable_flow_control();
|
||||
if (ISSET(PRESERVE))
|
||||
enable_flow_control();
|
||||
|
||||
tcgetattr(0, &desired_state);
|
||||
have_new_state = TRUE;
|
||||
} else
|
||||
tcsetattr(0, TCSANOW, &desired_state);
|
||||
|
||||
SLang_init_tty(-1, 0, 0);
|
||||
#endif
|
||||
disable_kb_interrupt();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -1255,6 +1240,8 @@ void confirm_margin(void)
|
||||
needed_margin = 0;
|
||||
|
||||
if (needed_margin != margin) {
|
||||
bool keep_focus = (margin > 0) && focusing;
|
||||
|
||||
margin = needed_margin;
|
||||
editwincols = COLS - margin - thebar;
|
||||
|
||||
@@ -1263,6 +1250,7 @@ void confirm_margin(void)
|
||||
* and ensure a proper starting column for the first screen row. */
|
||||
compute_the_extra_rows_per_line_from(openfile->filetop);
|
||||
ensure_firstcolumn_is_aligned();
|
||||
focusing = keep_focus;
|
||||
#endif
|
||||
/* The margin has changed -- schedule a full refresh. */
|
||||
refresh_needed = TRUE;
|
||||
@@ -1276,29 +1264,30 @@ void unbound_key(int code)
|
||||
if (code == FOREIGN_SEQUENCE)
|
||||
/* TRANSLATORS: This refers to a sequence of escape codes
|
||||
* (from the keyboard) that nano does not recognize. */
|
||||
statusline(ALERT, _("Unknown sequence"));
|
||||
statusline(AHEM, _("Unknown sequence"));
|
||||
else if (code > 0x7F)
|
||||
statusline(ALERT, _("Unbound key"));
|
||||
statusline(AHEM, _("Unbound key"));
|
||||
else if (meta_key) {
|
||||
#ifndef NANO_TINY
|
||||
if (code < 0x20)
|
||||
statusline(ALERT, _("Unbindable key: M-^%c"), code + 0x40);
|
||||
statusline(AHEM, _("Unbindable key: M-^%c"), code + 0x40);
|
||||
else
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
if (shifted_metas && 'A' <= code && code <= 'Z')
|
||||
statusline(ALERT, _("Unbound key: Sh-M-%c"), code);
|
||||
statusline(AHEM, _("Unbound key: Sh-M-%c"), code);
|
||||
else
|
||||
#endif
|
||||
statusline(ALERT, _("Unbound key: M-%c"), toupper(code));
|
||||
statusline(AHEM, _("Unbound key: M-%c"), toupper(code));
|
||||
} else if (code == ESC_CODE)
|
||||
statusline(ALERT, _("Unbindable key: ^["));
|
||||
statusline(AHEM, _("Unbindable key: ^["));
|
||||
else if (code < 0x20)
|
||||
statusline(ALERT, _("Unbound key: ^%c"), code + 0x40);
|
||||
statusline(AHEM, _("Unbound key: ^%c"), code + 0x40);
|
||||
#if defined(ENABLE_BROWSER) || defined (ENABLE_HELP)
|
||||
else
|
||||
statusline(ALERT, _("Unbound key: %c"), code);
|
||||
statusline(AHEM, _("Unbound key: %c"), code);
|
||||
#endif
|
||||
set_blankdelay_to_one();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
@@ -1340,9 +1329,11 @@ int do_mouse(void)
|
||||
#ifndef NANO_TINY
|
||||
/* Clicking where the cursor is toggles the mark, as does clicking
|
||||
* beyond the line length with the cursor at the end of the line. */
|
||||
if (sameline && openfile->current_x == current_x_save)
|
||||
if (sameline && openfile->current_x == current_x_save) {
|
||||
do_mark();
|
||||
else
|
||||
if (ISSET(STATEFLAGS))
|
||||
titlebar(NULL);
|
||||
} else
|
||||
#endif
|
||||
/* The cursor moved; clean the cutbuffer on the next cut. */
|
||||
keep_cutbuffer = FALSE;
|
||||
@@ -1403,7 +1394,7 @@ void suck_up_input_and_paste_it(void)
|
||||
index = 0;
|
||||
} else if ((0x20 <= input && input <= 0xFF && input != DEL_CODE) ||
|
||||
input == '\t') {
|
||||
line->data = charealloc(line->data, index + 2);
|
||||
line->data = nrealloc(line->data, index + 2);
|
||||
line->data[index++] = (char)input;
|
||||
line->data[index] = '\0';
|
||||
} else if (input != BRACKETED_PASTE_MARKER)
|
||||
@@ -1447,7 +1438,7 @@ void inject(char *burst, size_t count)
|
||||
#endif
|
||||
|
||||
/* Make room for the new bytes and copy them into the line. */
|
||||
thisline->data = charealloc(thisline->data, datalen + count + 1);
|
||||
thisline->data = nrealloc(thisline->data, datalen + count + 1);
|
||||
memmove(thisline->data + openfile->current_x + count,
|
||||
thisline->data + openfile->current_x,
|
||||
datalen - openfile->current_x + 1);
|
||||
@@ -1522,11 +1513,18 @@ void process_a_keystroke(void)
|
||||
/* The input buffer for actual characters. */
|
||||
static size_t depth = 0;
|
||||
/* The length of the input buffer. */
|
||||
#ifndef NANO_TINY
|
||||
linestruct *was_mark = openfile->mark;
|
||||
#endif
|
||||
static bool give_a_hint = TRUE;
|
||||
const keystruct *shortcut;
|
||||
|
||||
/* Read in a keystroke, and show the cursor while waiting. */
|
||||
input = get_kbinput(edit, VISIBLE);
|
||||
|
||||
lastmessage = VACUUM;
|
||||
hide_cursor = FALSE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (input == KEY_WINCH)
|
||||
return;
|
||||
@@ -1553,13 +1551,13 @@ void process_a_keystroke(void)
|
||||
print_view_warning();
|
||||
else {
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->mark && openfile->kind_of_mark == SOFTMARK) {
|
||||
if (openfile->mark && openfile->softmark) {
|
||||
openfile->mark = NULL;
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
#endif
|
||||
/* Store the byte, and leave room for a terminating zero. */
|
||||
puddle = charealloc(puddle, depth + 2);
|
||||
puddle = nrealloc(puddle, depth + 2);
|
||||
puddle[depth++] = (char)input;
|
||||
}
|
||||
}
|
||||
@@ -1587,6 +1585,13 @@ void process_a_keystroke(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (input == '\b' && give_a_hint && openfile->current_x == 0 &&
|
||||
openfile->current == openfile->filetop && !ISSET(NO_HELP)) {
|
||||
statusbar(_("^W = Ctrl+W M-W = Alt+W"));
|
||||
give_a_hint = FALSE;
|
||||
} else if (meta_key)
|
||||
give_a_hint = FALSE;
|
||||
|
||||
/* When not cutting or copying text, drop the cutbuffer the next time. */
|
||||
if (shortcut->func != cut_text) {
|
||||
#ifndef NANO_TINY
|
||||
@@ -1620,7 +1625,7 @@ void process_a_keystroke(void)
|
||||
if (shift_held && !openfile->mark) {
|
||||
openfile->mark = openfile->current;
|
||||
openfile->mark_x = openfile->current_x;
|
||||
openfile->kind_of_mark = SOFTMARK;
|
||||
openfile->softmark = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1632,7 +1637,7 @@ void process_a_keystroke(void)
|
||||
* discard a soft mark. And when the marked region covers a
|
||||
* different set of lines, reset the "last line too" flag. */
|
||||
if (openfile->mark) {
|
||||
if (!shift_held && openfile->kind_of_mark == SOFTMARK &&
|
||||
if (!shift_held && openfile->softmark &&
|
||||
(openfile->current != was_current ||
|
||||
openfile->current_x != was_x ||
|
||||
wanted_to_move(shortcut->func))) {
|
||||
@@ -1653,6 +1658,9 @@ void process_a_keystroke(void)
|
||||
#ifndef NANO_TINY
|
||||
if (bracketed_paste)
|
||||
suck_up_input_and_paste_it();
|
||||
|
||||
if (ISSET(STATEFLAGS) && openfile->mark != was_mark)
|
||||
titlebar(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1691,7 +1699,6 @@ int main(int argc, char **argv)
|
||||
{"quotestr", 1, NULL, 'Q'},
|
||||
#endif
|
||||
{"restricted", 0, NULL, 'R'},
|
||||
{"tabsize", 1, NULL, 'T'},
|
||||
{"quickblank", 0, NULL, 'U'},
|
||||
{"version", 0, NULL, 'V'},
|
||||
#ifdef ENABLE_COLOR
|
||||
@@ -1702,7 +1709,6 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
{"constantshow", 0, NULL, 'c'},
|
||||
{"rebinddelete", 0, NULL, 'd'},
|
||||
{"emptyline", 0, NULL, 'e'},
|
||||
#ifdef ENABLE_NANORC
|
||||
{"rcfile", 1, NULL, 'f'},
|
||||
#endif
|
||||
@@ -1710,14 +1716,12 @@ int main(int argc, char **argv)
|
||||
{"showcursor", 0, NULL, 'g'},
|
||||
#endif
|
||||
{"help", 0, NULL, 'h'},
|
||||
{"jumpyscrolling", 0, NULL, 'j'},
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
{"linenumbers", 0, NULL, 'l'},
|
||||
#endif
|
||||
#ifdef ENABLE_MOUSE
|
||||
{"mouse", 0, NULL, 'm'},
|
||||
#endif
|
||||
{"noread", 0, NULL, 'n'},
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
{"operatingdir", 1, NULL, 'o'},
|
||||
#endif
|
||||
@@ -1749,15 +1753,24 @@ int main(int argc, char **argv)
|
||||
{"bookstyle", 0, NULL, 'O'},
|
||||
{"positionlog", 0, NULL, 'P'},
|
||||
{"softwrap", 0, NULL, 'S'},
|
||||
{"tabsize", 1, NULL, 'T'},
|
||||
{"wordbounds", 0, NULL, 'W'},
|
||||
{"wordchars", 1, NULL, 'X'},
|
||||
{"zap", 0, NULL, 'Z'},
|
||||
{"atblanks", 0, NULL, 'a'},
|
||||
{"emptyline", 0, NULL, 'e'},
|
||||
{"autoindent", 0, NULL, 'i'},
|
||||
{"jumpyscrolling", 0, NULL, 'j'},
|
||||
{"cutfromcursor", 0, NULL, 'k'},
|
||||
{"noread", 0, NULL, 'n'},
|
||||
{"indicator", 0, NULL, 'q'},
|
||||
{"unix", 0, NULL, 'u'},
|
||||
{"afterends", 0, NULL, 'y'},
|
||||
{"stateflags", 0, NULL, '%'},
|
||||
{"minibar", 0, NULL, '_'},
|
||||
#endif
|
||||
#ifdef HAVE_LIBMAGIC
|
||||
{"magic", 0, NULL, '!'},
|
||||
#endif
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
@@ -1766,27 +1779,22 @@ int main(int argc, char **argv)
|
||||
struct vt_stat dummy;
|
||||
|
||||
/* Check whether we're running on a Linux console. */
|
||||
on_a_vt = (ioctl(1, VT_GETSTATE, &dummy) == 0);
|
||||
on_a_vt = (ioctl(STDOUT_FILENO, VT_GETSTATE, &dummy) == 0);
|
||||
#endif
|
||||
|
||||
/* Back up the terminal settings so that they can be restored. */
|
||||
tcgetattr(0, &original_state);
|
||||
tcgetattr(STDIN_FILENO, &original_state);
|
||||
|
||||
/* Get the state of standard input and ensure it uses blocking mode. */
|
||||
stdin_flags = fcntl(0, F_GETFL, 0);
|
||||
stdin_flags = fcntl(STDIN_FILENO, F_GETFL, 0);
|
||||
if (stdin_flags != -1)
|
||||
fcntl(0, F_SETFL, stdin_flags & ~O_NONBLOCK);
|
||||
fcntl(STDIN_FILENO, F_SETFL, stdin_flags & ~O_NONBLOCK);
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
/* If setting the locale is successful and it uses UTF-8, we need
|
||||
* to use the multibyte functions for text processing. */
|
||||
if (setlocale(LC_ALL, "") != NULL &&
|
||||
strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
|
||||
#ifdef USE_SLANG
|
||||
SLutf8_enable(1);
|
||||
#endif
|
||||
/* If setting the locale is successful and it uses UTF-8, we will
|
||||
* need to use the multibyte functions for text processing. */
|
||||
if (setlocale(LC_ALL, "") && strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
|
||||
utf8_init();
|
||||
}
|
||||
#else
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
@@ -1814,7 +1822,7 @@ int main(int argc, char **argv)
|
||||
SET(RESTRICTED);
|
||||
|
||||
while ((optchr = getopt_long(argc, argv, "ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Z"
|
||||
"abcdef:ghijklmno:pqr:s:tuvwxyz$", long_options, NULL)) != -1) {
|
||||
"abcdef:ghijklmno:pqr:s:tuvwxyz$%_!", long_options, NULL)) != -1) {
|
||||
switch (optchr) {
|
||||
#ifndef NANO_TINY
|
||||
case 'A':
|
||||
@@ -1903,7 +1911,6 @@ int main(int argc, char **argv)
|
||||
case '$': /* Deprecated; remove in 2024. */
|
||||
SET(SOFTWRAP);
|
||||
break;
|
||||
#endif
|
||||
case 'T':
|
||||
if (!parse_num(optarg, &tabsize) || tabsize <= 0) {
|
||||
fprintf(stderr, _("Requested tab size \"%s\" is invalid"), optarg);
|
||||
@@ -1911,6 +1918,7 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'U':
|
||||
SET(QUICK_BLANK);
|
||||
break;
|
||||
@@ -1949,9 +1957,11 @@ int main(int argc, char **argv)
|
||||
case 'd':
|
||||
SET(REBIND_DELETE);
|
||||
break;
|
||||
#ifndef NANO_TINY
|
||||
case 'e':
|
||||
SET(EMPTY_LINE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
case 'f':
|
||||
custom_nanorc = mallocstrcpy(custom_nanorc, optarg);
|
||||
@@ -1969,11 +1979,9 @@ int main(int argc, char **argv)
|
||||
case 'i':
|
||||
SET(AUTOINDENT);
|
||||
break;
|
||||
#endif
|
||||
case 'j':
|
||||
SET(JUMPY_SCROLLING);
|
||||
break;
|
||||
#ifndef NANO_TINY
|
||||
case 'k':
|
||||
SET(CUT_FROM_CURSOR);
|
||||
break;
|
||||
@@ -1988,9 +1996,11 @@ int main(int argc, char **argv)
|
||||
SET(USE_MOUSE);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
case 'n':
|
||||
SET(NOREAD_MODE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
case 'o':
|
||||
operating_dir = mallocstrcpy(operating_dir, optarg);
|
||||
@@ -2048,6 +2058,19 @@ int main(int argc, char **argv)
|
||||
case 'z':
|
||||
SET(SUSPENDABLE);
|
||||
break;
|
||||
#ifndef NANO_TINY
|
||||
case '%':
|
||||
SET(STATEFLAGS);
|
||||
break;
|
||||
case '_':
|
||||
SET(MINIBAR);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_LIBMAGIC
|
||||
case '!':
|
||||
SET(USE_MAGIC);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf(_("Type '%s -h' for a list of available options.\n"), argv[0]);
|
||||
exit(1);
|
||||
@@ -2075,9 +2098,10 @@ int main(int argc, char **argv)
|
||||
ssize_t fill_cmdline = fill;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
size_t stripeclm_cmdline = stripe_column;
|
||||
char *backup_dir_cmdline = backup_dir;
|
||||
char *word_chars_cmdline = word_chars;
|
||||
size_t stripeclm_cmdline = stripe_column;
|
||||
ssize_t tabsize_cmdline = tabsize;
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
char *operating_dir_cmdline = operating_dir;
|
||||
@@ -2088,7 +2112,6 @@ int main(int argc, char **argv)
|
||||
#ifdef ENABLE_SPELLER
|
||||
char *alt_speller_cmdline = alt_speller;
|
||||
#endif
|
||||
ssize_t tabsize_cmdline = tabsize;
|
||||
|
||||
/* Back up the command-line flags. */
|
||||
unsigned flags_cmdline[sizeof(flags) / sizeof(flags[0])];
|
||||
@@ -2117,8 +2140,6 @@ int main(int argc, char **argv)
|
||||
fill = fill_cmdline;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (stripeclm_cmdline > 0)
|
||||
stripe_column = stripeclm_cmdline;
|
||||
if (backup_dir_cmdline != NULL) {
|
||||
free(backup_dir);
|
||||
backup_dir = backup_dir_cmdline;
|
||||
@@ -2127,6 +2148,10 @@ int main(int argc, char **argv)
|
||||
free(word_chars);
|
||||
word_chars = word_chars_cmdline;
|
||||
}
|
||||
if (stripeclm_cmdline > 0)
|
||||
stripe_column = stripeclm_cmdline;
|
||||
if (tabsize_cmdline != -1)
|
||||
tabsize = tabsize_cmdline;
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
if (operating_dir_cmdline != NULL || ISSET(RESTRICTED)) {
|
||||
@@ -2145,9 +2170,10 @@ int main(int argc, char **argv)
|
||||
free(alt_speller);
|
||||
alt_speller = alt_speller_cmdline;
|
||||
}
|
||||
/* Strip leading whitespace from the speller command, if any. */
|
||||
while (alt_speller && *alt_speller && isblank(*alt_speller))
|
||||
memmove(alt_speller, alt_speller + 1, strlen(alt_speller));
|
||||
#endif
|
||||
if (tabsize_cmdline != -1)
|
||||
tabsize = tabsize_cmdline;
|
||||
|
||||
/* If an rcfile undid the default settings, copy it to the new flags. */
|
||||
if (!ISSET(NO_WRAP))
|
||||
@@ -2233,7 +2259,7 @@ int main(int argc, char **argv)
|
||||
quoterc = regcomp("ereg, quotestr, NANO_REG_EXTENDED);
|
||||
if (quoterc != 0) {
|
||||
size_t size = regerror(quoterc, "ereg, NULL, 0);
|
||||
char *message = charalloc(size);
|
||||
char *message = nmalloc(size);
|
||||
|
||||
regerror(quoterc, "ereg, message, size);
|
||||
die(_("Bad quoting regex \"%s\": %s\n"), quotestr, message);
|
||||
@@ -2297,7 +2323,10 @@ int main(int argc, char **argv)
|
||||
interface_color_pair[TITLE_BAR] = hilite_attribute;
|
||||
interface_color_pair[LINE_NUMBER] = hilite_attribute;
|
||||
interface_color_pair[GUIDE_STRIPE] = A_REVERSE;
|
||||
interface_color_pair[SCROLL_BAR] = A_NORMAL;
|
||||
interface_color_pair[SELECTED_TEXT] = hilite_attribute;
|
||||
interface_color_pair[HIGHLIGHTED] = A_REVERSE;
|
||||
interface_color_pair[PROMPT_BAR] = hilite_attribute;
|
||||
interface_color_pair[STATUS_BAR] = hilite_attribute;
|
||||
interface_color_pair[ERROR_MESSAGE] = hilite_attribute;
|
||||
interface_color_pair[KEY_COMBO] = hilite_attribute;
|
||||
@@ -2406,13 +2435,16 @@ int main(int argc, char **argv)
|
||||
statusline(ALERT, _("Invalid line or column number"));
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If the filename is a dash, read from standard input; otherwise,
|
||||
* open the file; skip positioning the cursor if either failed. */
|
||||
if (strcmp(argv[optind], "-") == 0) {
|
||||
optind++;
|
||||
if (!scoop_stdin())
|
||||
continue;
|
||||
} else if (!open_buffer(argv[optind++], TRUE))
|
||||
} else
|
||||
#endif
|
||||
if (!open_buffer(argv[optind++], TRUE))
|
||||
continue;
|
||||
|
||||
/* If a position was given on the command line, go there. */
|
||||
@@ -2460,6 +2492,9 @@ int main(int argc, char **argv)
|
||||
if (ISSET(VIEW_MODE))
|
||||
SET(MULTIBUFFER);
|
||||
}
|
||||
#else
|
||||
if (optind < argc)
|
||||
die(_("Can open just one file\n"));
|
||||
#endif
|
||||
|
||||
prepare_for_display();
|
||||
@@ -2488,12 +2523,16 @@ int main(int argc, char **argv)
|
||||
if (currmenu != MMAIN)
|
||||
bottombars(MMAIN);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(MINIBAR) && lastmessage < REMARK)
|
||||
minibar();
|
||||
else
|
||||
#endif
|
||||
/* Update the displayed current cursor position only when there
|
||||
* is no message and no keys are waiting in the input buffer. */
|
||||
if (ISSET(CONSTANT_SHOW) && lastmessage == VACUUM && get_key_buffer_len() == 0)
|
||||
report_cursor_position();
|
||||
|
||||
lastmessage = VACUUM;
|
||||
as_an_at = TRUE;
|
||||
|
||||
/* Refresh just the cursor position or the entire edit window. */
|
||||
@@ -2503,6 +2542,11 @@ int main(int argc, char **argv)
|
||||
} else
|
||||
edit_refresh();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Let the next keystroke cancel the highlighting of a search match. */
|
||||
refresh_needed = spotlighted;
|
||||
spotlighted = FALSE;
|
||||
#endif
|
||||
errno = 0;
|
||||
focusing = TRUE;
|
||||
|
||||
|
||||
86
src/prompt.c
86
src/prompt.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* prompt.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2018 Benno Schulenberg *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2018, 2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -57,9 +57,18 @@ void do_statusbar_next_word(void)
|
||||
* and if we've already seen a word, then it's a word end. */
|
||||
if (is_word_char(answer + typing_x, FALSE))
|
||||
seen_word = TRUE;
|
||||
#ifdef ENABLE_UTF8
|
||||
else if (is_zerowidth(answer + typing_x))
|
||||
; /* skip */
|
||||
#endif
|
||||
else if (seen_word)
|
||||
break;
|
||||
} else {
|
||||
#ifdef ENABLE_UTF8
|
||||
if (is_zerowidth(answer + typing_x))
|
||||
; /* skip */
|
||||
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_char(answer + typing_x, FALSE))
|
||||
@@ -81,6 +90,10 @@ void do_statusbar_prev_word(void)
|
||||
|
||||
if (is_word_char(answer + typing_x, FALSE))
|
||||
seen_a_word = TRUE;
|
||||
#ifdef ENABLE_UTF8
|
||||
else if (is_zerowidth(answer + typing_x))
|
||||
; /* skip */
|
||||
#endif
|
||||
else if (seen_a_word) {
|
||||
/* This is space now: we've overshot the start of the word. */
|
||||
step_forward = TRUE;
|
||||
@@ -97,15 +110,25 @@ void do_statusbar_prev_word(void)
|
||||
/* Move left one character in the answer. */
|
||||
void do_statusbar_left(void)
|
||||
{
|
||||
if (typing_x > 0)
|
||||
if (typing_x > 0) {
|
||||
typing_x = step_left(answer, typing_x);
|
||||
#ifdef ENABLE_UTF8
|
||||
while (typing_x > 0 && is_zerowidth(answer + typing_x))
|
||||
typing_x = step_left(answer, typing_x);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Move right one character in the answer. */
|
||||
void do_statusbar_right(void)
|
||||
{
|
||||
if (answer[typing_x] != '\0')
|
||||
if (answer[typing_x] != '\0') {
|
||||
typing_x = step_right(answer, typing_x);
|
||||
#ifdef ENABLE_UTF8
|
||||
while (answer[typing_x] != '\0' && is_zerowidth(answer + typing_x))
|
||||
typing_x = step_right(answer, typing_x);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete one character in the answer. */
|
||||
@@ -116,6 +139,10 @@ void do_statusbar_delete(void)
|
||||
|
||||
memmove(answer + typing_x, answer + typing_x + charlen,
|
||||
strlen(answer) - typing_x - charlen + 1);
|
||||
#ifdef ENABLE_UTF8
|
||||
if (is_zerowidth(answer + typing_x))
|
||||
do_statusbar_delete();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,8 +150,10 @@ void do_statusbar_delete(void)
|
||||
void do_statusbar_backspace(void)
|
||||
{
|
||||
if (typing_x > 0) {
|
||||
size_t was_x = typing_x;
|
||||
|
||||
typing_x = step_left(answer, typing_x);
|
||||
do_statusbar_delete();
|
||||
memmove(answer + typing_x, answer + was_x, strlen(answer) - was_x + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +170,7 @@ void do_statusbar_cut_text(void)
|
||||
void paste_into_answer(void)
|
||||
{
|
||||
size_t pastelen = strlen(cutbuffer->data);
|
||||
char *fusion = charalloc(strlen(answer) + pastelen + 1);
|
||||
char *fusion = nmalloc(strlen(answer) + pastelen + 1);
|
||||
|
||||
/* Concatenate: the current answer before the cursor, the first line
|
||||
* of the cutbuffer, plus the rest of the current answer. */
|
||||
@@ -184,7 +213,7 @@ void inject_into_answer(char *burst, size_t count)
|
||||
if (burst[index] == '\0')
|
||||
burst[index] = '\n';
|
||||
|
||||
answer = charealloc(answer, strlen(answer) + count + 1);
|
||||
answer = nrealloc(answer, strlen(answer) + count + 1);
|
||||
memmove(answer + typing_x + count, answer + typing_x,
|
||||
strlen(answer) - typing_x + 1);
|
||||
strncpy(answer + typing_x, burst , count);
|
||||
@@ -253,7 +282,7 @@ int do_statusbar_input(bool *finished)
|
||||
beep();
|
||||
else if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
|
||||
openfile->filename[0] == '\0') {
|
||||
puddle = charealloc(puddle, depth + 2);
|
||||
puddle = nrealloc(puddle, depth + 2);
|
||||
puddle[depth++] = (char)input;
|
||||
}
|
||||
}
|
||||
@@ -351,18 +380,19 @@ void put_cursor_at_end_of_answer(void)
|
||||
typing_x = HIGHEST_POSITIVE;
|
||||
}
|
||||
|
||||
/* Redraw the promptbar and place the cursor at the right spot. */
|
||||
/* Redraw the prompt bar and place the cursor at the right spot. */
|
||||
void draw_the_promptbar(void)
|
||||
{
|
||||
size_t base = breadth(prompt) + 2;
|
||||
size_t the_page, end_page, column;
|
||||
size_t column = base + wideness(answer, typing_x);
|
||||
size_t the_page, end_page;
|
||||
char *expanded;
|
||||
|
||||
the_page = get_statusbar_page_start(base, base + wideness(answer, typing_x));
|
||||
the_page = get_statusbar_page_start(base, column);
|
||||
end_page = get_statusbar_page_start(base, base + breadth(answer) - 1);
|
||||
|
||||
/* Color the promptbar over its full width. */
|
||||
wattron(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
/* Color the prompt bar over its full width. */
|
||||
wattron(bottomwin, interface_color_pair[PROMPT_BAR]);
|
||||
mvwprintw(bottomwin, 0, 0, "%*s", COLS, " ");
|
||||
|
||||
mvwaddstr(bottomwin, 0, 0, prompt);
|
||||
@@ -373,18 +403,21 @@ void draw_the_promptbar(void)
|
||||
waddstr(bottomwin, expanded);
|
||||
free(expanded);
|
||||
|
||||
if (base + breadth(answer) != COLS && the_page < end_page)
|
||||
if (the_page < end_page && base + breadth(answer) - the_page > COLS)
|
||||
mvwaddch(bottomwin, 0, COLS - 1, '>');
|
||||
|
||||
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
wattroff(bottomwin, interface_color_pair[PROMPT_BAR]);
|
||||
|
||||
/* Work around a cursor-misplacement bug in VTEs. */
|
||||
wmove(bottomwin, 0, 0);
|
||||
wrefresh(bottomwin);
|
||||
#if defined(NCURSES_VERSION_PATCH) && (NCURSES_VERSION_PATCH < 20210220)
|
||||
/* Work around a cursor-misplacement bug -- https://sv.gnu.org/bugs/?59808. */
|
||||
if (ISSET(NO_HELP)) {
|
||||
wmove(bottomwin, 0, 0);
|
||||
wrefresh(bottomwin);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Place the cursor at the right spot. */
|
||||
column = base + wideness(answer, typing_x);
|
||||
wmove(bottomwin, 0, column - get_statusbar_page_start(base, column));
|
||||
wmove(bottomwin, 0, column - the_page);
|
||||
wnoutrefresh(bottomwin);
|
||||
}
|
||||
|
||||
@@ -397,7 +430,7 @@ void add_or_remove_pipe_symbol_from_answer(void)
|
||||
if (typing_x > 0)
|
||||
typing_x--;
|
||||
} else {
|
||||
answer = charealloc(answer, strlen(answer) + 2);
|
||||
answer = nrealloc(answer, strlen(answer) + 2);
|
||||
memmove(answer + 1, answer, strlen(answer) + 1);
|
||||
answer[0] = '|';
|
||||
typing_x++;
|
||||
@@ -465,8 +498,7 @@ functionptrtype acquire_an_answer(int *actual, bool *listed,
|
||||
} else
|
||||
#endif
|
||||
/* Allow tab completion of filenames, but not in restricted mode. */
|
||||
if ((currmenu == MINSERTFILE || currmenu == MWRITEFILE ||
|
||||
currmenu == MGOTODIR) && !ISSET(RESTRICTED))
|
||||
if ((currmenu & (MINSERTFILE|MWRITEFILE|MGOTODIR)) && !ISSET(RESTRICTED))
|
||||
answer = input_tab(answer, &typing_x, refresh_func, listed);
|
||||
} else
|
||||
#endif /* ENABLE_TABCOMP */
|
||||
@@ -566,7 +598,7 @@ int do_prompt(int menu, const char *provided, linestruct **history_list,
|
||||
#ifndef NANO_TINY
|
||||
redo_theprompt:
|
||||
#endif
|
||||
prompt = charalloc((COLS * MAXCHARLEN) + 1);
|
||||
prompt = nmalloc((COLS * MAXCHARLEN) + 1);
|
||||
va_start(ap, msg);
|
||||
vsnprintf(prompt, COLS * MAXCHARLEN, msg, ap);
|
||||
va_end(ap);
|
||||
@@ -659,11 +691,11 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
post_one_key(cancelshortcut->keystr, _("Cancel"), width);
|
||||
}
|
||||
|
||||
/* Color the promptbar over its full width and display the question. */
|
||||
wattron(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
/* Color the prompt bar over its full width and display the question. */
|
||||
wattron(bottomwin, interface_color_pair[PROMPT_BAR]);
|
||||
mvwprintw(bottomwin, 0, 0, "%*s", COLS, " ");
|
||||
mvwaddnstr(bottomwin, 0, 0, msg, actual_x(msg, COLS - 1));
|
||||
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
wattroff(bottomwin, interface_color_pair[PROMPT_BAR]);
|
||||
wnoutrefresh(bottomwin);
|
||||
|
||||
currmenu = MYESNO;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* prototypes.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 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 *
|
||||
@@ -36,7 +36,7 @@ extern bool bracketed_paste;
|
||||
|
||||
extern bool we_are_running;
|
||||
extern bool more_than_one;
|
||||
|
||||
extern bool report_size;
|
||||
extern bool ran_a_tool;
|
||||
|
||||
extern bool inhelp;
|
||||
@@ -53,6 +53,7 @@ extern message_type lastmessage;
|
||||
extern linestruct *pletion_line;
|
||||
|
||||
extern bool also_the_last;
|
||||
extern bool hide_cursor;
|
||||
|
||||
extern char *answer;
|
||||
|
||||
@@ -186,15 +187,10 @@ extern size_t light_to_col;
|
||||
|
||||
typedef void (*functionptrtype)(void);
|
||||
|
||||
/* Most functions in browser.c. */
|
||||
/* The two needed functions from browser.c. */
|
||||
#ifdef ENABLE_BROWSER
|
||||
char *browse_in(const char *inpath);
|
||||
void read_the_list(const char *path, DIR *dir);
|
||||
void browser_refresh(void);
|
||||
void browser_select_dirname(const char *needle);
|
||||
void do_filesearch(bool forwards);
|
||||
void do_fileresearch(bool forwards);
|
||||
char *strip_last_component(const char *path);
|
||||
char *browse_in(const char *inpath);
|
||||
#endif
|
||||
|
||||
/* Most functions in chars.c. */
|
||||
@@ -209,6 +205,7 @@ bool is_word_char(const char *c, bool allow_punct);
|
||||
char control_mbrep(const char *c, bool isdata);
|
||||
#ifdef ENABLE_UTF8
|
||||
int mbwidth(const char *c);
|
||||
bool is_zerowidth(const char *ch);
|
||||
char *make_mbchar(long code, int *length);
|
||||
#endif
|
||||
int char_length(const char *pointer);
|
||||
@@ -242,7 +239,6 @@ bool is_valid_unicode(wchar_t wc);
|
||||
void set_interface_colorpairs(void);
|
||||
void prepare_palette(void);
|
||||
void find_and_prime_applicable_syntax(void);
|
||||
void set_up_multicache(linestruct *line);
|
||||
void check_the_multis(linestruct *line);
|
||||
void precalc_multicolorinfo(void);
|
||||
#endif
|
||||
@@ -395,9 +391,6 @@ void free_lines(linestruct *src);
|
||||
void renumber_from(linestruct *line);
|
||||
void print_view_warning(void);
|
||||
bool in_restricted_mode(void);
|
||||
#ifndef ENABLE_HELP
|
||||
void say_there_is_no_help(void);
|
||||
#endif
|
||||
void finish(void);
|
||||
void close_and_go(void);
|
||||
void do_exit(void);
|
||||
@@ -405,18 +398,20 @@ void die(const char *msg, ...);
|
||||
void window_init(void);
|
||||
void install_handler_for_Ctrl_C(void);
|
||||
void restore_handler_for_Ctrl_C(void);
|
||||
#ifndef NANO_TINY
|
||||
void reconnect_and_store_state(void);
|
||||
RETSIGTYPE handle_hupterm(int signal);
|
||||
#ifndef DEBUG
|
||||
RETSIGTYPE handle_crash(int signal);
|
||||
#endif
|
||||
RETSIGTYPE do_suspend(int signal);
|
||||
RETSIGTYPE do_continue(int signal);
|
||||
void handle_hupterm(int signal);
|
||||
#ifndef DEBUG
|
||||
void handle_crash(int signal);
|
||||
#endif
|
||||
void do_suspend(int signal);
|
||||
void do_continue(int signal);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER) || defined(ENABLE_COLOR)
|
||||
void block_sigwinch(bool blockit);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE handle_sigwinch(int signal);
|
||||
void handle_sigwinch(int signal);
|
||||
void compute_the_extra_rows_per_line_from(linestruct *fromline);
|
||||
void regenerate_screen(void);
|
||||
void do_toggle(int flag);
|
||||
@@ -595,9 +590,11 @@ void blank_statusbar(void);
|
||||
void wipe_statusbar(void);
|
||||
void blank_bottombars(void);
|
||||
void check_statusblank(void);
|
||||
void set_blankdelay_to_one(void);
|
||||
char *display_string(const char *buf, size_t column, size_t span,
|
||||
bool isdata, bool isprompt);
|
||||
void titlebar(const char *path);
|
||||
void minibar(void);
|
||||
void statusline(message_type importance, const char *msg, ...);
|
||||
void statusbar(const char *msg);
|
||||
void warn_and_briefly_pause(const char *msg);
|
||||
|
||||
117
src/rcfile.c
117
src/rcfile.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* rcfile.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014 Mike Frysinger *
|
||||
* Copyright (C) 2019 Brand Huntsman *
|
||||
* Copyright (C) 2014-2020 Benno Schulenberg *
|
||||
@@ -48,16 +48,17 @@ static const rcoption rcopts[] = {
|
||||
#endif
|
||||
{"casesensitive", CASE_SENSITIVE},
|
||||
{"constantshow", CONSTANT_SHOW},
|
||||
{"emptyline", EMPTY_LINE},
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
{"fill", 0},
|
||||
#endif
|
||||
#ifdef ENABLE_HISTORIES
|
||||
{"historylog", HISTORYLOG},
|
||||
#endif
|
||||
{"jumpyscrolling", JUMPY_SCROLLING},
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
{"linenumbers", LINE_NUMBERS},
|
||||
#endif
|
||||
#ifdef HAVE_LIBMAGIC
|
||||
{"magic", USE_MAGIC},
|
||||
#endif
|
||||
{"morespace", MORE_SPACE}, /* Deprecated; remove in 2021. */
|
||||
#ifdef ENABLE_MOUSE
|
||||
@@ -70,7 +71,7 @@ static const rcoption rcopts[] = {
|
||||
{"nonewlines", NO_NEWLINES},
|
||||
{"nopauses", NO_PAUSES}, /* Obsolete; remove in 2021. */
|
||||
#ifdef ENABLE_WRAPPING
|
||||
{"nowrap", NO_WRAP}, /* Deprecated; remove in 2021. */
|
||||
{"nowrap", NO_WRAP}, /* Deprecated; remove in 2024. */
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
{"operatingdir", 0},
|
||||
@@ -93,9 +94,7 @@ static const rcoption rcopts[] = {
|
||||
#endif
|
||||
{"suspend", SUSPENDABLE}, /* Deprecated; remove in 2022. */
|
||||
{"suspendable", SUSPENDABLE},
|
||||
{"tabsize", 0},
|
||||
{"tempfile", SAVE_ON_EXIT}, /* Deprecated; remove in 2022. */
|
||||
{"view", VIEW_MODE},
|
||||
#ifndef NANO_TINY
|
||||
{"afterends", AFTER_ENDS},
|
||||
{"allow_insecure_backup", INSECURE_BACKUP},
|
||||
@@ -105,15 +104,20 @@ static const rcoption rcopts[] = {
|
||||
{"backupdir", 0},
|
||||
{"bookstyle", BOOKSTYLE},
|
||||
{"cutfromcursor", CUT_FROM_CURSOR},
|
||||
{"emptyline", EMPTY_LINE},
|
||||
{"guidestripe", 0},
|
||||
{"indicator", INDICATOR},
|
||||
{"jumpyscrolling", JUMPY_SCROLLING},
|
||||
{"locking", LOCKING},
|
||||
{"matchbrackets", 0},
|
||||
{"minibar", MINIBAR},
|
||||
{"noconvert", NO_CONVERT},
|
||||
{"showcursor", SHOW_CURSOR},
|
||||
{"smarthome", SMART_HOME},
|
||||
{"smooth", SMOOTH_SCROLL}, /* Deprecated; remove in 2021. */
|
||||
{"softwrap", SOFTWRAP},
|
||||
{"stateflags", STATEFLAGS},
|
||||
{"tabsize", 0},
|
||||
{"tabstospaces", TABS_TO_SPACES},
|
||||
{"trimblanks", TRIM_BLANKS},
|
||||
{"unix", MAKE_IT_UNIX},
|
||||
@@ -126,7 +130,10 @@ static const rcoption rcopts[] = {
|
||||
{"titlecolor", 0},
|
||||
{"numbercolor", 0},
|
||||
{"stripecolor", 0},
|
||||
{"scrollercolor", 0},
|
||||
{"selectedcolor", 0},
|
||||
{"highlightcolor", 0},
|
||||
{"promptcolor", 0},
|
||||
{"statuscolor", 0},
|
||||
{"errorcolor", 0},
|
||||
{"keycolor", 0},
|
||||
@@ -469,7 +476,8 @@ keystruct *strtosc(const char *input)
|
||||
else if (!strcmp(input, "cutfromcursor"))
|
||||
s->toggle = CUT_FROM_CURSOR;
|
||||
#ifdef ENABLE_WRAPPING
|
||||
else if (!strcmp(input, "nowrap"))
|
||||
else if (!strcmp(input, "breaklonglines") ||
|
||||
!strcmp(input, "nowrap")) /* Deprecated; remove in 2024. */
|
||||
s->toggle = BREAK_LONG_LINES;
|
||||
#endif
|
||||
else if (!strcmp(input, "tabstospaces"))
|
||||
@@ -612,7 +620,7 @@ bool compile(const char *expression, int rex_flags, regex_t **packed)
|
||||
|
||||
if (outcome != 0) {
|
||||
size_t length = regerror(outcome, compiled, NULL, 0);
|
||||
char *message = charalloc(length);
|
||||
char *message = nmalloc(length);
|
||||
|
||||
regerror(outcome, compiled, message, length);
|
||||
jot_error(N_("Bad regex \"%s\": %s"), expression, message);
|
||||
@@ -662,7 +670,7 @@ void begin_new_syntax(char *ptr)
|
||||
}
|
||||
|
||||
/* Initialize a new syntax struct. */
|
||||
live_syntax = (syntaxtype *)nmalloc(sizeof(syntaxtype));
|
||||
live_syntax = nmalloc(sizeof(syntaxtype));
|
||||
live_syntax->name = copy_of(nameptr);
|
||||
live_syntax->filename = copy_of(nanorc);
|
||||
live_syntax->lineno = lineno;
|
||||
@@ -1166,7 +1174,7 @@ void parse_rule(char *ptr, int rex_flags)
|
||||
}
|
||||
|
||||
/* Allocate a rule, fill in the data, and link it into the list. */
|
||||
newcolor = (colortype *)nmalloc(sizeof(colortype));
|
||||
newcolor = nmalloc(sizeof(colortype));
|
||||
|
||||
newcolor->start = start_rgx;
|
||||
newcolor->end = end_rgx;
|
||||
@@ -1196,14 +1204,11 @@ colortype *parse_interface_color(char *combostr)
|
||||
{
|
||||
colortype *trio = nmalloc(sizeof(colortype));
|
||||
|
||||
if (parse_combination(combostr, &trio->fg, &trio->bg, &trio->attributes)) {
|
||||
free(combostr);
|
||||
return trio;
|
||||
} else {
|
||||
free(combostr);
|
||||
if (!parse_combination(combostr, &trio->fg, &trio->bg, &trio->attributes)) {
|
||||
free(trio);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
return trio;
|
||||
}
|
||||
|
||||
/* Read regex strings enclosed in double quotes from the line pointed at
|
||||
@@ -1248,7 +1253,7 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
|
||||
continue;
|
||||
|
||||
/* Copy the regex into a struct, and hook this in at the end. */
|
||||
newthing = (regexlisttype *)nmalloc(sizeof(regexlisttype));
|
||||
newthing = nmalloc(sizeof(regexlisttype));
|
||||
newthing->full_regex = copy_of(regexstring);
|
||||
newthing->next = NULL;
|
||||
|
||||
@@ -1542,8 +1547,6 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
argument = copy_of(argument);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (strcmp(option, "titlecolor") == 0)
|
||||
color_combo[TITLE_BAR] = parse_interface_color(argument);
|
||||
@@ -1551,8 +1554,14 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
color_combo[LINE_NUMBER] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "stripecolor") == 0)
|
||||
color_combo[GUIDE_STRIPE] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "scrollercolor") == 0)
|
||||
color_combo[SCROLL_BAR] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "selectedcolor") == 0)
|
||||
color_combo[SELECTED_TEXT] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "highlightcolor") == 0)
|
||||
color_combo[HIGHLIGHTED] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "promptcolor") == 0)
|
||||
color_combo[PROMPT_BAR] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "statuscolor") == 0)
|
||||
color_combo[STATUS_BAR] = parse_interface_color(argument);
|
||||
else if (strcmp(option, "errorcolor") == 0)
|
||||
@@ -1565,7 +1574,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
if (strcmp(option, "operatingdir") == 0)
|
||||
operating_dir = argument;
|
||||
operating_dir = copy_of(argument);
|
||||
else
|
||||
#endif
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
@@ -1574,31 +1583,21 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
jot_error(N_("Requested fill size \"%s\" is invalid"), argument);
|
||||
fill = -COLUMNS_FROM_EOL;
|
||||
}
|
||||
free(argument);
|
||||
} else
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (strcmp(option, "guidestripe") == 0) {
|
||||
if (!parse_num(argument, &stripe_column) || stripe_column <= 0) {
|
||||
jot_error(N_("Guide column \"%s\" is invalid"), argument);
|
||||
stripe_column = 0;
|
||||
}
|
||||
free(argument);
|
||||
} else if (strcmp(option, "matchbrackets") == 0) {
|
||||
if (has_blank_char(argument)) {
|
||||
if (strcmp(option, "matchbrackets") == 0) {
|
||||
if (has_blank_char(argument))
|
||||
jot_error(N_("Non-blank characters required"));
|
||||
free(argument);
|
||||
} else if (mbstrlen(argument) % 2 != 0) {
|
||||
else if (mbstrlen(argument) % 2 != 0)
|
||||
jot_error(N_("Even number of characters required"));
|
||||
free(argument);
|
||||
} else
|
||||
matchbrackets = argument;
|
||||
else
|
||||
matchbrackets = copy_of(argument);
|
||||
} else if (strcmp(option, "whitespace") == 0) {
|
||||
if (mbstrlen(argument) != 2 || breadth(argument) != 2) {
|
||||
if (mbstrlen(argument) != 2 || breadth(argument) != 2)
|
||||
jot_error(N_("Two single-column characters required"));
|
||||
free(argument);
|
||||
} else {
|
||||
whitespace = argument;
|
||||
else {
|
||||
whitespace = copy_of(argument);
|
||||
whitelen[0] = char_length(whitespace);
|
||||
whitelen[1] = char_length(whitespace + whitelen[0]);
|
||||
}
|
||||
@@ -1606,41 +1605,43 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
if (strcmp(option, "punct") == 0) {
|
||||
if (has_blank_char(argument)) {
|
||||
if (has_blank_char(argument))
|
||||
jot_error(N_("Non-blank characters required"));
|
||||
free(argument);
|
||||
} else
|
||||
punct = argument;
|
||||
else
|
||||
punct = copy_of(argument);
|
||||
} else if (strcmp(option, "brackets") == 0) {
|
||||
if (has_blank_char(argument)) {
|
||||
if (has_blank_char(argument))
|
||||
jot_error(N_("Non-blank characters required"));
|
||||
free(argument);
|
||||
} else
|
||||
brackets = argument;
|
||||
else
|
||||
brackets = copy_of(argument);
|
||||
} else if (strcmp(option, "quotestr") == 0)
|
||||
quotestr = argument;
|
||||
else
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (strcmp(option, "backupdir") == 0)
|
||||
backup_dir = argument;
|
||||
else
|
||||
if (strcmp(option, "wordchars") == 0)
|
||||
word_chars = argument;
|
||||
quotestr = copy_of(argument);
|
||||
else
|
||||
#endif
|
||||
#ifdef ENABLE_SPELLER
|
||||
if (strcmp(option, "speller") == 0)
|
||||
alt_speller = argument;
|
||||
alt_speller = copy_of(argument);
|
||||
else
|
||||
#endif
|
||||
if (strcmp(option, "tabsize") == 0) {
|
||||
#ifndef NANO_TINY
|
||||
if (strcmp(option, "backupdir") == 0)
|
||||
backup_dir = copy_of(argument);
|
||||
else if (strcmp(option, "wordchars") == 0)
|
||||
word_chars = copy_of(argument);
|
||||
else if (strcmp(option, "guidestripe") == 0) {
|
||||
if (!parse_num(argument, &stripe_column) || stripe_column <= 0) {
|
||||
jot_error(N_("Guide column \"%s\" is invalid"), argument);
|
||||
stripe_column = 0;
|
||||
}
|
||||
} else if (strcmp(option, "tabsize") == 0) {
|
||||
if (!parse_num(argument, &tabsize) || tabsize <= 0) {
|
||||
jot_error(N_("Requested tab size \"%s\" is invalid"), argument);
|
||||
tabsize = -1;
|
||||
}
|
||||
free(argument);
|
||||
}
|
||||
#else
|
||||
; /* Properly terminate any earlier 'else'. */
|
||||
#endif
|
||||
}
|
||||
|
||||
if (intros_only)
|
||||
|
||||
80
src/search.c
80
src/search.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* search.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2019 Benno Schulenberg *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2020 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "prototypes.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
static bool came_full_circle = FALSE;
|
||||
/* Have we reached the starting line again while searching? */
|
||||
@@ -38,10 +39,10 @@ bool regexp_init(const char *regexp)
|
||||
/* If regex compilation failed, show the error message. */
|
||||
if (value != 0) {
|
||||
size_t len = regerror(value, &search_regexp, NULL, 0);
|
||||
char *str = charalloc(len);
|
||||
char *str = nmalloc(len);
|
||||
|
||||
regerror(value, &search_regexp, str, len);
|
||||
statusline(ALERT, _("Bad regex \"%s\": %s"), regexp, str);
|
||||
statusline(AHEM, _("Bad regex \"%s\": %s"), regexp, str);
|
||||
free(str);
|
||||
|
||||
return FALSE;
|
||||
@@ -78,7 +79,7 @@ void search_init(bool replacing, bool retain_answer)
|
||||
if (*last_search != '\0') {
|
||||
char *disp = display_string(last_search, 0, COLS / 3, FALSE, FALSE);
|
||||
|
||||
thedefault = charalloc(strlen(disp) + 7);
|
||||
thedefault = nmalloc(strlen(disp) + 7);
|
||||
/* We use (COLS / 3) here because we need to see more on the line. */
|
||||
sprintf(thedefault, " [%s%s]", disp,
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
@@ -250,7 +251,7 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
line = (ISSET(BACKWARDS_SEARCH)) ? openfile->filebot : openfile->filetop;
|
||||
|
||||
if (modus == JUSTFIND) {
|
||||
statusbar(_("Search Wrapped"));
|
||||
statusline(REMARK, _("Search Wrapped"));
|
||||
/* Delay the "Searching..." message for at least two seconds. */
|
||||
feedback = -2;
|
||||
}
|
||||
@@ -321,6 +322,17 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
if (match_len != NULL)
|
||||
*match_len = found_len;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (modus == JUSTFIND && (!openfile->mark || openfile->softmark)) {
|
||||
spotlighted = TRUE;
|
||||
light_from_col = xplustabs();
|
||||
light_to_col = wideness(line->data, found_x + found_len);
|
||||
if (!ISSET(SHOW_CURSOR))
|
||||
hide_cursor = TRUE;
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wipe the "Searching..." message and unsuppress cursor-position display. */
|
||||
if (feedback > 0) {
|
||||
wipe_statusbar();
|
||||
@@ -355,7 +367,7 @@ void do_research(void)
|
||||
#endif
|
||||
|
||||
if (*last_search == '\0') {
|
||||
statusbar(_("No current search pattern"));
|
||||
statusline(AHEM, _("No current search pattern"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -365,7 +377,8 @@ void do_research(void)
|
||||
/* Use the search-menu key bindings, to allow cancelling. */
|
||||
currmenu = MWHEREIS;
|
||||
|
||||
wipe_statusbar();
|
||||
if (LINES > 1)
|
||||
wipe_statusbar();
|
||||
|
||||
go_looking();
|
||||
|
||||
@@ -392,7 +405,7 @@ void not_found_msg(const char *str)
|
||||
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE, FALSE);
|
||||
size_t numchars = actual_x(disp, wideness(disp, COLS / 2));
|
||||
|
||||
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
|
||||
statusline(AHEM, _("\"%.*s%s\" not found"), numchars, disp,
|
||||
(disp[numchars] == '\0') ? "" : "...");
|
||||
free(disp);
|
||||
}
|
||||
@@ -419,12 +432,14 @@ void go_looking(void)
|
||||
* where we started searching, then this is the only occurrence. */
|
||||
if (didfind == 1 && openfile->current == was_current &&
|
||||
openfile->current_x == was_current_x)
|
||||
statusbar(_("This is the only occurrence"));
|
||||
statusline(REMARK, _("This is the only occurrence"));
|
||||
else if (didfind == 1 && LINES == 1)
|
||||
refresh_needed = TRUE;
|
||||
else if (didfind == 0)
|
||||
not_found_msg(last_search);
|
||||
|
||||
#ifdef TIMEIT
|
||||
statusline(HUSH, "Took: %.2f", (double)(clock() - start) / CLOCKS_PER_SEC);
|
||||
statusline(INFO, "Took: %.2f", (double)(clock() - start) / CLOCKS_PER_SEC);
|
||||
#endif
|
||||
|
||||
edit_redraw(was_current, CENTERING);
|
||||
@@ -489,7 +504,7 @@ char *replace_line(const char *needle)
|
||||
new_size += strlen(answer) - match_len;
|
||||
}
|
||||
|
||||
copy = charalloc(new_size);
|
||||
copy = nmalloc(new_size);
|
||||
|
||||
/* Copy the head of the original line. */
|
||||
strncpy(copy, openfile->current->data, openfile->current_x);
|
||||
@@ -506,19 +521,6 @@ char *replace_line(const char *needle)
|
||||
return copy;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
/* Reset the multiline coloring info and then recalculate it. */
|
||||
void wipe_and_recalculate_colorinfo(void)
|
||||
{
|
||||
for (linestruct *line = openfile->filetop; line != NULL; line = line->next)
|
||||
if (line->multidata)
|
||||
for (short index = 0; index < openfile->syntax->nmultis; index++)
|
||||
line->multidata[index] = -1;
|
||||
|
||||
precalc_multicolorinfo();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Step through each occurrence of the search string and prompt the user
|
||||
* before replacing it. We seek for needle, and replace it with answer.
|
||||
* The parameters real_current and real_current_x are needed in order to
|
||||
@@ -666,13 +668,6 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP))
|
||||
openfile->current->extrarows = extra_chunks_in(openfile->current);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
/* Check whether the replacement requires a change in the coloring. */
|
||||
check_the_multis(openfile->current);
|
||||
|
||||
if (refresh_needed && !replaceall)
|
||||
wipe_and_recalculate_colorinfo();
|
||||
#endif
|
||||
set_modified();
|
||||
as_an_at = TRUE;
|
||||
@@ -683,11 +678,6 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
if (numreplaced == -1)
|
||||
not_found_msg(needle);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (refresh_needed)
|
||||
wipe_and_recalculate_colorinfo();
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
openfile->mark = was_mark;
|
||||
#endif
|
||||
@@ -746,7 +736,7 @@ void ask_for_and_do_replacements(void)
|
||||
refresh_needed = TRUE;
|
||||
|
||||
if (numreplaced >= 0)
|
||||
statusline(HUSH, P_("Replaced %zd occurrence",
|
||||
statusline(REMARK, P_("Replaced %zd occurrence",
|
||||
"Replaced %zd occurrences", numreplaced), numreplaced);
|
||||
}
|
||||
|
||||
@@ -794,7 +784,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool retain_answer,
|
||||
|
||||
/* Try to extract one or two numbers from the user's response. */
|
||||
if (!parse_line_column(answer, &line, &column)) {
|
||||
statusline(ALERT, _("Invalid line or column number"));
|
||||
statusline(AHEM, _("Invalid line or column number"));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -942,7 +932,7 @@ void do_find_bracket(void)
|
||||
ch = mbstrchr(matchbrackets, openfile->current->data + openfile->current_x);
|
||||
|
||||
if (ch == NULL) {
|
||||
statusbar(_("Not a bracket"));
|
||||
statusline(AHEM, _("Not a bracket"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -985,7 +975,7 @@ void do_find_bracket(void)
|
||||
}
|
||||
}
|
||||
|
||||
statusbar(_("No matching bracket"));
|
||||
statusline(AHEM, _("No matching bracket"));
|
||||
|
||||
/* Restore the cursor position. */
|
||||
openfile->current = was_current;
|
||||
@@ -1000,9 +990,9 @@ void put_or_lift_anchor(void)
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
|
||||
if (openfile->current->has_anchor)
|
||||
statusbar(_("Placed anchor"));
|
||||
statusline(REMARK, _("Placed anchor"));
|
||||
else
|
||||
statusbar(_("Removed anchor"));
|
||||
statusline(REMARK, _("Removed anchor"));
|
||||
}
|
||||
|
||||
/* Make the given line the current line, or report the anchoredness. */
|
||||
@@ -1016,9 +1006,9 @@ void go_to_and_confirm(linestruct *line)
|
||||
edit_redraw(was_current, CENTERING);
|
||||
statusbar(_("Jumped to anchor"));
|
||||
} else if (openfile->current->has_anchor)
|
||||
statusbar(_("This is the only anchor"));
|
||||
statusline(REMARK, _("This is the only anchor"));
|
||||
else
|
||||
statusbar(_("There are no anchors"));
|
||||
statusline(AHEM, _("There are no anchors"));
|
||||
}
|
||||
|
||||
/* Jump to the first anchor before the current line; wrap around at the top. */
|
||||
|
||||
209
src/text.c
209
src/text.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* text.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2015 Mark Majeres *
|
||||
* Copyright (C) 2016 Mike Scalora *
|
||||
* Copyright (C) 2016 Sumedh Pendurkar *
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
@@ -49,8 +50,8 @@ void do_mark(void)
|
||||
if (!openfile->mark) {
|
||||
openfile->mark = openfile->current;
|
||||
openfile->mark_x = openfile->current_x;
|
||||
openfile->softmark = FALSE;
|
||||
statusbar(_("Mark Set"));
|
||||
openfile->kind_of_mark = HARDMARK;
|
||||
} else {
|
||||
openfile->mark = NULL;
|
||||
statusbar(_("Mark Unset"));
|
||||
@@ -70,7 +71,7 @@ void do_tab(void)
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(TABS_TO_SPACES)) {
|
||||
char *spaces = charalloc(tabsize + 1);
|
||||
char *spaces = nmalloc(tabsize + 1);
|
||||
size_t length = tabsize - (xplustabs() % tabsize);
|
||||
|
||||
memset(spaces, ' ', length);
|
||||
@@ -96,7 +97,7 @@ void indent_a_line(linestruct *line, char *indentation)
|
||||
return;
|
||||
|
||||
/* Add the fabricated indentation to the beginning of the line. */
|
||||
line->data = charealloc(line->data, length + indent_len + 1);
|
||||
line->data = nrealloc(line->data, length + indent_len + 1);
|
||||
memmove(line->data + indent_len, line->data, length + 1);
|
||||
memcpy(line->data, indentation, indent_len);
|
||||
|
||||
@@ -133,7 +134,7 @@ void do_indent(void)
|
||||
if (top == bot->next)
|
||||
return;
|
||||
|
||||
indentation = charalloc(tabsize + 1);
|
||||
indentation = nmalloc(tabsize + 1);
|
||||
|
||||
/* Set the indentation to either a bunch of spaces or a single tab. */
|
||||
#ifdef ENABLE_COLOR
|
||||
@@ -331,7 +332,7 @@ bool comment_line(undo_type action, linestruct *line, const char *comment_seq)
|
||||
if (action == COMMENT) {
|
||||
/* Make room for the comment sequence(s), move the text right and
|
||||
* copy them in. */
|
||||
line->data = charealloc(line->data, line_len + pre_len + post_len + 1);
|
||||
line->data = nrealloc(line->data, line_len + pre_len + post_len + 1);
|
||||
memmove(line->data + pre_len, line->data, line_len + 1);
|
||||
memmove(line->data, comment_seq, pre_len);
|
||||
if (post_len > 0)
|
||||
@@ -386,7 +387,7 @@ void do_comment(void)
|
||||
comment_seq = openfile->syntax->comment;
|
||||
|
||||
if (*comment_seq == '\0') {
|
||||
statusbar(_("Commenting is not supported for this file type"));
|
||||
statusline(AHEM, _("Commenting is not supported for this file type"));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -396,7 +397,7 @@ void do_comment(void)
|
||||
|
||||
/* If only the magic line is selected, don't do anything. */
|
||||
if (top == bot && bot == openfile->filebot && !ISSET(NO_NEWLINES)) {
|
||||
statusbar(_("Cannot comment past end of file"));
|
||||
statusline(AHEM, _("Cannot comment past end of file"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -518,7 +519,7 @@ void do_undo(void)
|
||||
size_t original_x, regain_from_x;
|
||||
|
||||
if (u == NULL) {
|
||||
statusbar(_("Nothing to undo"));
|
||||
statusline(AHEM, _("Nothing to undo"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -543,7 +544,7 @@ void do_undo(void)
|
||||
* case, adjust the positions to return to and to scoop data from. */
|
||||
original_x = (u->head_x == 0) ? u->tail_x : u->head_x;
|
||||
regain_from_x = (u->head_x == 0) ? 0 : u->tail_x;
|
||||
line->data = charealloc(line->data, strlen(line->data) +
|
||||
line->data = nrealloc(line->data, strlen(line->data) +
|
||||
strlen(&u->strdata[regain_from_x]) + 1);
|
||||
strcat(line->data, &u->strdata[regain_from_x]);
|
||||
line->has_anchor |= line->next->has_anchor;
|
||||
@@ -554,7 +555,7 @@ void do_undo(void)
|
||||
case BACK:
|
||||
case DEL:
|
||||
undidmsg = _("deletion");
|
||||
data = charalloc(strlen(line->data) + strlen(u->strdata) + 1);
|
||||
data = nmalloc(strlen(line->data) + strlen(u->strdata) + 1);
|
||||
strncpy(data, line->data, u->head_x);
|
||||
strcpy(&data[u->head_x], u->strdata);
|
||||
strcpy(&data[u->head_x + strlen(u->strdata)], &line->data[u->head_x]);
|
||||
@@ -582,6 +583,8 @@ void do_undo(void)
|
||||
break;
|
||||
case REPLACE:
|
||||
undidmsg = _("replacement");
|
||||
if ((u->xflags & INCLUDED_LAST_LINE) && !ISSET(NO_NEWLINES))
|
||||
remove_magicline();
|
||||
data = u->strdata;
|
||||
u->strdata = line->data;
|
||||
line->data = data;
|
||||
@@ -695,7 +698,7 @@ void do_redo(void)
|
||||
undostruct *u = openfile->undotop;
|
||||
|
||||
if (u == NULL || u == openfile->current_undo) {
|
||||
statusbar(_("Nothing to redo"));
|
||||
statusline(AHEM, _("Nothing to redo"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -711,7 +714,7 @@ void do_redo(void)
|
||||
redidmsg = _("addition");
|
||||
if ((u->xflags & INCLUDED_LAST_LINE) && !ISSET(NO_NEWLINES))
|
||||
new_magicline();
|
||||
data = charalloc(strlen(line->data) + strlen(u->strdata) + 1);
|
||||
data = nmalloc(strlen(line->data) + strlen(u->strdata) + 1);
|
||||
strncpy(data, line->data, u->head_x);
|
||||
strcpy(&data[u->head_x], u->strdata);
|
||||
strcpy(&data[u->head_x + strlen(u->strdata)], &line->data[u->head_x]);
|
||||
@@ -746,7 +749,7 @@ void do_redo(void)
|
||||
goto_line_posx(u->tail_lineno, u->tail_x);
|
||||
break;
|
||||
}
|
||||
line->data = charealloc(line->data, strlen(line->data) + strlen(u->strdata) + 1);
|
||||
line->data = nrealloc(line->data, strlen(line->data) + strlen(u->strdata) + 1);
|
||||
strcat(line->data, u->strdata);
|
||||
unlink_node(line->next);
|
||||
renumber_from(line);
|
||||
@@ -754,6 +757,8 @@ void do_redo(void)
|
||||
break;
|
||||
case REPLACE:
|
||||
redidmsg = _("replacement");
|
||||
if ((u->xflags & INCLUDED_LAST_LINE) && !ISSET(NO_NEWLINES))
|
||||
new_magicline();
|
||||
data = u->strdata;
|
||||
u->strdata = line->data;
|
||||
line->data = data;
|
||||
@@ -876,7 +881,7 @@ void do_enter(void)
|
||||
allblanks = TRUE;
|
||||
}
|
||||
#endif /* NANO_TINY */
|
||||
newnode->data = charalloc(strlen(openfile->current->data +
|
||||
newnode->data = nmalloc(strlen(openfile->current->data +
|
||||
openfile->current_x) + extra + 1);
|
||||
strcpy(&newnode->data[extra], openfile->current->data +
|
||||
openfile->current_x);
|
||||
@@ -1038,6 +1043,8 @@ void add_undo(undo_type action, const char *message)
|
||||
break;
|
||||
case REPLACE:
|
||||
u->strdata = copy_of(thisline->data);
|
||||
if (thisline == openfile->filebot && answer[0] != '\0')
|
||||
u->xflags |= INCLUDED_LAST_LINE;
|
||||
break;
|
||||
#ifdef ENABLE_WRAPPING
|
||||
case SPLIT_BEGIN:
|
||||
@@ -1070,9 +1077,7 @@ void add_undo(undo_type action, const char *message)
|
||||
break;
|
||||
case PASTE:
|
||||
u->cutbuffer = copy_buffer(cutbuffer);
|
||||
if (thisline == openfile->filebot)
|
||||
u->xflags |= INCLUDED_LAST_LINE;
|
||||
break;
|
||||
/* Fall-through. */
|
||||
case INSERT:
|
||||
if (thisline == openfile->filebot)
|
||||
u->xflags |= INCLUDED_LAST_LINE;
|
||||
@@ -1112,7 +1117,7 @@ void update_multiline_undo(ssize_t lineno, char *indentation)
|
||||
u->grouping->bottom_line++;
|
||||
|
||||
number_of_lines = u->grouping->bottom_line - u->grouping->top_line + 1;
|
||||
u->grouping->indentations = (char **)nrealloc(u->grouping->indentations,
|
||||
u->grouping->indentations = nrealloc(u->grouping->indentations,
|
||||
number_of_lines * sizeof(char *));
|
||||
u->grouping->indentations[number_of_lines - 1] = copy_of(indentation);
|
||||
} else {
|
||||
@@ -1123,7 +1128,7 @@ void update_multiline_undo(ssize_t lineno, char *indentation)
|
||||
born->top_line = lineno;
|
||||
born->bottom_line = lineno;
|
||||
|
||||
u->grouping->indentations = (char **)nmalloc(sizeof(char *));
|
||||
u->grouping->indentations = nmalloc(sizeof(char *));
|
||||
u->grouping->indentations[0] = copy_of(indentation);
|
||||
}
|
||||
|
||||
@@ -1148,7 +1153,7 @@ void update_undo(undo_type action)
|
||||
switch (u->type) {
|
||||
case ADD:
|
||||
newlen = openfile->current_x - u->head_x;
|
||||
u->strdata = charealloc(u->strdata, newlen + 1);
|
||||
u->strdata = nrealloc(u->strdata, newlen + 1);
|
||||
strncpy(u->strdata, openfile->current->data + u->head_x, newlen);
|
||||
u->strdata[newlen] = '\0';
|
||||
u->tail_x = openfile->current_x;
|
||||
@@ -1164,13 +1169,13 @@ void update_undo(undo_type action)
|
||||
datalen = strlen(u->strdata);
|
||||
if (openfile->current_x == u->head_x) {
|
||||
/* They deleted more: add removed character after earlier stuff. */
|
||||
u->strdata = charealloc(u->strdata, datalen + charlen + 1);
|
||||
u->strdata = nrealloc(u->strdata, datalen + charlen + 1);
|
||||
strncpy(u->strdata + datalen, textposition, charlen);
|
||||
u->strdata[datalen + charlen] = '\0';
|
||||
u->tail_x = openfile->current_x;
|
||||
} else if (openfile->current_x == u->head_x - charlen) {
|
||||
/* They backspaced further: add removed character before earlier. */
|
||||
u->strdata = charealloc(u->strdata, datalen + charlen + 1);
|
||||
u->strdata = nrealloc(u->strdata, datalen + charlen + 1);
|
||||
memmove(u->strdata + charlen, u->strdata, datalen + 1);
|
||||
strncpy(u->strdata, textposition, charlen);
|
||||
u->head_x = openfile->current_x;
|
||||
@@ -1212,17 +1217,11 @@ void update_undo(undo_type action)
|
||||
u->tail_x = strlen(bottomline->data);
|
||||
}
|
||||
break;
|
||||
case PASTE:
|
||||
u->tail_lineno = openfile->current->lineno;
|
||||
u->tail_x = openfile->current_x;
|
||||
break;
|
||||
case INSERT:
|
||||
u->tail_lineno = openfile->current->lineno;
|
||||
u->tail_x = openfile->current_x;
|
||||
break;
|
||||
case COUPLE_BEGIN:
|
||||
break;
|
||||
case COUPLE_END:
|
||||
case PASTE:
|
||||
case INSERT:
|
||||
u->tail_lineno = openfile->current->lineno;
|
||||
u->tail_x = openfile->current_x;
|
||||
break;
|
||||
@@ -1302,7 +1301,7 @@ bool do_wrap(void)
|
||||
#ifndef NANO_TINY
|
||||
add_undo(ADD, NULL);
|
||||
#endif
|
||||
line->data = charealloc(line->data, line_len + 2);
|
||||
line->data = nrealloc(line->data, line_len + 2);
|
||||
line->data[line_len] = ' ';
|
||||
line->data[line_len + 1] = '\0';
|
||||
rest_length++;
|
||||
@@ -1352,7 +1351,7 @@ bool do_wrap(void)
|
||||
if (quot_len > 0) {
|
||||
line = line->next;
|
||||
line_len = strlen(line->data);
|
||||
line->data = charealloc(line->data, lead_len + line_len + 1);
|
||||
line->data = nrealloc(line->data, lead_len + line_len + 1);
|
||||
|
||||
memmove(line->data + lead_len, line->data, line_len + 1);
|
||||
strncpy(line->data, line->prev->data, lead_len);
|
||||
@@ -1586,12 +1585,12 @@ void concat_paragraph(linestruct *line, size_t count)
|
||||
/* We're just about to tack the next line onto this one. If
|
||||
* this line isn't empty, make sure it ends in a space. */
|
||||
if (line_len > 0 && line->data[line_len - 1] != ' ') {
|
||||
line->data = charealloc(line->data, line_len + 2);
|
||||
line->data = nrealloc(line->data, line_len + 2);
|
||||
line->data[line_len++] = ' ';
|
||||
line->data[line_len] = '\0';
|
||||
}
|
||||
|
||||
line->data = charealloc(line->data,
|
||||
line->data = nrealloc(line->data,
|
||||
line_len + next_line_len - next_lead_len + 1);
|
||||
strcat(line->data, next_line->data + next_lead_len);
|
||||
#ifndef NANO_TINY
|
||||
@@ -1688,7 +1687,7 @@ void rewrap_paragraph(linestruct **line, char *lead_string, size_t lead_len)
|
||||
/* Insert a new line after the current one, and copy the leading part
|
||||
* plus the text after the breaking point into it. */
|
||||
splice_node(*line, make_new_node(*line));
|
||||
(*line)->next->data = charalloc(lead_len + line_len - break_pos + 1);
|
||||
(*line)->next->data = nmalloc(lead_len + line_len - break_pos + 1);
|
||||
strncpy((*line)->next->data, lead_string, lead_len);
|
||||
strcpy((*line)->next->data + lead_len, (*line)->data + break_pos);
|
||||
|
||||
@@ -1785,7 +1784,7 @@ void do_justify(bool full_justify)
|
||||
|
||||
/* When the marked region is empty, do nothing. */
|
||||
if (startline == endline && start_x == end_x) {
|
||||
statusline(ALERT, _("Selection is empty"));
|
||||
statusline(AHEM, _("Selection is empty"));
|
||||
discard_until(openfile->undotop->next);
|
||||
return;
|
||||
}
|
||||
@@ -1838,7 +1837,7 @@ void do_justify(bool full_justify)
|
||||
other_white_len = indent_length(sampleline->data + other_quot_len);
|
||||
|
||||
secondary_len = quot_len + other_white_len;
|
||||
secondary_lead = charalloc(secondary_len + 1);
|
||||
secondary_lead = nmalloc(secondary_len + 1);
|
||||
|
||||
strncpy(secondary_lead, startline->data, quot_len);
|
||||
strncpy(secondary_lead + quot_len, sampleline->data + other_quot_len,
|
||||
@@ -1919,7 +1918,7 @@ void do_justify(bool full_justify)
|
||||
|
||||
/* Then copy back in the leading part that it should have. */
|
||||
if (primary_len > 0) {
|
||||
line->data = charealloc(line->data, primary_len + text_len + 1);
|
||||
line->data = nrealloc(line->data, primary_len + text_len + 1);
|
||||
memmove(line->data + primary_len, line->data, text_len + 1);
|
||||
strncpy(line->data, primary_lead, primary_len);
|
||||
}
|
||||
@@ -1997,11 +1996,11 @@ void do_justify(bool full_justify)
|
||||
/* Show what we justified on the status bar. */
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->mark)
|
||||
statusbar(_("Justified selection"));
|
||||
statusline(REMARK, _("Justified selection"));
|
||||
else
|
||||
#endif
|
||||
if (full_justify)
|
||||
statusbar(_("Justified file"));
|
||||
statusline(REMARK, _("Justified file"));
|
||||
else
|
||||
statusbar(_("Justified paragraph"));
|
||||
|
||||
@@ -2036,7 +2035,7 @@ void construct_argument_list(char ***arguments, char *command, char *filename)
|
||||
int count = 2;
|
||||
|
||||
while (element != NULL) {
|
||||
*arguments = (char **)nrealloc(*arguments, ++count * sizeof(char *));
|
||||
*arguments = nrealloc(*arguments, ++count * sizeof(char *));
|
||||
(*arguments)[count - 3] = element;
|
||||
element = strtok(NULL, " ");
|
||||
}
|
||||
@@ -2105,10 +2104,10 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
|
||||
if (fileinfo.st_size == 0) {
|
||||
#ifndef NANO_TINY
|
||||
if (spelling && openfile->mark)
|
||||
statusline(ALERT, _("Selection is empty"));
|
||||
statusline(AHEM, _("Selection is empty"));
|
||||
else
|
||||
#endif
|
||||
statusbar(_("Buffer is empty"));
|
||||
statusline(AHEM, _("Buffer is empty"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2143,18 +2142,22 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
|
||||
|
||||
if (thepid < 0) {
|
||||
statusline(ALERT, _("Could not fork: %s"), strerror(errornumber));
|
||||
free(arguments[0]);
|
||||
return;
|
||||
} else if (!WIFEXITED(program_status) || WEXITSTATUS(program_status) > 2) {
|
||||
statusline(ALERT, _("Error invoking '%s'"), arguments[0]);
|
||||
free(arguments[0]);
|
||||
return;
|
||||
} else if (WEXITSTATUS(program_status) != 0)
|
||||
statusline(ALERT, _("Program '%s' complained"), arguments[0]);
|
||||
|
||||
free(arguments[0]);
|
||||
|
||||
/* When the temporary file wasn't touched, say so and leave. */
|
||||
if (timestamp_sec > 0 && stat(tempfile_name, &fileinfo) == 0 &&
|
||||
(long)fileinfo.st_mtim.tv_sec == timestamp_sec &&
|
||||
(long)fileinfo.st_mtim.tv_nsec == timestamp_nsec) {
|
||||
statusbar(_("Nothing changed"));
|
||||
statusline(REMARK, _("Nothing changed"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2202,9 +2205,9 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
|
||||
adjust_viewport(STATIONARY);
|
||||
|
||||
if (spelling)
|
||||
statusbar(_("Finished checking spelling"));
|
||||
statusline(REMARK, _("Finished checking spelling"));
|
||||
else
|
||||
statusbar(_("Buffer has been processed"));
|
||||
statusline(REMARK, _("Buffer has been processed"));
|
||||
}
|
||||
#endif /* ENABLE_SPELLER || ENABLE_COLOR */
|
||||
|
||||
@@ -2212,27 +2215,17 @@ void treat(char *tempfile_name, char *theprogram, bool spelling)
|
||||
/* Let the user edit the misspelled word. Return FALSE if the user cancels. */
|
||||
bool fix_spello(const char *word)
|
||||
{
|
||||
char *save_search;
|
||||
size_t firstcolumn_save = openfile->firstcolumn;
|
||||
size_t current_x_save = openfile->current_x;
|
||||
linestruct *edittop_save = openfile->edittop;
|
||||
linestruct *current_save = openfile->current;
|
||||
/* Save where we are. */
|
||||
linestruct *was_edittop = openfile->edittop;
|
||||
linestruct *was_current = openfile->current;
|
||||
size_t was_firstcolumn = openfile->firstcolumn;
|
||||
size_t was_x = openfile->current_x;
|
||||
bool proceed = FALSE;
|
||||
/* The return value of this function. */
|
||||
bool result;
|
||||
/* The return value of searching for a misspelled word. */
|
||||
int result;
|
||||
#ifndef NANO_TINY
|
||||
bool right_side_up = (openfile->mark && mark_is_before_cursor());
|
||||
linestruct *top, *bot;
|
||||
size_t top_x, bot_x;
|
||||
bool right_side_up = (openfile->mark && mark_is_before_cursor());
|
||||
#endif
|
||||
|
||||
/* Save the current search string, then set it to the misspelled word. */
|
||||
save_search = last_search;
|
||||
last_search = copy_of(word);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If the mark is on, start at the beginning of the marked region. */
|
||||
if (openfile->mark) {
|
||||
get_region(&top, &top_x, &bot, &bot_x);
|
||||
@@ -2286,7 +2279,7 @@ bool fix_spello(const char *word)
|
||||
|
||||
/* If a replacement was given, go through all occurrences. */
|
||||
if (proceed && strcmp(word, answer) != 0) {
|
||||
do_replace_loop(word, TRUE, current_save, ¤t_x_save);
|
||||
do_replace_loop(word, TRUE, was_current, &was_x);
|
||||
|
||||
/* TRANSLATORS: Shown after fixing misspellings in one word. */
|
||||
statusbar(_("Next word..."));
|
||||
@@ -2310,17 +2303,13 @@ bool fix_spello(const char *word)
|
||||
#endif
|
||||
{
|
||||
/* Restore the (compensated) cursor position. */
|
||||
openfile->current = current_save;
|
||||
openfile->current_x = current_x_save;
|
||||
openfile->current = was_current;
|
||||
openfile->current_x = was_x;
|
||||
}
|
||||
|
||||
/* Restore the string that was last searched for. */
|
||||
free(last_search);
|
||||
last_search = save_search;
|
||||
|
||||
/* Restore the viewport to where it was. */
|
||||
openfile->edittop = edittop_save;
|
||||
openfile->firstcolumn = firstcolumn_save;
|
||||
openfile->edittop = was_edittop;
|
||||
openfile->firstcolumn = was_firstcolumn;
|
||||
|
||||
return proceed;
|
||||
}
|
||||
@@ -2353,11 +2342,11 @@ void do_int_speller(const char *tempfile_name)
|
||||
exit(6);
|
||||
|
||||
/* Connect standard input to the temporary file. */
|
||||
if (dup2(tempfile_fd, STDIN_FILENO) != STDIN_FILENO)
|
||||
if (dup2(tempfile_fd, STDIN_FILENO) < 0)
|
||||
exit(7);
|
||||
|
||||
/* Connect standard output to the write end of the first pipe. */
|
||||
if (dup2(spell_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
|
||||
if (dup2(spell_fd[1], STDOUT_FILENO) < 0)
|
||||
exit(8);
|
||||
|
||||
close(tempfile_fd);
|
||||
@@ -2378,11 +2367,11 @@ void do_int_speller(const char *tempfile_name)
|
||||
/* Fork a process to run sort in. */
|
||||
if ((pid_sort = fork()) == 0) {
|
||||
/* Connect standard input to the read end of the first pipe. */
|
||||
if (dup2(spell_fd[0], STDIN_FILENO) != STDIN_FILENO)
|
||||
if (dup2(spell_fd[0], STDIN_FILENO) < 0)
|
||||
exit(7);
|
||||
|
||||
/* Connect standard output to the write end of the second pipe. */
|
||||
if (dup2(sort_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
|
||||
if (dup2(sort_fd[1], STDOUT_FILENO) < 0)
|
||||
exit(8);
|
||||
|
||||
close(spell_fd[0]);
|
||||
@@ -2400,10 +2389,10 @@ void do_int_speller(const char *tempfile_name)
|
||||
|
||||
/* Fork a process to run uniq in. */
|
||||
if ((pid_uniq = fork()) == 0) {
|
||||
if (dup2(sort_fd[0], STDIN_FILENO) != STDIN_FILENO)
|
||||
if (dup2(sort_fd[0], STDIN_FILENO) < 0)
|
||||
exit(7);
|
||||
|
||||
if (dup2(uniq_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
|
||||
if (dup2(uniq_fd[1], STDOUT_FILENO) < 0)
|
||||
exit(8);
|
||||
|
||||
close(sort_fd[0]);
|
||||
@@ -2442,13 +2431,13 @@ void do_int_speller(const char *tempfile_name)
|
||||
|
||||
totalread = 0;
|
||||
buffersize = pipesize + 1;
|
||||
misspellings = charalloc(buffersize);
|
||||
misspellings = nmalloc(buffersize);
|
||||
pointer = misspellings;
|
||||
|
||||
while ((bytesread = read(uniq_fd[0], pointer, pipesize)) > 0) {
|
||||
totalread += bytesread;
|
||||
buffersize += pipesize;
|
||||
misspellings = charealloc(misspellings, buffersize);
|
||||
misspellings = nrealloc(misspellings, buffersize);
|
||||
pointer = misspellings + totalread;
|
||||
}
|
||||
|
||||
@@ -2503,7 +2492,7 @@ void do_int_speller(const char *tempfile_name)
|
||||
else if (WIFEXITED(spell_status) == 0 || WEXITSTATUS(spell_status))
|
||||
statusline(ALERT, _("Error invoking \"spell\""));
|
||||
else
|
||||
statusbar(_("Finished checking spelling"));
|
||||
statusline(REMARK, _("Finished checking spelling"));
|
||||
}
|
||||
|
||||
/* Spell check the current file. If an alternate spell checker is
|
||||
@@ -2548,7 +2537,7 @@ void do_spell(void)
|
||||
|
||||
blank_bottombars();
|
||||
|
||||
if (alt_speller)
|
||||
if (alt_speller && *alt_speller)
|
||||
treat(temp_name, alt_speller, TRUE);
|
||||
else
|
||||
do_int_speller(temp_name);
|
||||
@@ -2576,7 +2565,6 @@ void do_linter(void)
|
||||
int lint_status, lint_fd[2];
|
||||
pid_t pid_lint;
|
||||
bool helpless = ISSET(NO_HELP);
|
||||
static char **lintargs = NULL;
|
||||
lintstruct *lints = NULL, *tmplint = NULL, *curlint = NULL;
|
||||
time_t last_wait = 0;
|
||||
|
||||
@@ -2586,7 +2574,7 @@ void do_linter(void)
|
||||
return;
|
||||
|
||||
if (!openfile->syntax || !openfile->syntax->linter) {
|
||||
statusbar(_("No linter is defined for this type of file"));
|
||||
statusline(AHEM, _("No linter is defined for this type of file"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2615,19 +2603,21 @@ void do_linter(void)
|
||||
currmenu = MLINTER;
|
||||
statusbar(_("Invoking linter..."));
|
||||
|
||||
construct_argument_list(&lintargs, openfile->syntax->linter, openfile->filename);
|
||||
|
||||
/* Fork a process to run the linter in. */
|
||||
if ((pid_lint = fork()) == 0) {
|
||||
char **lintargs = NULL;
|
||||
|
||||
/* Redirect standard output and standard error into the pipe. */
|
||||
if (dup2(lint_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
|
||||
if (dup2(lint_fd[1], STDOUT_FILENO) < 0)
|
||||
exit(7);
|
||||
if (dup2(lint_fd[1], STDERR_FILENO) != STDERR_FILENO)
|
||||
if (dup2(lint_fd[1], STDERR_FILENO) < 0)
|
||||
exit(8);
|
||||
|
||||
close(lint_fd[0]);
|
||||
close(lint_fd[1]);
|
||||
|
||||
construct_argument_list(&lintargs, openfile->syntax->linter, openfile->filename);
|
||||
|
||||
/* Start the linter program; we are using $PATH. */
|
||||
execvp(lintargs[0], lintargs);
|
||||
|
||||
@@ -2657,13 +2647,13 @@ void do_linter(void)
|
||||
/* Read in the returned syntax errors. */
|
||||
totalread = 0;
|
||||
buffersize = pipesize + 1;
|
||||
lintings = charalloc(buffersize);
|
||||
lintings = nmalloc(buffersize);
|
||||
pointer = lintings;
|
||||
|
||||
while ((bytesread = read(lint_fd[0], pointer, pipesize)) > 0) {
|
||||
totalread += bytesread;
|
||||
buffersize += pipesize;
|
||||
lintings = charealloc(lintings, buffersize);
|
||||
lintings = nrealloc(lintings, buffersize);
|
||||
pointer = lintings + totalread;
|
||||
}
|
||||
|
||||
@@ -2746,7 +2736,7 @@ void do_linter(void)
|
||||
}
|
||||
|
||||
if (!parsesuccess) {
|
||||
statusline(HUSH, _("Got 0 parsable lines from command: %s"),
|
||||
statusline(REMARK, _("Got 0 parsable lines from command: %s"),
|
||||
openfile->syntax->linter);
|
||||
return;
|
||||
}
|
||||
@@ -2781,7 +2771,7 @@ void do_linter(void)
|
||||
|
||||
if (openfile->statinfo == NULL ||
|
||||
openfile->statinfo->st_ino != lintfileinfo.st_ino) {
|
||||
char *msg = charalloc(1024 + strlen(curlint->filename));
|
||||
char *msg = nmalloc(1024 + strlen(curlint->filename));
|
||||
int choice;
|
||||
|
||||
sprintf(msg, _("This message is for unopened file %s,"
|
||||
@@ -2823,7 +2813,7 @@ void do_linter(void)
|
||||
free(dontwantfile);
|
||||
|
||||
if (restlint == NULL) {
|
||||
statusbar(_("No messages for this file"));
|
||||
statusline(REMARK, _("No messages for this file"));
|
||||
break;
|
||||
} else {
|
||||
curlint = restlint;
|
||||
@@ -2836,7 +2826,10 @@ void do_linter(void)
|
||||
}
|
||||
|
||||
if (tmplint != curlint) {
|
||||
/* Put the cursor at the reported position, but don't go beyond EOL
|
||||
* when the second number is a column number instead of an index. */
|
||||
goto_line_posx(curlint->lineno, curlint->colno - 1);
|
||||
openfile->current_x = actual_x(openfile->current->data, openfile->placewewant);
|
||||
titlebar(NULL);
|
||||
adjust_viewport(CENTERING);
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
@@ -2904,6 +2897,7 @@ void do_linter(void)
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
lastmessage = VACUUM;
|
||||
currmenu = MMOST;
|
||||
titlebar(NULL);
|
||||
}
|
||||
@@ -2921,7 +2915,7 @@ void do_formatter(void)
|
||||
return;
|
||||
|
||||
if (!openfile->syntax || !openfile->syntax->formatter) {
|
||||
statusbar(_("No formatter is defined for this type of file"));
|
||||
statusline(AHEM, _("No formatter is defined for this type of file"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2997,9 +2991,12 @@ void do_wordlinechar_count(void)
|
||||
openfile->current = was_current;
|
||||
openfile->current_x = was_x;
|
||||
|
||||
/* Display the total word, line, and character counts on the status bar. */
|
||||
statusline(HUSH, _("%sWords: %zu Lines: %zd Chars: %zu"), openfile->mark ?
|
||||
_("In Selection: ") : "", words, lines, chars);
|
||||
/* Report on the status bar the number of lines, words, and characters. */
|
||||
statusline(INFO, _("%s%zd %s, %zu %s, %zu %s"),
|
||||
openfile->mark ? _("In Selection: ") : "",
|
||||
lines, P_("line", "lines", lines),
|
||||
words, P_("word", "words", words),
|
||||
chars, P_("character", "characters", chars));
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
@@ -3010,7 +3007,7 @@ void do_verbatim_input(void)
|
||||
char *bytes;
|
||||
|
||||
/* TRANSLATORS: Shown when the next keystroke will be inserted verbatim. */
|
||||
statusbar(_("Verbatim Input"));
|
||||
statusline(INFO, _("Verbatim Input"));
|
||||
place_the_cursor();
|
||||
|
||||
/* Read in the first one or two bytes of the next keystroke. */
|
||||
@@ -3019,7 +3016,7 @@ void do_verbatim_input(void)
|
||||
/* When something valid was obtained, unsuppress cursor-position display,
|
||||
* insert the bytes into the edit buffer, and blank the status bar. */
|
||||
if (count > 0) {
|
||||
if (ISSET(CONSTANT_SHOW))
|
||||
if (ISSET(CONSTANT_SHOW) || ISSET(MINIBAR))
|
||||
lastmessage = VACUUM;
|
||||
|
||||
if (count < 999)
|
||||
@@ -3028,7 +3025,7 @@ void do_verbatim_input(void)
|
||||
wipe_statusbar();
|
||||
} else
|
||||
/* TRANSLATORS: An invalid verbatim Unicode code was typed. */
|
||||
statusline(ALERT, _("Invalid code"));
|
||||
statusline(AHEM, _("Invalid code"));
|
||||
|
||||
free(bytes);
|
||||
}
|
||||
@@ -3045,7 +3042,7 @@ char *copy_completion(char *text)
|
||||
length = step_right(text, length);
|
||||
|
||||
/* Now copy this candidate to a new string. */
|
||||
word = charalloc(length + 1);
|
||||
word = nmalloc(length + 1);
|
||||
while (index < length)
|
||||
word[index++] = *(text++);
|
||||
word[index] = '\0';
|
||||
@@ -3104,12 +3101,12 @@ void complete_a_word(void)
|
||||
/* If there is no word fragment before the cursor, do nothing. */
|
||||
if (start_of_shard == openfile->current_x) {
|
||||
/* TRANSLATORS: Shown when no text is directly left of the cursor. */
|
||||
statusbar(_("No word fragment"));
|
||||
statusline(AHEM, _("No word fragment"));
|
||||
pletion_line = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
shard = charalloc(openfile->current_x - start_of_shard + 1);
|
||||
shard = nmalloc(openfile->current_x - start_of_shard + 1);
|
||||
|
||||
/* Copy the fragment that has to be searched for. */
|
||||
while (start_of_shard < openfile->current_x)
|
||||
@@ -3164,7 +3161,7 @@ void complete_a_word(void)
|
||||
}
|
||||
|
||||
/* Add the found word to the list of completions. */
|
||||
some_word = (completion_word *)nmalloc(sizeof(completion_word));
|
||||
some_word = nmalloc(sizeof(completion_word));
|
||||
some_word->word = completion;
|
||||
some_word->next = list_of_completions;
|
||||
list_of_completions = some_word;
|
||||
@@ -3196,11 +3193,11 @@ void complete_a_word(void)
|
||||
|
||||
/* The search has reached the end of the file. */
|
||||
if (list_of_completions != NULL) {
|
||||
statusline(ALERT, _("No further matches"));
|
||||
statusline(AHEM, _("No further matches"));
|
||||
refresh_needed = TRUE;
|
||||
} else
|
||||
/* TRANSLATORS: Shown when there are zero possible completions. */
|
||||
statusline(ALERT, _("No matches"));
|
||||
statusline(AHEM, _("No matches"));
|
||||
|
||||
free(shard);
|
||||
}
|
||||
|
||||
32
src/utils.c
32
src/utils.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* utils.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2020 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016, 2017, 2019 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -68,7 +68,7 @@ const char *tail(const char *path)
|
||||
char *concatenate(const char *path, const char *name)
|
||||
{
|
||||
size_t pathlen = strlen(path);
|
||||
char *joined = charalloc(pathlen + strlen(name) + 1);
|
||||
char *joined = nmalloc(pathlen + strlen(name) + 1);
|
||||
|
||||
strcpy(joined, path);
|
||||
strcpy(joined + pathlen, name);
|
||||
@@ -108,19 +108,19 @@ int digits(ssize_t n)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read an integer from str. If it parses okay, store it in *result
|
||||
* and return TRUE; otherwise, return FALSE. */
|
||||
bool parse_num(const char *str, ssize_t *result)
|
||||
/* Read an integer from the given string. If it parses okay,
|
||||
* store it in *result and return TRUE; otherwise, return FALSE. */
|
||||
bool parse_num(const char *string, ssize_t *result)
|
||||
{
|
||||
char *first_error;
|
||||
ssize_t value;
|
||||
char *excess;
|
||||
|
||||
/* The manual page for strtol() says this is required. */
|
||||
/* Clear the error number so that we can check it afterward. */
|
||||
errno = 0;
|
||||
|
||||
value = (ssize_t)strtol(str, &first_error, 10);
|
||||
value = (ssize_t)strtol(string, &excess, 10);
|
||||
|
||||
if (errno == ERANGE || *str == '\0' || *first_error != '\0')
|
||||
if (errno == ERANGE || *string == '\0' || *excess != '\0')
|
||||
return FALSE;
|
||||
|
||||
*result = value;
|
||||
@@ -294,7 +294,10 @@ void *nmalloc(size_t howmuch)
|
||||
{
|
||||
void *r = malloc(howmuch);
|
||||
|
||||
if (r == NULL && howmuch != 0)
|
||||
if (howmuch == 0)
|
||||
die("Allocating zero bytes. Please report a bug.\n");
|
||||
|
||||
if (r == NULL)
|
||||
die(_("Nano is out of memory!\n"));
|
||||
|
||||
return r;
|
||||
@@ -306,7 +309,10 @@ void *nrealloc(void *ptr, size_t howmuch)
|
||||
{
|
||||
void *r = realloc(ptr, howmuch);
|
||||
|
||||
if (r == NULL && howmuch != 0)
|
||||
if (howmuch == 0)
|
||||
die("Allocating zero bytes. Please report a bug.\n");
|
||||
|
||||
if (r == NULL)
|
||||
die(_("Nano is out of memory!\n"));
|
||||
|
||||
return r;
|
||||
@@ -318,7 +324,7 @@ char *mallocstrcpy(char *dest, const char *src)
|
||||
{
|
||||
size_t count = strlen(src) + 1;
|
||||
|
||||
dest = charealloc(dest, count);
|
||||
dest = nrealloc(dest, count);
|
||||
strncpy(dest, src, count);
|
||||
|
||||
return dest;
|
||||
@@ -328,7 +334,7 @@ char *mallocstrcpy(char *dest, const char *src)
|
||||
* of the given string, and NUL-terminate the copy. */
|
||||
char *measured_copy(const char *string, size_t count)
|
||||
{
|
||||
char *thecopy = charalloc(count + 1);
|
||||
char *thecopy = nmalloc(count + 1);
|
||||
|
||||
memcpy(thecopy, string, count);
|
||||
thecopy[count] = '\0';
|
||||
|
||||
690
src/winio.c
690
src/winio.c
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,8 @@
|
||||
## Syntax highlighting for Autoconf.
|
||||
|
||||
## Original author: Benno Schulenberg
|
||||
## License: GPL version 3 or newer
|
||||
|
||||
syntax autoconf "\.(ac|m4)$"
|
||||
comment "#"
|
||||
|
||||
|
||||
@@ -6,28 +6,34 @@ magic "^(C|C\+\+) (source|program)"
|
||||
comment "//"
|
||||
|
||||
# Constants.
|
||||
color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
||||
color brightred "\<[A-Z_][0-9A-Z_]*\>"
|
||||
# Labels.
|
||||
color brightmagenta "^[[:space:]]*[A-Z_a-z]+:[[:space:]]*$"
|
||||
|
||||
color green "\<(float|double|bool|char|int|short|long|sizeof|enum|void|auto|static|const|struct|union|typedef|extern|(un)?signed|inline)\>"
|
||||
# Types and related keywords.
|
||||
color green "\<(auto|bool|char|const|double|enum|extern|float|inline|int|long|restrict|short|signed|sizeof|static|struct|typedef|union|unsigned|void)\>"
|
||||
color green "\<([[:lower:]][[:lower:]_]*|(u_?)?int(8|16|32|64))_t\>"
|
||||
color green "\<(class|namespace|template|public|protected|private|typename|this|friend|virtual|override|using|mutable|volatile|register|explicit)\>"
|
||||
color brightyellow "\<(for|if|while|do|else|case|default|switch)\>"
|
||||
color green "\<(_(Alignas|Alignof|Atomic|Bool|Complex|Generic|Imaginary|Noreturn|Static_assert|Thread_local))\>"
|
||||
color green "\<(class|explicit|friend|mutable|namespace|override|private|protected|public|register|template|this|typename|using|virtual|volatile)\>"
|
||||
|
||||
# Flow control.
|
||||
color brightyellow "\<(if|else|for|while|do|switch|case|default)\>"
|
||||
color brightyellow "\<(try|throw|catch|operator|new|delete)\>"
|
||||
color magenta "\<(goto|continue|break|return)\>"
|
||||
color brightmagenta "'([^'\]|(\\["'abfnrtv\\]))'" "'\\(([0-3]?[0-7]{1,2}))'" "'\\x[0-9A-Fa-f]{1,2}'"
|
||||
color magenta "\<(break|continue|goto|return)\>"
|
||||
|
||||
# Single-quoted stuff (characters, backslash escapes, hex and octal byte codes).
|
||||
color brightmagenta "'([^'\]|\\(["'\abfnrtv]|x[0-9A-Fa-f]{1,2}|[0-3]?[0-7]{1,2}))'"
|
||||
|
||||
# GCC builtins.
|
||||
color cyan "__attribute__[[:space:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__"
|
||||
|
||||
# Strings. In general you will want your strings and comments to come last,
|
||||
# because highlighting rules are applied in the order they are read in.
|
||||
# Strings. (In general you will want your strings and comments to come last,
|
||||
# because highlighting rules are applied in the order they are read in.)
|
||||
color brightyellow ""([^"]|\\")*"" "#[[:space:]]*include[[:space:]]+<[^[:blank:]=]*>"
|
||||
|
||||
# Preprocessor directives.
|
||||
color brightcyan start="^[[:space:]]*#[[:space:]]*(if(n?def)?|elif|warning|error|pragma)\>" end="(\`|[^\\])$"
|
||||
color brightcyan "^[[:space:]]*#[[:space:]]*(define|else|endif|include(_next)?|undef)\>"
|
||||
color brightcyan "^[[:space:]]*#[[:space:]]*((define|else|endif|include(_next)?|line|undef)\>|$)"
|
||||
|
||||
# Comments.
|
||||
color brightblue "//.*"
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
## Syntax highlighting for Changelogs.
|
||||
|
||||
## Original author: Benno Schulenberg
|
||||
## License: GPL version 3 or newer
|
||||
|
||||
syntax changelog "Change[Ll]og[^/]*$"
|
||||
|
||||
# Author lines.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
## Syntax highlighting for Go.
|
||||
|
||||
## Original author: Robert Clausecker
|
||||
## License: CC0 (public domain)
|
||||
|
||||
syntax go "\.go$"
|
||||
comment "//"
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
## Syntax highlighting for Markdown files.
|
||||
|
||||
## Original authors: Ryan Westlund and Benno Schulenberg
|
||||
## License: GPL version 3 or newer
|
||||
|
||||
syntax markdown "\.md$"
|
||||
comment "<!--|-->"
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ comment "#"
|
||||
color brightred ".*"
|
||||
|
||||
# Keywords
|
||||
color brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|breaklonglines|casesensitive|constantshow|cutfromcursor|emptyline|finalnewline|historylog|indicator|jumpyscrolling|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rawsequences|rebinddelete|regexp|saveonexit|showcursor|smarthome|smooth|softwrap|suspendable|tabstospaces|trimblanks|unix|view|wordbounds|zap)\>"
|
||||
color yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|selected|status|stripe|title)color)[[:space:]]+(bold,)?(italic,)?(bright|light)?(white|black|red|blue|green|yellow|magenta|cyan|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte)?(,(light)?(white|black|red|blue|green|yellow|magenta|cyan|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte))?\>"
|
||||
color brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|stripecolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
color brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|boldtext|bookstyle|breaklonglines|casesensitive|constantshow|cutfromcursor|emptyline|historylog|indicator|jumpyscrolling|linenumbers|locking|magic|minibar|mouse|multibuffer|noconvert|nohelp|nonewlines|positionlog|preserve|quickblank|rawsequences|rebinddelete|regexp|saveonexit|showcursor|smarthome|softwrap|stateflags|suspendable|tabstospaces|trimblanks|unix|wordbounds|zap)\>"
|
||||
color yellow "^[[:space:]]*set[[:space:]]+((error|function|highlight|key|number|prompt|scroller|selected|status|stripe|title)color)[[:space:]]+(bold,)?(italic,)?(bright|light)?(white|black|red|blue|green|yellow|magenta|cyan|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte)?(,(light)?(white|black|red|blue|green|yellow|magenta|cyan|normal|pink|purple|mauve|lagoon|mint|lime|peach|orange|latte))?\>"
|
||||
color brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|highlightcolor|keycolor|matchbrackets|numbercolor|operatingdir|promptcolor|punct|quotestr|scrollercolor|selectedcolor|speller|statuscolor|stripecolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
color brightgreen "^[[:space:]]*set[[:space:]]+(fill[[:space:]]+-?[[:digit:]]+|(guidestripe|tabsize)[[:space:]]+[1-9][0-9]*)\>"
|
||||
color brightgreen "^[[:space:]]*bind[[:space:]]+((\^([A-Za-z]|[]/@\^_`]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([][!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+([a-z]+|".*")[[:space:]]+(main|help|search|replace(with)?|yesno|gotoline|writeout|insert|browser|whereisfile|gotodir|execute|spell|linter|all)([[:space:]]+#|[[:space:]]*$)"
|
||||
color brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([A-Za-z]|[]/@\^_`]|Space)|([Ss][Hh]-)?[Mm]-[A-Za-z]|[Mm]-([][!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
## Syntax highlighting for the packet-filtering rules of Netfilter.
|
||||
|
||||
## Original author: Arturo Borrero González <arturo@debian.org>
|
||||
## License: GPL version 3 or newer
|
||||
|
||||
syntax nftables "\.(nft|nftables)$"
|
||||
header "^#!.*(nft|nftables)"
|
||||
comment "#"
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
## Syntax highlighting for PO files.
|
||||
|
||||
## Original author: Benno Schulenberg
|
||||
## License: GPL version 3 or newer
|
||||
|
||||
syntax po "\.pot?$"
|
||||
comment "#"
|
||||
|
||||
@@ -27,3 +30,7 @@ color cyan "\\([abcefnrtv"\]|x[0-9abcdefABCDEF]{2}|[0-7]{3})"
|
||||
color brightwhite,yellow "\<(FIXME|TODO|XXX)\>"
|
||||
# Obsolete strings.
|
||||
color red "#~.*"
|
||||
# Stray control codes.
|
||||
color bold,pink,red "[[:cntrl:]]"
|
||||
# Tabs.
|
||||
color mint "[[:blank:]]"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
## Syntax highlighting for Bourne shell scripts.
|
||||
|
||||
syntax sh "(\.sh|(\.|/)(a|ba|c|da|k|mk|pdk|tc|z)sh(rc|_profile)?|/(etc/|\.)profile)$"
|
||||
header "^#!.*/(((a|ba|c|da|k|mk|pdk|tc|z)?sh)|(busybox|env) +sh|openrc-run|runscript)"
|
||||
header "^#!.*/((env\s+)?((a|ba|c|da|k|mk|pdk|tc|z)?sh)|busybox\s+sh|openrc-run|runscript)\>"
|
||||
header "-\*-.*shell-script.*-\*-"
|
||||
magic "(POSIX|Bourne-Again) shell script.*text"
|
||||
comment "#"
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
## Syntax highlighting for Texinfo files.
|
||||
|
||||
## Original author: Benno Schulenberg
|
||||
## License: GPL version 3 or newer
|
||||
|
||||
syntax texinfo "\.texi$"
|
||||
header "^\\input texinfo"
|
||||
magic "Texinfo source"
|
||||
|
||||
Reference in New Issue
Block a user