Compare commits
355 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8987a1e40 | ||
|
|
895d2b8e9c | ||
|
|
47068c3770 | ||
|
|
345cf5accc | ||
|
|
c7ca60b046 | ||
|
|
01e4f85f29 | ||
|
|
6bfbb2bcd9 | ||
|
|
d82c753ba4 | ||
|
|
0af9ce926b | ||
|
|
4e14a8a977 | ||
|
|
accd17c249 | ||
|
|
e8eb30cad6 | ||
|
|
36bd68f3ab | ||
|
|
03692363a2 | ||
|
|
0e94575c6b | ||
|
|
27cc3117e2 | ||
|
|
19f71632c8 | ||
|
|
e3f18e7a6c | ||
|
|
b55923f5ec | ||
|
|
7028adf211 | ||
|
|
d7df7c694a | ||
|
|
ce69d5be88 | ||
|
|
3da4240229 | ||
|
|
43caf7bb7b | ||
|
|
e8e30e5197 | ||
|
|
189de5ee78 | ||
|
|
c57d040e99 | ||
|
|
0adb15c7a1 | ||
|
|
1e48df388e | ||
|
|
d477775871 | ||
|
|
ed40fd8031 | ||
|
|
5c4b0b38f4 | ||
|
|
bd331b0198 | ||
|
|
cd09482231 | ||
|
|
c5955d14ce | ||
|
|
7d38379919 | ||
|
|
45bf18f8fe | ||
|
|
787dca6724 | ||
|
|
15e36956b5 | ||
|
|
967f581860 | ||
|
|
1075de1222 | ||
|
|
3457039cee | ||
|
|
ca77254968 | ||
|
|
710a600f22 | ||
|
|
843eef65b8 | ||
|
|
781c7a7a5f | ||
|
|
aa205f58ca | ||
|
|
3bf04afa6d | ||
|
|
71236e145d | ||
|
|
7be76af418 | ||
|
|
fb17929fab | ||
|
|
fea1901592 | ||
|
|
33fea90bcd | ||
|
|
f03c87c300 | ||
|
|
45b1a38b82 | ||
|
|
c3bf17a801 | ||
|
|
8582e4a6b9 | ||
|
|
9b34d0a4fb | ||
|
|
26d16ab9d1 | ||
|
|
6ca8518428 | ||
|
|
f2c61c4b9a | ||
|
|
c4e04eb682 | ||
|
|
0b257fe558 | ||
|
|
941637615b | ||
|
|
378aa8bc41 | ||
|
|
157098ee75 | ||
|
|
8d4e171d3c | ||
|
|
6f1e5912a9 | ||
|
|
28a6d9f300 | ||
|
|
f92606491c | ||
|
|
260588af1e | ||
|
|
cdc9482d8f | ||
|
|
7c1b649eb8 | ||
|
|
57b3f83cfe | ||
|
|
edbdcb9b9a | ||
|
|
a6978b54f1 | ||
|
|
8bc2d18fa9 | ||
|
|
fb10a94f35 | ||
|
|
9b30bb15cc | ||
|
|
a1669e1bfd | ||
|
|
3d6eca3f26 | ||
|
|
c025a60ce9 | ||
|
|
5e1f90d8fa | ||
|
|
7f3ffe8544 | ||
|
|
ea1016efdb | ||
|
|
f63fee79e3 | ||
|
|
2003413989 | ||
|
|
9369af77ce | ||
|
|
35d2bc6b38 | ||
|
|
b52d166afa | ||
|
|
3952dcb629 | ||
|
|
7e9dd385f5 | ||
|
|
2e81023553 | ||
|
|
b9f994b2c0 | ||
|
|
e98847200e | ||
|
|
a77b21388a | ||
|
|
58ca5fb0f3 | ||
|
|
844214b4a0 | ||
|
|
f9dfca7d5a | ||
|
|
fe40e8867d | ||
|
|
923a90cba0 | ||
|
|
5817e83e33 | ||
|
|
122cabd3ba | ||
|
|
c5d157dd9d | ||
|
|
3a65c0d192 | ||
|
|
e1c011c9a1 | ||
|
|
477ff49f66 | ||
|
|
85eb9b9a53 | ||
|
|
484523b3bb | ||
|
|
5a48edc9ae | ||
|
|
6dc8570d55 | ||
|
|
7e422402d5 | ||
|
|
5f03c20ea0 | ||
|
|
71574e7a6f | ||
|
|
821445d284 | ||
|
|
3eab405e7b | ||
|
|
423ed031b4 | ||
|
|
57390cff04 | ||
|
|
4e637cd1c7 | ||
|
|
add1159675 | ||
|
|
dbdf38cce5 | ||
|
|
47770bd321 | ||
|
|
d656b0d3b9 | ||
|
|
d9deaf9f2f | ||
|
|
b75563b88e | ||
|
|
33e1bf1435 | ||
|
|
d946f38a2b | ||
|
|
b53dffaeed | ||
|
|
6dcfcd11ce | ||
|
|
f21b094dad | ||
|
|
a521ac4ae7 | ||
|
|
d972c17050 | ||
|
|
f6e182ca72 | ||
|
|
6a83bb7508 | ||
|
|
728498fde5 | ||
|
|
05f34bbfaf | ||
|
|
b7e2da7434 | ||
|
|
8e2d03b92c | ||
|
|
308a094d8d | ||
|
|
5757aa8a0c | ||
|
|
8c5b67379f | ||
|
|
b2926eb675 | ||
|
|
ea11709564 | ||
|
|
8550c6bd93 | ||
|
|
65560a583c | ||
|
|
35a791dee5 | ||
|
|
98ffb19746 | ||
|
|
93edd12099 | ||
|
|
9a475bf2d3 | ||
|
|
b512e253b6 | ||
|
|
137c4467ef | ||
|
|
4cacb626a0 | ||
|
|
e3e81879b1 | ||
|
|
acd23551c3 | ||
|
|
2f1691079e | ||
|
|
12bf3bfce4 | ||
|
|
d7555d071f | ||
|
|
9596f7de9d | ||
|
|
20635b40f4 | ||
|
|
1128a40d42 | ||
|
|
1e2e6733df | ||
|
|
2669d3623d | ||
|
|
22fc16b2d0 | ||
|
|
372e858ec8 | ||
|
|
da8c74a44f | ||
|
|
cba9d8d05e | ||
|
|
0e29c2a24a | ||
|
|
9e182722cc | ||
|
|
4f1eb5fdd4 | ||
|
|
53352d0b26 | ||
|
|
1d3a4df3b3 | ||
|
|
afbaf8ae2d | ||
|
|
1b2018e921 | ||
|
|
26642a39c3 | ||
|
|
8723375443 | ||
|
|
82aea04c79 | ||
|
|
341601e1a2 | ||
|
|
368f1a1c9d | ||
|
|
527c6c1ca0 | ||
|
|
a9e8f88e77 | ||
|
|
0cbf1f4027 | ||
|
|
96baa70cc8 | ||
|
|
b18e2129ce | ||
|
|
e26cbdd6cd | ||
|
|
0ebfd54e17 | ||
|
|
8f1cd50f1e | ||
|
|
4fb9f298c9 | ||
|
|
c338d86843 | ||
|
|
247dd8f052 | ||
|
|
71d0847b19 | ||
|
|
c55d144748 | ||
|
|
da91a44f9e | ||
|
|
02d3a2c0fb | ||
|
|
5764619655 | ||
|
|
3c959fd038 | ||
|
|
f0bc94fd02 | ||
|
|
8720cfcce9 | ||
|
|
954c4d03ac | ||
|
|
edf6995be4 | ||
|
|
b50d5758ef | ||
|
|
6c4d0d87f0 | ||
|
|
a962bceca6 | ||
|
|
e0c5c589ad | ||
|
|
dfe87540c6 | ||
|
|
6c4f228f6f | ||
|
|
fe06ae5f48 | ||
|
|
07289f437f | ||
|
|
99d155d80f | ||
|
|
3346c5395e | ||
|
|
083218aca5 | ||
|
|
fd3b3bc1d6 | ||
|
|
9bc6bc83c0 | ||
|
|
d4468b2def | ||
|
|
404a6862cd | ||
|
|
85fc41470b | ||
|
|
2b9dd6c574 | ||
|
|
9e44a53be7 | ||
|
|
0c561f0325 | ||
|
|
e5831f81bb | ||
|
|
fa21986ecf | ||
|
|
772137cabe | ||
|
|
4c53e2f56b | ||
|
|
14140d5249 | ||
|
|
17aa9371b5 | ||
|
|
208995e4a7 | ||
|
|
b503670750 | ||
|
|
7c08e8ea69 | ||
|
|
542426f1f1 | ||
|
|
6319a86178 | ||
|
|
9888e67b20 | ||
|
|
8fe19e344f | ||
|
|
896cfcef95 | ||
|
|
d54180ad8b | ||
|
|
065afe6e0f | ||
|
|
37eccd3117 | ||
|
|
b9dd572a67 | ||
|
|
3fe17e0355 | ||
|
|
6e3a3964ce | ||
|
|
18eb7e6d21 | ||
|
|
e84a790b5d | ||
|
|
20d9070aa1 | ||
|
|
482b2814b4 | ||
|
|
e92c3110a1 | ||
|
|
1ca9241eaa | ||
|
|
0b6889cbd8 | ||
|
|
00410d83fc | ||
|
|
fcad442d80 | ||
|
|
34d22d3f00 | ||
|
|
1326af7eae | ||
|
|
11aa191bdc | ||
|
|
ea844d28fe | ||
|
|
7668bfe6f2 | ||
|
|
493f215513 | ||
|
|
723451a5ce | ||
|
|
326e41d799 | ||
|
|
3ce74eb8fe | ||
|
|
ec4883b6a9 | ||
|
|
e8f69e40d1 | ||
|
|
297fb013cb | ||
|
|
4e52c75568 | ||
|
|
192a303e40 | ||
|
|
dcec8a4112 | ||
|
|
5316f5078f | ||
|
|
286c877853 | ||
|
|
8613285321 | ||
|
|
8a4639cdd6 | ||
|
|
576c20c4e4 | ||
|
|
3a0a6b5db8 | ||
|
|
c039aaad9d | ||
|
|
145bb6e01a | ||
|
|
9cc70d2069 | ||
|
|
3604ad2950 | ||
|
|
1fe3e2ed69 | ||
|
|
baca8bb19e | ||
|
|
1c707d4f99 | ||
|
|
c0e3779453 | ||
|
|
bf6bcde078 | ||
|
|
167a8e5c09 | ||
|
|
90cbdbbe75 | ||
|
|
d83a8eb359 | ||
|
|
98cc39e8e5 | ||
|
|
b20fadd604 | ||
|
|
cdf0f8e68a | ||
|
|
f645009a5e | ||
|
|
2b2736d41a | ||
|
|
5a6029a938 | ||
|
|
8d272db4e6 | ||
|
|
70885d0f9a | ||
|
|
f1e5da6cdd | ||
|
|
d79b9823ae | ||
|
|
82f1ce8ebf | ||
|
|
50ee655f9d | ||
|
|
5459f56f6d | ||
|
|
209531a761 | ||
|
|
2552307064 | ||
|
|
5601b9a66b | ||
|
|
81dcb13783 | ||
|
|
580fd13424 | ||
|
|
790ce3791a | ||
|
|
97cd62a8fb | ||
|
|
2f68bbb5e8 | ||
|
|
55952c0984 | ||
|
|
d9cfdd364b | ||
|
|
c9605e7308 | ||
|
|
c3f97bc9b7 | ||
|
|
4399b734db | ||
|
|
b9581bd50a | ||
|
|
408f15954e | ||
|
|
f585403b36 | ||
|
|
601973ddc2 | ||
|
|
25a5fb8231 | ||
|
|
897e557ce3 | ||
|
|
81bee1f5fd | ||
|
|
691eb1145c | ||
|
|
fb04dff6d7 | ||
|
|
c224ea3ce7 | ||
|
|
2a2fe7208a | ||
|
|
3f9d8011b9 | ||
|
|
4788c5f97d | ||
|
|
a5869ba450 | ||
|
|
7bc324f276 | ||
|
|
8d40b568fa | ||
|
|
0c0afb0039 | ||
|
|
2281ec9a31 | ||
|
|
cd0917fe10 | ||
|
|
1a1519b6cd | ||
|
|
947ccbb597 | ||
|
|
671db5e1e3 | ||
|
|
acfee2538e | ||
|
|
32431cddf8 | ||
|
|
8e302738e8 | ||
|
|
aa2568858e | ||
|
|
5375403b9d | ||
|
|
b0c9809a2e | ||
|
|
19c82e6a43 | ||
|
|
84d21b0972 | ||
|
|
f8e0320722 | ||
|
|
e5a8c35104 | ||
|
|
7ad232d714 | ||
|
|
85804ec70d | ||
|
|
e473ba5e6c | ||
|
|
9120a62cdd | ||
|
|
53ecb3225f | ||
|
|
3f695b8fb7 | ||
|
|
55699dc171 | ||
|
|
fa48d523b2 | ||
|
|
92cbc7c426 | ||
|
|
6f07f2b444 | ||
|
|
f58869d072 | ||
|
|
978c121de1 | ||
|
|
f6a7983a8a | ||
|
|
a1375474d9 | ||
|
|
d0cc75f197 | ||
|
|
0fccfc0373 | ||
|
|
d0a7e6e6a6 |
7
AUTHORS
7
AUTHORS
@@ -14,7 +14,9 @@ David Lawrence Ramsey <pooka109@gmail.com>
|
||||
* Former stable series maintainer. Multiple buffer support,
|
||||
operating dir (-o) option, bug fixes for display routines,
|
||||
wrapping code, spelling fixes, constantshow mode, parts of
|
||||
UTF-8 support, softwrap overhaul, and various other fixes.
|
||||
UTF-8 support, softwrap overhaul, undoable (un)indentations,
|
||||
undoable justifications, justifiable regions, and numerous
|
||||
other fixes.
|
||||
|
||||
Jordi Mallach <jordi@gnu.org>
|
||||
* Debian package maintainer, fellow bug squasher.
|
||||
@@ -67,3 +69,6 @@ Rishabh Dave <rishabhddave@gmail.com>
|
||||
|
||||
Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
|
||||
* Filtering text through an external command.
|
||||
|
||||
Brand Huntsman <alpha@qzx.com>
|
||||
* The delayed parsing of syntax files.
|
||||
|
||||
378
ChangeLog
378
ChangeLog
@@ -1,3 +1,381 @@
|
||||
Changes between v4.2 and v4.3:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (235):
|
||||
bindings: at a Yes-No prompt, accept also ^N and ^Q for "No"
|
||||
bindings: at a Yes-No prompt, accept also ^Y for "Yes"
|
||||
bindings: bind the Alt+arrow keystrokes also in non-UTF-8 locales
|
||||
browser: don't show a mistaken message when exiting from help viewer
|
||||
build: avoid a warning on FreeBSD, OpenBSD, and Alpine
|
||||
build: avoid a warning when using --disable-utf8
|
||||
build: exclude the ability to open a FIFO from the tiny version
|
||||
build: fix compilation on another system
|
||||
build: fix compilation when configured with --disable-color
|
||||
build: fix compilation when configured with --enable-tiny
|
||||
build: move an #include to where it is needed
|
||||
build: remove two #includes that don't seem to be needed
|
||||
bump version numbers and add a news item for the 4.3 release
|
||||
chars: create a dedicated function for getting the length of a character
|
||||
chars: redo the speedup for plain ASCII from three commits ago
|
||||
chars: speed up case-insensitive searching by roughly one percent
|
||||
chars: speed up the determination of length and width for plain ASCII
|
||||
copying: let a copy command break a chain of cut or zap commands
|
||||
copying: make M-6 do nothing when at end of buffer
|
||||
copying: scroll just one line when M-6 is pressed on the bottom row
|
||||
cutting: clear the cutbuffer when the previous operation was copying
|
||||
cutting: ignore the mark when a word is deleted
|
||||
display: properly show all characters in a non-UTF-8 build
|
||||
docs: add a light warning to the explanation of --nonewlines
|
||||
docs: adjust the wording of the README to be factually correct
|
||||
docs: clarify that in nano regexes are extended regular expressions
|
||||
docs: mention the default value for 'errorcolor'
|
||||
docs: note Brand as the author of the delayed syntax parsing
|
||||
docs: note David as author of undoable indenting and undoable justifying
|
||||
docs: remove "--" from the default value of 'quotestr'
|
||||
docs: say thanks to the Korean translator, and trim a double space
|
||||
docs: show double quotes where they are needed
|
||||
docs: slightly reword the notice about the changed defaults since 4.0
|
||||
feedback: don't clear off possible error messages after a spell check
|
||||
feedback: don't try to represent keys outside of the seven-bit range
|
||||
feedback: make an error check work also when curses hasn't started yet
|
||||
feedback: print helpful message only when data comes from keyboard
|
||||
feedback: show a more fitting message when opening a FIFO is interrupted
|
||||
feedback: show an appropriate message when reading a file was cut short
|
||||
feedback: treat statusline() being called outside of curses mode as a bug
|
||||
feedback: when the last line is empty, don't include it in the count
|
||||
files: allow a given file to be a special file but not a directory
|
||||
files: allow to abort the reading of slow files with Ctrl+C
|
||||
files: allow to interrupt the opening of a FIFO for writing with Ctrl+C
|
||||
files: allow to interrupt the opening of a FIFO with Ctrl+C
|
||||
files: check for writability by the access bits, not by trying to append
|
||||
files: don't close a newly-created buffer when it is the only one
|
||||
files: don't save the state of the terminal a second time
|
||||
files: don't say "Error...: Success" when aborting after resizing
|
||||
files: give feedback while waiting for a FIFO to open up
|
||||
files: suppress feedback when writing an emergency or temporary file
|
||||
files: try matching a syntax after scooping data from standard input
|
||||
files: when needed, reconnect the keyboard and reenter curses mode
|
||||
gnulib: update to its current upstream state
|
||||
help: don't check for confinement when opening a temporary help-text file
|
||||
help: don't cycle through the buffers for every resizing step
|
||||
help: don't show Alt+Left and Alt+Right when running on a Linux console
|
||||
help: make the column for the first keystroke a little wider
|
||||
help: write the text directly into a new buffer, without using a tempfile
|
||||
justify: remove "--" from the quoting regex, to avoid false paragraphs
|
||||
oops: apparently the line numbers in the cutbuffer do matter
|
||||
rcfile: at terminating points, verify that a defined syntax is not empty
|
||||
rcfile: check for missing color commands only when a syntax is still open
|
||||
rcfile: close off a syntax when a non-syntax command is encountered
|
||||
rcfile: disallow extending a syntax that is defined in a main nanorc
|
||||
rcfile: fully read each included file, so all its syntaxes are seen
|
||||
search: stay in the Search menu when trying to Replace in view mode
|
||||
softwrap: use smooth scrolling when softwrapping is toggled on
|
||||
speller: be more concise and to the point when something goes wrong
|
||||
speller: don't crash when the spell-checked tempfile cannot be opened
|
||||
speller: ensure that a Shift-selected region is retained
|
||||
speller: when something goes wrong with 'sort', do not blame 'spell'
|
||||
startup: remove the now-unneeded workaround for a SIGWINCH during input
|
||||
startup: resave the terminal's state only when there were no signals
|
||||
syntax: po: colorize also escaped hex and octal codes
|
||||
syntax: python: avoid miscoloring stuff between two empty strings
|
||||
tweaks: add a missing forward declaration of make_new_buffer()
|
||||
tweaks: add a pair of braces, to silence a compiler warning
|
||||
tweaks: add a warning for something that shouldn't occur
|
||||
tweaks: adjust a comment and drop two others, and reshuffle two lines
|
||||
tweaks: adjust some indentation after the previous change
|
||||
tweaks: adjust some whitespace and rewrap a few lines
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: avoid an unneeded, extra stat() for temporary files
|
||||
tweaks: avoid parsing a character twice
|
||||
tweaks: be more sparing in redrawing things when exiting from help viewer
|
||||
tweaks: change a function to void, to make things more direct
|
||||
tweaks: check in a single place for files that should not be opened
|
||||
tweaks: close a buffer differently and elide a parameter
|
||||
tweaks: condense a comment and reshuffle a couple of lines
|
||||
tweaks: condense a couple of comments, and reshuffle a line
|
||||
tweaks: condense the setup of the two signal handlers for Ctrl+C
|
||||
tweaks: condense two comments, and normalize the whitespace of a label
|
||||
tweaks: consistently report failures to fork (and the like) as errors
|
||||
tweaks: delete a leftover
|
||||
tweaks: delete a now-unused function
|
||||
tweaks: delete a now-unused function
|
||||
tweaks: don't bother calling mblen() in a non-UTF-8 build
|
||||
tweaks: don't bother checking the return value of wait()
|
||||
tweaks: don't bother keeping track of whether a squeezed line has shrunk
|
||||
tweaks: don't bother renumbering the lines in the cutbuffer
|
||||
tweaks: don't bother saving and restoring 'cutbottom' all the time
|
||||
tweaks: don't bother to free the content of 'extendsyntax' commands
|
||||
tweaks: don't check the user's nanorc file for accessibility twice
|
||||
tweaks: drop an unneeded parameter from open_file()
|
||||
tweaks: drop a useless tidying-up call, as spelling does not use regexes
|
||||
tweaks: drop most of the remaining debugging code, and some timing code
|
||||
tweaks: drop some checks that were made redundant by the previous commit
|
||||
tweaks: drop two checks that were made redundant by the previous commit
|
||||
tweaks: elide a function that is an amalgam of three others
|
||||
tweaks: elide a function that is called in just one place
|
||||
tweaks: elide a function that is used just once
|
||||
tweaks: elide another parameter, and rename the function to match
|
||||
tweaks: elide an unneeded, duplicate stat() for the FIFO check
|
||||
tweaks: elide an unneeded 'if' and 'break'
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: elide a parameter and a return value
|
||||
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: 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
|
||||
tweaks: factor out the installing and restoring of the ^C signal handler
|
||||
tweaks: improve a couple of comments
|
||||
tweaks: improve a handful of comments
|
||||
tweaks: improve some comments, reshuffle a line, and rename a variable
|
||||
tweaks: include the enabling of SIGINT into the tiny version
|
||||
tweaks: invert a condition, in order to return earlier
|
||||
tweaks: invert two conditions, in order to elide an extra variable
|
||||
tweaks: just mark four rcfile errors for translation, like the others
|
||||
tweaks: make better use of two variables, and reshuffle two comments
|
||||
tweaks: merge two functions, as the first is called just once
|
||||
tweaks: merge two functions, as the one is used only by the other
|
||||
tweaks: merge two very similar functions into a single one
|
||||
tweaks: move a bit of timing code to where it will be needed
|
||||
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: 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
|
||||
tweaks: really don't bother renumbering the lines in the cutbuffer
|
||||
tweaks: reduce a bit of mark-adjusting code to its essence
|
||||
tweaks: reduce the scope of a variable, and let the compiler zero it
|
||||
tweaks: remove a bit of redundant code
|
||||
tweaks: remove a check that is no longer relevant
|
||||
tweaks: remove a condition that has become superfluous
|
||||
tweaks: remove an unneeded "closing" of a syntax after extending it
|
||||
tweaks: remove an unneeded setting and unsetting of a flag
|
||||
tweaks: remove a superfluous and ineffective assignment
|
||||
tweaks: remove a superfluous condition, in three places
|
||||
tweaks: remove four unneeded pre-processor directives
|
||||
tweaks: remove some unneeded braces, and reshuffle for more symmetry
|
||||
tweaks: remove the two remaining handfuls of asserts
|
||||
tweaks: remove two more unneeded assignments
|
||||
tweaks: remove two unneeded assignments, and improve a comment
|
||||
tweaks: remove two unneeded checks for NULL
|
||||
tweaks: rename a bunch of variables, to become identical to others
|
||||
tweaks: rename a function and a variable, for contrast and variety
|
||||
tweaks: rename a function and its parameters, to be more fitting
|
||||
tweaks: rename a function, to be clearer and to stop using an old abbrev
|
||||
tweaks: rename a function, to be more fitting
|
||||
tweaks: rename a function, to better indicate what it does
|
||||
tweaks: rename a function, to better suit what it does
|
||||
tweaks: rename a parameter and a variable, to be more distinct
|
||||
tweaks: rename a struct element, to be distinct
|
||||
tweaks: rename a type, for more contrast
|
||||
tweaks: rename a type, to make more sense
|
||||
tweaks: rename a variable, reduce its scope, and use it consistently
|
||||
tweaks: rename a variable, reshuffle declarations, and drop an assert
|
||||
tweaks: rename a variable, to be shorter
|
||||
tweaks: rename a variable, to better indicate it contains two characters
|
||||
tweaks: rename a variable, to better suit its counterpart
|
||||
tweaks: rename a variable, to fit a bit better
|
||||
tweaks: rename a variable, to fit a little better
|
||||
tweaks: rename a variable, to get out of the way of the next commit
|
||||
tweaks: rename a variable, to match another with the same meaning
|
||||
tweaks: rename a variable, to match the style of its brothers
|
||||
tweaks: rename four elements of the holder struct, for more contrast
|
||||
tweaks: rename some single-letter variables to the same significant word
|
||||
tweaks: rename three variables, to get rid of a suffix or an underscore
|
||||
tweaks: rename three variables, to use full words instead of abbrevs
|
||||
tweaks: rename two functions, to be simpler
|
||||
tweaks: rename two functions, to better describe what they do
|
||||
tweaks: rename two functions, to get rid of the "mb" abbreviation
|
||||
tweaks: rename two more functions, to be simpler too
|
||||
tweaks: rename two parameters, away from single letters
|
||||
tweaks: rename two parameters, for more contrast, and elide another
|
||||
tweaks: rename two parameters, to differentiate them from function names
|
||||
tweaks: rename two variables, and frob some comments
|
||||
tweaks: rename two variables, and reshuffle their declarations
|
||||
tweaks: rename two variables, away from a single letter
|
||||
tweaks: rename two variables, for more contrast
|
||||
tweaks: rename two variables, for more contrast with the partition stuff
|
||||
tweaks: rename two variables, to be less cryptic
|
||||
tweaks: rename two variables, to be unique
|
||||
tweaks: rename two variables, to not be abbreviations
|
||||
tweaks: reorder some code, to further optimize display_string() for ASCII
|
||||
tweaks: reshuffle a bit of code, to be less intertwined
|
||||
tweaks: reshuffle a couple of lines and adjust a few comments
|
||||
tweaks: reshuffle a few lines, to be more straightforward
|
||||
tweaks: reshuffle a few things, partly to make two chunks more alike
|
||||
tweaks: reshuffle an assignment, to be able to return earlier
|
||||
tweaks: reshuffle some closing and switching to a better place
|
||||
tweaks: reshuffle some code to the one place that needs it
|
||||
tweaks: reshuffle some lines and frob some comments
|
||||
tweaks: reshuffle some lines, to group things more sensibly
|
||||
tweaks: reshuffle some lines, to put the most likely candidate first
|
||||
tweaks: reshuffle some lines, to reduce duplication
|
||||
tweaks: reshuffle two #ifdefs, to avoid an unpaired brace
|
||||
tweaks: reuse the install and restore functions for a signal handler
|
||||
tweaks: set a boolean directly, instead of using a function call
|
||||
tweaks: set a boolean directly, instead of using a function call
|
||||
tweaks: sort three translator names better
|
||||
tweaks: specifically refer to the manual of GNU grep for more regex info
|
||||
tweaks: speed up the counting of characters in mbstrlen()
|
||||
tweaks: squeeze excess spaces out of a line in situ
|
||||
tweaks: step away one character from the current bracket, not one byte
|
||||
tweaks: stop allocating and freeing a holder struct for every cut/paste
|
||||
tweaks: stop checking for a NULL result from line_from_number()
|
||||
tweaks: stop passing 'cutbuffer' and 'cutbottom' back and forth
|
||||
tweaks: switch to the preceding buffer in a cheaper way (when in help)
|
||||
tweaks: use a cheaper way to switch between buffers where possible
|
||||
tweaks: use a more direct call when a single linestruct is deleted
|
||||
tweaks: use a slightly faster function where appropriate
|
||||
tweaks: use a symbol instead of zero to refer to standard input
|
||||
tweaks: use FALSE for booleans instead of zero
|
||||
tweaks: when OR'ing, put the most likely condition first
|
||||
usage: make the --help output independent from the terminal's tab size
|
||||
zapping: disjoin a zap command from earlier ones when the mark is set
|
||||
zapping: use the 'keep_cutbuffer' logic to keep undo items apart
|
||||
|
||||
Brand Huntsman (6):
|
||||
files: block SIGWINCH while opening a FIFO for reading or writing
|
||||
rcfile: compile the color regexes just once
|
||||
rcfile: fully parse a syntax file only when needed
|
||||
rcfile: store errors and display them when nano terminates
|
||||
startup: prevent a crash when no applicable syntax is found
|
||||
tweaks: remove an unneeded pre-processor '#else' clause
|
||||
|
||||
|
||||
Changes between v4.1 and v4.2:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (23):
|
||||
build: be more specific and avoid committing accidentally changed files
|
||||
bump version numbers and add a news item for the 4.2 release
|
||||
docs: put the 'set guidestripe' option into its alphabetical position
|
||||
options: make --breaklonglines work also when --ignorercfiles is used
|
||||
speller: do not crash by trying to free something that cannot be freed
|
||||
tweaks: adjust a few comments and some indentation
|
||||
tweaks: condense and improve a handful of comments
|
||||
tweaks: declare a function as const and let its allocated string leak
|
||||
tweaks: drop an unneeded saving and restoring of a variable
|
||||
tweaks: elide an unneeded intermediate variable
|
||||
tweaks: elide an unneeded parameter, as the function already assumes it
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: exclude a bit more code from a single-buffer build
|
||||
tweaks: remove an unneeded condition
|
||||
tweaks: remove a redundant, enclosed #ifdef
|
||||
tweaks: rename a function, to be distinct and fitting
|
||||
tweaks: rename another function, to be distinct and fitting
|
||||
tweaks: rename a variable, for a little more meaning
|
||||
tweaks: rename a variable, to distinguish it from a browser function
|
||||
wrapping: add a missing space only when the remainder will be prepended
|
||||
wrapping: compute the width of a succeeding line in the correct manner
|
||||
wrapping: improve the persistence of the prepending behavior
|
||||
wrapping: trim any trailing blanks when cursor goes to next line
|
||||
|
||||
|
||||
Changes between v4.0 and v4.1:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (85):
|
||||
bindings: add easier keystrokes for the linenumber and softwrap toggles
|
||||
bindings: disallow executing an external command when in view mode
|
||||
bindings: recognize the ^W^Y and ^W^V legacy keystrokes again
|
||||
bindings: remove the jumpy-scrolling toggle entirely
|
||||
build: add gnulib modules to the list of files with translatable strings
|
||||
build: add src/cut.c to the list of files with translatable strings
|
||||
build: don't do fuzzy matching when merging PO files against the POT file
|
||||
build: remove obsolete translations from the PO files after merging
|
||||
bump version numbers and add a news item for the 4.1 release
|
||||
display: report and catch a bad state, to prevent a possible hang
|
||||
docs: for two of the toggles, mention the new instead of the old option
|
||||
docs: give the FILES section in the man page its canonical title
|
||||
docs: mention that -b is the opposite of -w also in the latter's item
|
||||
docs: mention that M-S now toggles softwrap and M-N line numbers
|
||||
docs: put paths and filenames in italics, per 'man man-pages'
|
||||
docs: remove all mention of --finalnewline, and undefault --nonewlines
|
||||
docs: remove the AUTHOR section, per advice from 'man man-pages'
|
||||
docs: re-title the temporary section about the changed defaults
|
||||
feedback: replace an assert with a check plus error message at startup
|
||||
feedback: show a message while executing an external command
|
||||
feedback: spare the user a superfluous scaring when trying to exit
|
||||
gnulib: update to its current upstream state
|
||||
help: don't doubly list toggles that have two keys assigned to them
|
||||
indenting, commenting: ensure a partial line stays displayed properly
|
||||
justify: correctly compute the number of lines to take, to avoid a crash
|
||||
options: make --nowrap override again a contrary nanorc setting
|
||||
options: remove -f (--finalnewline); go back to auto-adding this newline
|
||||
rcfile: don't break a chain of 'else if' [scan-build]
|
||||
rcfile: read the syntax files in alphabetical order when globbing
|
||||
speller: block the resizing signal again during an external spell check
|
||||
speller: block the resizing signal also during an integrated spell check
|
||||
speller: resizing can happen also when configured with --enable-tiny
|
||||
syntax: c: color as a type any lowercase word that ends with "_t"
|
||||
syntax: default: color in red also versions 4.x of nano
|
||||
syntax: man: add comments, and color all the safe lowercase macros
|
||||
syntax: man: anchor macros at start of line, as only then they are valid
|
||||
syntax: man: require the dot to be at start of line, not the comment
|
||||
syntax: nanorc: colorize also strings preceded by 'start=' or 'end='
|
||||
syntax: nanorc: require whitespace both before and after a quoted string
|
||||
tweaks: adjust the indentation after the previous change
|
||||
tweaks: condense a bit of copying code
|
||||
tweaks: consistently use .sp instead of .PP to insert a blank line
|
||||
tweaks: do a check up front instead of every time round the loop
|
||||
tweaks: don't bother copying the NUL byte -- it is set nine lines down
|
||||
tweaks: don't bother reallocating the data when a line gets hard-wrapped
|
||||
tweaks: don't bother reallocating the squeezed string, just terminate it
|
||||
tweaks: don't bother special-casing non-UTF8 when seeking a character
|
||||
tweaks: drop an assignment whose value is never used [scan-build]
|
||||
tweaks: drop two 'const' qualifiers, to silence the compiler
|
||||
tweaks: free some memory before a possible error exit [coverity]
|
||||
tweaks: free the copy of a linter message in all cases [valgrind]
|
||||
tweaks: free the result string from an invocation error [coverity]
|
||||
tweaks: initialize a boolean before it is referenced [valgrind]
|
||||
tweaks: put the unblocking of SIGWINCHes in a better place
|
||||
tweaks: remove a function that is now unused
|
||||
tweaks: remove an unneeded check for NULL and its associated message
|
||||
tweaks: remove an unneeded check for NULL [coverity]
|
||||
tweaks: remove an unpaired closing parenthesis from the NEWS file
|
||||
tweaks: remove a superfluous check for NULL plus the associated message
|
||||
tweaks: remove several unneeded bad-state checks and their messages
|
||||
tweaks: rename a cryptic type to something that makes a little sense
|
||||
tweaks: rename a function plus parameter, to stay closer to what it does
|
||||
tweaks: rename another variable, to be more descriptive
|
||||
tweaks: rename another variable, to be more fitting
|
||||
tweaks: rename an overshort type to something that makes some sense
|
||||
tweaks: rename a variable, to be more distinct and more apt
|
||||
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 two variables, for more contrast
|
||||
tweaks: rename two variables, to be more distinct and more fitting
|
||||
tweaks: rename two variables, to make more sense
|
||||
tweaks: rename two variables, to match others
|
||||
tweaks: reshuffle some lines, condense a comment and drop another
|
||||
tweaks: reshuffle some lines, to elide an 'if'
|
||||
tweaks: reshuffle two lines, and reword a comment
|
||||
tweaks: reword a comment, and drop an unneeded assert
|
||||
tweaks: shorten a comment to its essence
|
||||
tweaks: shorten and improve some comments, and reshuffle a few lines
|
||||
tweaks: simplify a message, and normalize the spelling of another one
|
||||
tweaks: stop doing tandem assignments (one passing through the other)
|
||||
tweaks: switch back from checking FINAL_NEWLINE to checking NO_NEWLINES
|
||||
tweaks: use a signed type for a result that could be negative [coverity]
|
||||
unindent: ensure that a partial line gets displayed properly afterwards
|
||||
|
||||
Brand Huntsman (1):
|
||||
files: block the resizing signal while reading from an external command
|
||||
|
||||
Devin Hussey (1):
|
||||
files: initialize a variable before referencing it
|
||||
|
||||
Liu Hao (1):
|
||||
syntax: c: change the highlighting of preprocessor directives
|
||||
|
||||
|
||||
Changes between v3.2 and v4.0:
|
||||
------------------------------
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ Improvements in GNU nano
|
||||
========================
|
||||
|
||||
Since 4.0:
|
||||
- The ability to both read from and write to a FIFO.
|
||||
- Automatic hard-wrapping is no longer the default.
|
||||
- Addition of --guidestripe to draw a helpful vertical bar.
|
||||
- Meta-Up and Meta-Down scroll the screen linewise.
|
||||
|
||||
34
NEWS
34
NEWS
@@ -1,3 +1,31 @@
|
||||
2019.06.18 - GNU nano 4.3 "Musa Kart"
|
||||
• The ability to read from and write to a FIFO has been regained.
|
||||
• Startup time is reduced by fully parsing a syntax only when needed.
|
||||
• Asking for help (^G) when using --operatingdir does not crash.
|
||||
• The reading of a huge or slow file can be stopped with ^C.
|
||||
• Cut, zap, and copy operations are undone separately when intermixed.
|
||||
• M-D reports the correct number of lines (zero for an empty buffer).
|
||||
|
||||
2019.04.24 - GNU nano 4.2 "Tax the rich, pay the teachers"
|
||||
• The integrated spell checker does not crash when 'spell' is missing.
|
||||
• Option --breaklonglines works also when --ignorercfiles is used.
|
||||
• Automatic hard-wrapping is more persistent in pushing words to the
|
||||
same overflow line.
|
||||
|
||||
2019.04.15 - GNU nano 4.1 "Qué corchos será eso?"
|
||||
• By default, a newline character is again automatically added at the
|
||||
end of a buffer, to produce valid POSIX text files by default, but
|
||||
also to get back the easy adding of text at the bottom.
|
||||
• The now unneeded option --finalnewline (-f) has been removed.
|
||||
• Syntax files are read in alphabetical order when globbing, so that
|
||||
the precedence of syntaxes becomes predictable.
|
||||
• In the C syntax, preprocessor directives are highlighted differently.
|
||||
• M-S now toggles soft wrapping, and M-N toggles line numbers.
|
||||
• The jumpy-scrolling toggle has been removed.
|
||||
• The legacy keystrokes ^W^Y and ^W^V are recognized again.
|
||||
• Executing an external command is disallowed when in view mode.
|
||||
• Problems with resizing during external or speller commands were fixed.
|
||||
|
||||
2019.03.24 - GNU nano 4.0 "Thy Rope of Sands"
|
||||
• An overlong line is no longer automatically hard-wrapped.
|
||||
• Smooth scrolling (one line at a time) has become the default.
|
||||
@@ -13,7 +41,7 @@
|
||||
• Option --guidestripe=<number> draws a vertical bar at the given column.
|
||||
• Option --fill=<number> no longer turns on automatic hard-wrapping.
|
||||
• When a line continues offscreen, it now ends with a highlighted ">".
|
||||
• The halfs of a split two-column character are shown as "[" and "]".
|
||||
• The halves of a split two-column character are shown as "[" and "]".
|
||||
• A line now scrolls horizontally one column earlier.
|
||||
• The bindable functions 'cutwordleft' and 'cutwordright' were renamed
|
||||
to 'chopwordleft' and 'chopwordright' as they don't use the cutbuffer.
|
||||
@@ -670,8 +698,8 @@
|
||||
without the usual truncation and a '$' symbol at the end
|
||||
of the line. It can be enabled via Meta-$ inside the
|
||||
editor, via the -$ or --softwrap command-line flags,
|
||||
or "set softwrap" in your .nanorc). As always, please
|
||||
report any bugs to the nano Savannah project page
|
||||
or via "set softwrap" in your .nanorc. As always,
|
||||
please report any bugs to the nano Savannah project page
|
||||
(http://savannah.gnu.org/bugs/?func=additem&group=nano)
|
||||
Remember: data loss happens, back up your files.
|
||||
|
||||
|
||||
6
README
6
README
@@ -15,10 +15,10 @@ Overview
|
||||
|
||||
Nano aimed to solve these problems by: 1) being truly free software
|
||||
by using the GPL, 2) emulating the functionality of Pico as closely
|
||||
as is reasonable, and 3) include extra functionality by default.
|
||||
as is reasonable, and 3) including extra functionality by default.
|
||||
|
||||
Nowadays, nano wants to be a generally useful editor, with default
|
||||
settings that do not change the file contents automatically.
|
||||
Nowadays, nano wants to be a generally useful editor with sensible
|
||||
defaults (linewise scrolling, no automatic line breaking).
|
||||
|
||||
The nano editor is an official GNU package. For more information on
|
||||
GNU and the Free Software Foundation, please see https://www.gnu.org/.
|
||||
|
||||
9
THANKS
9
THANKS
@@ -11,6 +11,7 @@ Mario Blättermann <mario.blaettermann@gmail.com> German
|
||||
Ricardo Cárdenes Medina <ricardo@conisys.com> Spanish
|
||||
Antonio Ceballos <aceballos@gmail.com> Spanish
|
||||
Wei-Lun CHAO <chaoweilun@pcmail.com.tw> Chinese (traditional)
|
||||
Seong-ho Cho <darkcircle.0426@gmail.com> Korean
|
||||
Yuri Chornoivan <yurchor@ukr.net> Ukrainian
|
||||
Marco Colombo <magicdice@inwind.it> Italian
|
||||
Mihai Cristescu <mihai.cristescu@archlinux.info> Romanian
|
||||
@@ -22,22 +23,22 @@ Rafael Fontenelle <rffontenelle@gmail.com> Brazilian Portuguese
|
||||
Pavel Fric <pavelfric@seznam.cz> Czech
|
||||
Jorge González <aloriel@gmail.com> Spanish
|
||||
Jean-Philippe Guérard <jean-philippe.guerard@laposte.net> French
|
||||
Geir Helland <pjallabais@users.sourceforge.net> Norwegian Bokmål
|
||||
Tedi Heriyanto <tedi_h@gmx.net> Indonesian
|
||||
Václav Haisman <V.Haisman@sh.cvut.cz> Czech
|
||||
Takeshi Hamasaki <hmatrjp@users.sourceforge.jp> Japanese
|
||||
Geir Helland <pjallabais@users.sourceforge.net> Norwegian Bokmål
|
||||
Tedi Heriyanto <tedi_h@gmx.net> Indonesian
|
||||
Kjetil Torgrim Homme <kjetilho@linpro.no> Norwegian Nynorsk
|
||||
Szabolcs Horvath <horvaths@janus.gimsz.sulinet.hu> Hungarian
|
||||
Jorma Karvonen <karvonen.jorma@gmail.com> Finnish
|
||||
Mehmet Kececi <mkececi@mehmetkececi.com> Turkish
|
||||
Mehmet Kececi <mkececi@mehmetkececi.com> Turkish
|
||||
Gabor Kelemen <kelemeng@gnome.hu> Hungarian
|
||||
Kalle Kivimaa <kalle.kivimaa@iki.fi> Finnish
|
||||
Eivind Kjørstad <ekj@vestdata.no> Norwegian Nynorsk
|
||||
Florian König <floki@bigfoot.com> German
|
||||
Klemen Košir <klemen913@gmail.com> Slovenian
|
||||
Wojciech Kotwica <wkotwica@post.pl> Polish
|
||||
Ask Hjorth Larsen <asklarsen@gmail.com> Danish
|
||||
Clement Laforet <clem_laf@wanadoo.fr> French
|
||||
Ask Hjorth Larsen <asklarsen@gmail.com> Danish
|
||||
LI Daobing <lidaobing@gmail.com> Chinese (simplified)
|
||||
Jordi Mallach <jordi@gnu.org> Catalan
|
||||
João Victor Duarte Martins <jvdm@sdf.lonestar.org> Brazilian Portuguese
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="69c4509f33c6a6ac159f3429d4150bf119ac4d76"
|
||||
gnulib_hash="a1beabcb14cde661c36f7a3c7c17b5871704003e"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
AC_INIT([GNU nano], [4.0], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [4.3], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.14])
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
|
||||
<blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program "establishes a full duplex terminal connection to a remote host", and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote>
|
||||
<h3><a name="1.4"></a>1.4. What is the current version of nano?</h3>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>4.0</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>4.3</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%">
|
||||
|
||||
54
doc/nano.1
54
doc/nano.1
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 4.0" "March 2019"
|
||||
.TH NANO 1 "version 4.3" "June 2019"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, inspired by Pico
|
||||
@@ -25,15 +25,13 @@ nano \- Nano's ANOther editor, inspired by Pico
|
||||
.B nano
|
||||
.RI [ options "] [[+" line [, column "]]\ " file "]..."
|
||||
|
||||
.SH NOTE
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
line by default, and no longer automatically adds a newline at the end
|
||||
of the text if one is missing. Furthermore, it uses smooth scrolling
|
||||
by default and makes use of the line below the title bar.
|
||||
line by default. It further uses smooth scrolling by default, and by
|
||||
default includes the line below the title bar into the editing area.
|
||||
.sp
|
||||
If you want the old, Pico behavior back, you can use \fB\-\-breaklonglines\fR,
|
||||
\fB\-\-finalnewline\fR, \fB\-\-jumpyscrolling\fR, and \fB\-\-emptyline\fR
|
||||
(or \fB\-bfje\fR for short).
|
||||
\fB\-\-jumpyscrolling\fR, and \fB\-\-emptyline\fR (or \fB\-bje\fR for short).
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBnano\fP is a small and friendly editor. It copies the look and feel
|
||||
@@ -57,18 +55,18 @@ Consecutive \fB^K\fRs will put all deleted lines together in the cutbuffer.
|
||||
Any cursor movement or executing any other command will cause the next
|
||||
\fB^K\fR to overwrite the cutbuffer. A \fB^U\fR will paste the current
|
||||
contents of the cutbuffer at the current cursor position.
|
||||
.PP
|
||||
.sp
|
||||
When a more precise piece of text needs to be cut or copied, one can mark
|
||||
its start with \fB^6\fR, move the cursor to its end (the marked text will be
|
||||
highlighted), and then use \fB^K\fR to cut it, or \fBM\-6\fR to copy it to the
|
||||
cutbuffer. One can also save the marked text to a file with \fB^O\fR, or
|
||||
spell check it with \fB^T\fR.
|
||||
.PP
|
||||
.sp
|
||||
On some terminals, text can be selected also by holding down Shift while
|
||||
using the arrow keys. Holding down the Ctrl or Alt key too will increase
|
||||
the stride.
|
||||
Any cursor movement without Shift being held will cancel such a selection.
|
||||
.PP
|
||||
.sp
|
||||
The two lines at the bottom of the screen show some important commands;
|
||||
the built-in help (\fB^G\fR) lists all the available ones.
|
||||
The default key bindings can be changed via a \fInanorc\fR file -- see
|
||||
@@ -123,8 +121,8 @@ properly, please report a bug. Using this option disables \fBnano\fR's
|
||||
mouse support.
|
||||
.TP
|
||||
.BR \-L ", " \-\-nonewlines
|
||||
Don't automatically add a newline when a file does not end with one.
|
||||
(This is the default.)
|
||||
Don't automatically add a newline when a text does not end with one.
|
||||
(This can cause you to save non-POSIX text files.)
|
||||
.TP
|
||||
.BR \-M ", " \-\-trimblanks
|
||||
Snip trailing whitespace from the wrapped line when automatic
|
||||
@@ -144,7 +142,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]*([!#%:;>|}]|//))+"\fP.
|
||||
(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.
|
||||
@@ -213,11 +211,6 @@ system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
.BR \-e ", " \-\-emptyline
|
||||
Do not use the line below the title bar, leaving it entirely blank.
|
||||
.TP
|
||||
.BR \-f ", " \-\-finalnewline
|
||||
If the buffer is not empty, ensure that it ends with a newline character.
|
||||
(This option is the opposite of \fB\-L\fR (\fB\-\-nonewlines\fR) --
|
||||
the last one given takes effect.)
|
||||
.TP
|
||||
.BR \-g ", " \-\-showcursor
|
||||
Make the cursor visible in the file browser (putting it on the
|
||||
highlighted item) and in the help viewer. Useful for braille users
|
||||
@@ -288,7 +281,9 @@ unless \fB\-\-restricted\fR is given too.
|
||||
.TP
|
||||
.BR \-w ", " \-\-nowrap
|
||||
Do not automatically hard-wrap the current line when it becomes overlong.
|
||||
(This is the default.)
|
||||
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.
|
||||
@@ -310,16 +305,16 @@ separately (e.g.\& 'nano \-wS \-$').
|
||||
.SH TOGGLES
|
||||
Several of the above options can be switched on and off also while
|
||||
\fBnano\fR is running. For example, \fBM\-L\fR toggles the
|
||||
hard-wrapping of long lines, \fBM\-$\fR toggles soft-wrapping,
|
||||
\fBM\-#\fR toggles line numbers, \fBM\-M\fR toggles the mouse,
|
||||
hard-wrapping of long lines, \fBM\-S\fR toggles soft-wrapping,
|
||||
\fBM\-N\fR toggles line numbers, \fBM\-M\fR toggles the mouse,
|
||||
\fBM\-I\fR auto-indentation, and \fBM\-X\fR the help lines.
|
||||
See at the end of the \fB^G\fR help text for a complete list.
|
||||
|
||||
.SH INITIALIZATION FILE
|
||||
.SH FILES
|
||||
\fBnano\fR will read two configuration files: first the system's
|
||||
\fInanorc\fR (if it exists), and then the user's \fInanorc\fR (if it
|
||||
exists), either \fB~/.nanorc\fR or \fI$XDG_CONFIG_HOME\fB/nano/nanorc\fR
|
||||
or \fB~/.config/nano/nanorc\fR, whichever is encountered first. See
|
||||
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.
|
||||
|
||||
@@ -345,21 +340,16 @@ not by default distinguish modified from unmodified arrow keys.
|
||||
.sp
|
||||
Please report any other bugs that you encounter via:
|
||||
.br
|
||||
\fIhttps://savannah.gnu.org/bugs/?group=nano\fR.
|
||||
.IR https://savannah.gnu.org/bugs/?group=nano .
|
||||
.sp
|
||||
When nano crashes, it will save any modified buffers to emergency .save files.
|
||||
If you are able to reproduce the crash and you want to get a backtrace, define
|
||||
the environment variable \fBNANO_NOCATCH\fR.
|
||||
|
||||
.SH HOMEPAGE
|
||||
\fIhttps://nano\-editor.org/\fR
|
||||
.I https://nano\-editor.org/
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR nanorc (5)
|
||||
.PP
|
||||
.sp
|
||||
\fI/usr/share/doc/nano/\fP (or equivalent on your system)
|
||||
|
||||
.SH AUTHOR
|
||||
Chris Allegretta and others (see the files \fIAUTHORS\fR and
|
||||
\fITHANKS\fP for details). This manual page was originally written by
|
||||
Jordi Mallach for the Debian system (but may be used by others).
|
||||
|
||||
108
doc/nano.texi
108
doc/nano.texi
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 4.0
|
||||
@set UPDATED March 2019
|
||||
@set VERSION 4.3
|
||||
@set UPDATED June 2019
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 4.0
|
||||
@subtitle version 4.3
|
||||
|
||||
@author Chris Allegretta
|
||||
@page
|
||||
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
|
||||
@node Top
|
||||
@top
|
||||
|
||||
This manual documents the GNU @command{nano} editor, version 4.0.
|
||||
This manual documents the GNU @command{nano} editor, version 4.3.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@@ -97,14 +97,13 @@ as is reasonable while offering a superset of Pico's functionality.
|
||||
Pico differ.
|
||||
|
||||
Starting with version 4.0, @command{nano} no longer hard-wraps an overlong
|
||||
line by default, and no longer automatically adds a newline at the end
|
||||
of the text if one is missing. Furthermore, it uses smooth scrolling
|
||||
by default and makes use of the line below the title bar.
|
||||
line by default. It further uses smooth 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{--finalnewline},
|
||||
following options: @option{--breaklonglines},
|
||||
@option{--jumpyscrolling}, and @option{--emptyline}
|
||||
(or @option{-bfje} for short).
|
||||
(or @option{-bje} for short).
|
||||
|
||||
Please report bugs via @url{https://savannah.gnu.org/bugs/?group=nano}.
|
||||
|
||||
@@ -215,8 +214,8 @@ mouse support.
|
||||
|
||||
@item -L
|
||||
@itemx --nonewlines
|
||||
Don't automatically add a newline when a file does not end with one.
|
||||
(This is the default.)
|
||||
Don't automatically add a newline when a text does not end with one.
|
||||
(This can cause you to save non-POSIX text files.)
|
||||
|
||||
@item -M
|
||||
@itemx --trimblanks
|
||||
@@ -241,7 +240,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.
|
||||
@@ -325,12 +324,6 @@ system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
@itemx --emptyline
|
||||
Do not use the line below the title bar, leaving it entirely blank.
|
||||
|
||||
@item -f
|
||||
@itemx --finalnewline
|
||||
If the buffer is not empty, ensure that it ends with a newline character.
|
||||
(This option is the opposite of @option{-L} (@option{--nonewlines}) ---
|
||||
the last one given takes effect.)
|
||||
|
||||
@item -g
|
||||
@itemx --showcursor
|
||||
Make the cursor visible in the file browser (putting it on the
|
||||
@@ -426,7 +419,9 @@ file permissions to implement a read-only file.)
|
||||
@item -w
|
||||
@itemx --nowrap
|
||||
Do not automatically hard-wrap the current line when it becomes overlong.
|
||||
(This is the default.)
|
||||
This is the default. (This option is the opposite of @option{-b}
|
||||
(@option{--breaklonglines}) --- the last one given takes effect.)
|
||||
|
||||
|
||||
@anchor{Expert Mode}
|
||||
@item -x
|
||||
@@ -643,19 +638,22 @@ The following global toggles are available:
|
||||
@kbd{Meta-K} toggles the @option{-k} (@option{--cutfromcursor}) command-line option.
|
||||
|
||||
@item Long-Line Wrapping
|
||||
@kbd{Meta-L} toggles the @option{-w} (@option{--nowrap}) command-line option.
|
||||
@kbd{Meta-L} toggles the @option{-b} (@option{--breaklonglines}) command-line option.
|
||||
|
||||
@item Mouse Support
|
||||
@kbd{Meta-M} toggles the @option{-m} (@option{--mouse}) command-line option.
|
||||
|
||||
@item Line Numbers
|
||||
@kbd{Meta-N} toggles the @option{-l} (@option{--linenumbers}) command-line option.
|
||||
|
||||
@item Tabs To Spaces
|
||||
@kbd{Meta-O} toggles the @option{-E} (@option{--tabstospaces}) command-line option.
|
||||
|
||||
@item Whitespace Display
|
||||
@kbd{Meta-P} toggles the displaying of whitespace (@pxref{Whitespace}).
|
||||
|
||||
@item Smooth Scrolling
|
||||
@kbd{Meta-S} toggles the @option{-S} (@option{--smooth}) command-line option.
|
||||
@item Soft Wrapping
|
||||
@kbd{Meta-S} toggles the @option{-$} (@option{--softwrap}) command-line option.
|
||||
|
||||
@item Expert/No Help
|
||||
@kbd{Meta-X} toggles the @option{-x} (@option{--nohelp}) command-line option.
|
||||
@@ -667,12 +665,6 @@ The following global toggles are available:
|
||||
@item Suspension
|
||||
@kbd{Meta-Z} toggles the @option{-z} (@option{--suspend}) command-line option.
|
||||
|
||||
@item Line Numbers
|
||||
@kbd{Meta-#} toggles the @option{-l} (@option{--linenumbers}) command-line option.
|
||||
|
||||
@item Soft Wrapping
|
||||
@kbd{Meta-$} toggles the @option{-$} (@option{--softwrap}) command-line option.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@@ -698,10 +690,8 @@ take an argument are unset by default. So using the @code{unset} command
|
||||
is only needed when wanting to override a setting of the system's nanorc
|
||||
file in your own nanorc. Options that take an argument cannot be unset.
|
||||
|
||||
Quotes inside string parameters don't have to be escaped with
|
||||
backslashes. The last double quote in the string will be treated as its
|
||||
end. For example, for the @code{brackets} option, @t{""')>]@}"} will match
|
||||
@code{"}, @code{'}, @code{)}, @code{>}, @code{]}, and @code{@}}.
|
||||
Quotes inside the @var{characters} parameters below should not be escaped.
|
||||
The last double quote on the line will be seen as the closing quote.
|
||||
|
||||
@menu
|
||||
* Settings::
|
||||
@@ -749,7 +739,7 @@ function tags, line numbers, and selected text. This can be overridden by
|
||||
setting the options @code{titlecolor}, @code{statuscolor}, @code{keycolor},
|
||||
@code{functioncolor}, @code{numbercolor}, and @code{selectedcolor}.
|
||||
|
||||
@item set brackets "@var{string}"
|
||||
@item set brackets "@var{characters}"
|
||||
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
|
||||
@@ -774,11 +764,9 @@ Do not use the line below the title bar, leaving it entirely blank.
|
||||
|
||||
@item set errorcolor @var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for the status bar when an error message is displayed.
|
||||
The default value is @t{brightwhite,red}.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set finalnewline
|
||||
If the buffer is not empty, ensure that it ends with a newline character.
|
||||
|
||||
@item set fill @var{number}
|
||||
Set the target width for justifying and automatic hard-wrapping at this
|
||||
@var{number} of columns. If the value is 0 or less, wrapping will occur
|
||||
@@ -797,6 +785,10 @@ Valid names for foreground and background color are:
|
||||
The name of the foreground color may be prefixed with @code{bright}.
|
||||
And either @var{fgcolor} or ,@var{bgcolor} may be left out.
|
||||
|
||||
@item set guidestripe @var{number}
|
||||
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 historylog
|
||||
Save the last hundred search strings and replacement strings and
|
||||
executed commands, so they can be easily reused in later sessions.
|
||||
@@ -815,11 +807,7 @@ Display line numbers to the left of the text area.
|
||||
@item set locking
|
||||
Enable vim-style lock-files for when editing files.
|
||||
|
||||
@item set guidestripe @var{number}
|
||||
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 matchbrackets "@var{string}"
|
||||
@item set matchbrackets "@var{characters}"
|
||||
Set 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.
|
||||
@@ -843,8 +831,8 @@ Don't convert files from DOS/Mac format.
|
||||
Don't display the help lists at the bottom of the screen.
|
||||
|
||||
@item set nonewlines
|
||||
Deprecated option since it has become the default setting.
|
||||
When needed, use @code{unset finalnewline} instead.
|
||||
Don't automatically add a newline when a text does not end with one.
|
||||
(This can cause you to save non-POSIX text files.)
|
||||
|
||||
@item set nopauses
|
||||
Don't pause between warnings at startup. This means that only
|
||||
@@ -871,7 +859,7 @@ 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 punct "@var{string}"
|
||||
@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
|
||||
@@ -884,7 +872,7 @@ keystroke instead of 25. Note that @option{constantshow} overrides 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.
|
||||
@@ -901,7 +889,8 @@ and Delete work properly. You should only use this option when on your
|
||||
system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
|
||||
@item set regexp
|
||||
Do extended regular expression searches by default.
|
||||
Do regular-expression searches by default.
|
||||
Regular expressions in @command{nano} are of the extended type (ERE).
|
||||
|
||||
@item set selectedcolor @var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for selected text.
|
||||
@@ -970,7 +959,7 @@ 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{string}"
|
||||
@item set whitespace "@var{characters}"
|
||||
Set the two characters used to indicate the presence of tabs and
|
||||
spaces. They must be single-column characters. The default pair
|
||||
for a UTF-8 locale is @t{"»·"}, and for other locales @t{">."}.
|
||||
@@ -979,7 +968,7 @@ for a UTF-8 locale is @t{"»·"}, and for other locales @t{">."}.
|
||||
Detect word boundaries differently by treating punctuation
|
||||
characters as part of a word.
|
||||
|
||||
@item set wordchars "@var{string}"
|
||||
@item set wordchars "@var{characters}"
|
||||
Specify which other characters (besides the normal alphanumeric ones)
|
||||
should be considered as parts of words. This overrides the option
|
||||
@code{wordbounds}.
|
||||
@@ -1000,6 +989,20 @@ 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}.
|
||||
|
||||
All regular expressions in @command{nano} are extended regular expressions
|
||||
(ERE). This means that @code{.}, @code{?}, @code{*}, @code{+}, @code{^},
|
||||
@code{$}, and several other characters are special.
|
||||
The period @code{.} matches any single character,
|
||||
@code{?} means the preceding item is optional,
|
||||
@code{*} means the preceding item may be matched zero or more times,
|
||||
@code{+} means the preceding item must be matched one or more times,
|
||||
@code{^} matches the beginning of a line, and @code{$} the end,
|
||||
@code{\<} matches the start of a word, and @code{\>} the end,
|
||||
and @code{\s} matches a blank.
|
||||
It also means that lookahead and lookbehind are not possible.
|
||||
A complete explanation can be found in the manual of GNU grep:
|
||||
@code{info grep regular}.
|
||||
|
||||
A separate syntax can be defined for each kind of file
|
||||
via the following commands in a nanorc file:
|
||||
|
||||
@@ -1442,9 +1445,6 @@ Toggles the presence of the two-line list of key bindings at the bottom of the s
|
||||
@item constantshow
|
||||
Toggles the constant display of the current line, column, and character positions.
|
||||
|
||||
@item smoothscroll
|
||||
Toggles smooth scrolling (when moving around with the arrow keys).
|
||||
|
||||
@item softwrap
|
||||
Toggles the displaying of overlong lines on multiple screen lines.
|
||||
|
||||
@@ -1576,12 +1576,6 @@ switched on with the @option{--breaklonglines} option. With that option,
|
||||
whereas Pico does it at screen width minus six columns. You can make
|
||||
@command{nano} do as Pico by using @option{--fill=-6}.
|
||||
|
||||
@item Magic Newline
|
||||
Pico ensures that any text always ends with a newline character.
|
||||
Nano does not do this by default: the user is left in full control
|
||||
of the formatting. You can get the automatic newline by using the
|
||||
@option{--finalnewline} option.
|
||||
|
||||
@item Scrolling
|
||||
By default, @command{nano} will scroll just one line (instead of half
|
||||
a screen) when the cursor is moved to a line that is just out of view.
|
||||
|
||||
97
doc/nanorc.5
97
doc/nanorc.5
@@ -16,28 +16,27 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 4.0" "March 2019"
|
||||
.TH NANORC 5 "version 4.3" "June 2019"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
|
||||
.SH NOTE
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
line by default, and no longer automatically adds a newline at the end
|
||||
of the text if one is missing. Furthermore, it uses smooth scrolling
|
||||
by default and makes use of the line below the title bar.
|
||||
line by default. It further uses smooth scrolling by default, and by
|
||||
default includes the line below the title bar into the editing area.
|
||||
.sp
|
||||
If you want the old, Pico behavior back, you can use \fBset breaklonglines\fR,
|
||||
\fBset finalnewline\fR, \fBset jumpyscrolling\fR, and \fBset emptyline\fR.
|
||||
\fBset jumpyscrolling\fR, and \fBset emptyline\fR.
|
||||
|
||||
.SH DESCRIPTION
|
||||
The \fInanorc\fP file contains the default settings for \fBnano\fP, a
|
||||
small and friendly editor. The file should be in Unix format, not in
|
||||
DOS or Mac format. During startup, \fBnano\fP will first read the
|
||||
system-wide settings, from \fB/etc/nanorc\fP (the exact path might be
|
||||
system-wide settings, from \fI/etc/nanorc\fP (the exact path might be
|
||||
different on your system), and then the user-specific settings, either
|
||||
from \fB~/.nanorc\fR or from \fI$XDG_CONFIG_HOME\fB/nano/nanorc\fR
|
||||
or from \fB~/.config/nano/nanorc\fR, whichever is encountered first.
|
||||
from \fI~/.nanorc\fR or from \fI$XDG_CONFIG_HOME/nano/nanorc\fR
|
||||
or from \fI~/.config/nano/nanorc\fR, whichever is encountered first.
|
||||
|
||||
.SH OPTIONS
|
||||
The configuration file accepts a series of \fBset\fP and \fBunset\fP
|
||||
@@ -45,20 +44,17 @@ commands, which can be used to configure nano on startup without using
|
||||
command-line options. Additionally, there are some commands to define
|
||||
syntax highlighting and to rebind keys -- see the two separate sections
|
||||
on those. \fBnano\fP reads one command per line.
|
||||
.PP
|
||||
.sp
|
||||
Options in \fInanorc\fP files take precedence over nano's defaults, and
|
||||
command-line options override \fInanorc\fP settings. Also, options that
|
||||
do not take an argument are unset by default. So using the \fBunset\fR
|
||||
command is only needed when wanting to override a setting of the system's
|
||||
\fInanorc\fR file in your own \fInanorc\fR. Options that take an
|
||||
argument cannot be unset.
|
||||
.PP
|
||||
Below, the \fIstring\fR parameters need to be enclosed in double quotes.
|
||||
Quotes inside these string parameters don't have to be escaped with
|
||||
backslashes. The last double quote in the string will be treated as its
|
||||
end. For example, for the \fBbrackets\fP option, "\fB"')>]}\fP" will
|
||||
match \fB"\fP, \fB'\fP, \fB)\fP, \fB>\fP, \fB]\fP, and \fB}\fP.
|
||||
.PP
|
||||
.sp
|
||||
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
|
||||
@@ -95,7 +91,7 @@ function tags, line numbers, and selected text. This can be overridden by
|
||||
setting the options \fBtitlecolor\fP, \fBstatuscolor\fP, \fBkeycolor\fP,
|
||||
\fBfunctioncolor\fP, \fBnumbercolor\fP, and \fBselectedcolor\fP.
|
||||
.TP
|
||||
.B set brackets "\fIstring\fP"
|
||||
.BI "set brackets """ characters """
|
||||
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
|
||||
@@ -119,23 +115,25 @@ Do not use the line below the title bar, leaving it entirely blank.
|
||||
.TP
|
||||
.B set errorcolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Use this color combination for the status bar when an error message is displayed.
|
||||
The default value is \fBbrightwhite,red\fR.
|
||||
See \fBset titlecolor\fR for valid color names.
|
||||
.TP
|
||||
.B set finalnewline
|
||||
If the buffer is not empty, ensure that it ends with a newline character.
|
||||
.TP
|
||||
.B set fill \fInumber\fR
|
||||
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 set functioncolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Specify the color combination to use for the function descriptions
|
||||
in the two help lines at the bottom of the screen.
|
||||
See \fBset titlecolor\fR for more details.
|
||||
.TP
|
||||
.B set guidestripe \fInumber
|
||||
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 historylog
|
||||
Save the last hundred search strings and replacement strings and
|
||||
executed commands, so they can be easily reused in later sessions.
|
||||
@@ -154,11 +152,7 @@ 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 guidestripe \fInumber
|
||||
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 matchbrackets "\fIstring\fP"
|
||||
.BI "set matchbrackets """ characters """
|
||||
Set 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.
|
||||
@@ -185,8 +179,8 @@ Don't convert files from DOS/Mac format.
|
||||
Don't display the two help lines at the bottom of the screen.
|
||||
.TP
|
||||
.B set nonewlines
|
||||
Deprecated option since it has become the default setting.
|
||||
When needed, use \fBunset finalnewline\fR instead.
|
||||
Don't automatically add a newline when a text does not end with one.
|
||||
(This can cause you to save non-POSIX text files.)
|
||||
.TP
|
||||
.B set nopauses
|
||||
Don't pause between warnings at startup. This means that only
|
||||
@@ -213,7 +207,7 @@ The cursor position is remembered for the 200 most-recently edited files.
|
||||
.B set preserve
|
||||
Preserve the XON and XOFF keys (^Q and ^S).
|
||||
.TP
|
||||
.B set punct "\fIstring\fP"
|
||||
.BI "set punct """ characters """
|
||||
Set the characters treated as closing punctuation when justifying
|
||||
paragraphs. This may not include blank characters. Only the
|
||||
specfified closing punctuation, optionally followed by closing brackets
|
||||
@@ -223,9 +217,9 @@ specfified closing punctuation, optionally followed by closing brackets
|
||||
Do quick status-bar blanking: status-bar messages will disappear after 1
|
||||
keystroke instead of 25. The option \fBconstantshow\fR overrides this.
|
||||
.TP
|
||||
.B set quotestr "\fIregex\fP"
|
||||
.BI "set quotestr """ regex """
|
||||
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]*([!#%:;>|}]|//))+\fP".
|
||||
(Note that \fB\\t\fR stands for an actual 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.
|
||||
@@ -242,7 +236,8 @@ and Delete work properly. You should only use this option when on your
|
||||
system either Backspace acts like Delete or Delete acts like Backspace.
|
||||
.TP
|
||||
.B set regexp
|
||||
Do extended regular expression searches by default.
|
||||
Do regular-expression searches by default.
|
||||
Regular expressions in \fBnano\fR are of the extended type (ERE).
|
||||
.TP
|
||||
.B set selectedcolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Specify the color combination to use for selected text.
|
||||
@@ -314,7 +309,7 @@ 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
|
||||
.B set whitespace "\fIstring\fP"
|
||||
.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
|
||||
for a UTF-8 locale is "\fB\[Fc]\[md]\fR", and for other locales "\fB>.\fR".
|
||||
@@ -323,7 +318,7 @@ for a UTF-8 locale is "\fB\[Fc]\[md]\fR", and for other locales "\fB>.\fR".
|
||||
Detect word boundaries differently by treating punctuation
|
||||
characters as parts of words.
|
||||
.TP
|
||||
.B set wordchars \fIstring\fP
|
||||
.BI "set wordchars """ characters """
|
||||
Specify which other characters (besides the normal alphanumeric ones)
|
||||
should be considered as parts of words. This overrides the option
|
||||
\fBwordbounds\fR.
|
||||
@@ -340,6 +335,20 @@ 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 \fBnano\fR.
|
||||
.sp
|
||||
All regular expressions in \fBnano\fR are extended regular expressions (ERE).
|
||||
This means that \fB.\fR, \fB?\fR, \fB*\fR, \fB+\fR, \fB^\fR, \fB$\fR, and
|
||||
several other characters are special.
|
||||
The period \fB.\fR matches any single character,
|
||||
\fB?\fR means the preceding item is optional,
|
||||
\fB*\fR means the preceding item may be matched zero or more times,
|
||||
\fB+\fR means the preceding item must be matched one or more times,
|
||||
\fB^\fR matches the beginning of a line, and \fB$\fR the end,
|
||||
\fB\\<\fR matches the start of a word, and \fB\\>\fR the end,
|
||||
and \fB\\s\fR matches a blank.
|
||||
It also means that lookahead and lookbehind are not possible.
|
||||
A complete explanation can be found in the manual page of GNU grep:
|
||||
\fBman grep\fR.
|
||||
.sp
|
||||
For each kind of file a separate syntax can be defined
|
||||
via the following commands:
|
||||
.TP
|
||||
@@ -434,14 +443,14 @@ a more general mechanism: the filtering of buffer or marked text through
|
||||
an external command. Such filtering is done by typing \fB^R^X\fR and then
|
||||
preceding your formatter command with the pipe symbol (\fB|\fR). It has
|
||||
the added advantage that the operation can be undone.
|
||||
.PP
|
||||
.sp
|
||||
If you use such a formatting command regularly, you could assign the relevant
|
||||
series of keystrokes to a single key in your nanorc:
|
||||
.PP
|
||||
.sp
|
||||
.RS
|
||||
.B "bind M\-F \(dq^R^X|yourformatcommand^M\(dq main"
|
||||
.RE
|
||||
.PP
|
||||
.sp
|
||||
(Note that the \fB^R\fR, \fB^X\fR, and \fB^M\fR are each a single, literal
|
||||
control character. You can enter them by preceding each with \fBM\-V\fR.)
|
||||
|
||||
@@ -776,9 +785,6 @@ Toggles the presence of the two-line list of key bindings at the bottom of the s
|
||||
.B constantshow
|
||||
Toggles the constant display of the current line, column, and character positions.
|
||||
.TP
|
||||
.B smoothscroll
|
||||
Toggles smooth scrolling (when moving around with the arrow keys).
|
||||
.TP
|
||||
.B softwrap
|
||||
Toggles the displaying of overlong lines on multiple screen lines.
|
||||
.TP
|
||||
@@ -873,16 +879,11 @@ for \fBunbind\fR it means all menus where the specified \fIkey\fR exists.
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.B /etc/nanorc
|
||||
.I /etc/nanorc
|
||||
System-wide configuration file.
|
||||
.TP
|
||||
.BR ~/.nanorc " or " \fI$XDG_CONFIG_HOME\fB/nano/nanorc " or " ~/.config/nano/nanorc
|
||||
.IR ~/.nanorc " or " $XDG_CONFIG_HOME/nano/nanorc " or " ~/.config/nano/nanorc
|
||||
Per-user configuration file.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR nano (1)
|
||||
|
||||
.SH AUTHOR
|
||||
Chris Allegretta and others (see the files \fIAUTHORS\fP and
|
||||
\fITHANKS\fP for details). This manual page was originally written by
|
||||
Jordi Mallach for the Debian system (but may be used by others).
|
||||
|
||||
20
doc/rnano.1
20
doc/rnano.1
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 4.0" "March 2019"
|
||||
.TH RNANO 1 "version 4.3" "June 2019"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
@@ -29,7 +29,7 @@ rnano \- a restricted nano
|
||||
\fBrnano\fR runs the \fBnano\fR editor in restricted mode. This allows
|
||||
editing only the specified file or files, and doesn't allow the user
|
||||
access to the filesystem nor to a command shell.
|
||||
.PP
|
||||
.sp
|
||||
In restricted mode, \fBnano\fR will:
|
||||
.IP \[bu] 2
|
||||
not allow suspending;
|
||||
@@ -45,20 +45,16 @@ not make backup files nor do spell checking.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Show a summary of command-line options and exit.
|
||||
.PP
|
||||
See the \fBnano\fP(1) manpage for all available options.
|
||||
Show the available command-line options and exit.
|
||||
.P
|
||||
For all existing options, see the \fBnano\fR(1) man page.
|
||||
|
||||
.SH BUGS
|
||||
Please report bugs via \fIhttps://savannah.gnu.org/bugs/?group=nano\fR.
|
||||
Please report bugs via
|
||||
.IR https://savannah.gnu.org/bugs/?group=nano .
|
||||
|
||||
.SH HOMEPAGE
|
||||
https://nano-editor.org/
|
||||
.I https://nano-editor.org/
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR nano (1)
|
||||
|
||||
.SH AUTHOR
|
||||
Chris Allegretta and others (see the files \fIAUTHORS\fR and \fITHANKS\fR
|
||||
for details). This manual page was originally written by Thijs Kinkhorst
|
||||
for the Debian system (but may be used by others).
|
||||
|
||||
@@ -8,10 +8,8 @@
|
||||
## For the options that take parameters, the default value is given.
|
||||
## Other options are unset by default.
|
||||
##
|
||||
## Quotes inside string parameters don't have to be escaped with
|
||||
## backslashes. The last double quote in the string will be treated as
|
||||
## its end. For example, for the "brackets" option, ""')>]}" will match
|
||||
## ", ', ), >, ], and }.
|
||||
## Inside string parameters, quotes should not be escaped. The last
|
||||
## double quote on the line will be seen as the closing quote.
|
||||
|
||||
## Make the 'nextword' function (Ctrl+Right) stop at word ends
|
||||
## instead of at beginnings.
|
||||
@@ -61,9 +59,6 @@
|
||||
## less, the wrapping point will be the screen width minus this number.
|
||||
# set fill -8
|
||||
|
||||
## Ensure that a non-empty buffer ends with a newline character.
|
||||
# set finalnewline
|
||||
|
||||
## Remember the used search/replace strings for the next session.
|
||||
# set historylog
|
||||
|
||||
@@ -99,6 +94,9 @@
|
||||
## Don't display the helpful shortcut lists at the bottom of the screen.
|
||||
# set nohelp
|
||||
|
||||
## Don't automatically add a newline when a file does not end with one.
|
||||
# set nonewlines
|
||||
|
||||
## Don't pause between warnings at startup. Which means that only the
|
||||
## last one will be readable (when there are multiple ones).
|
||||
# set nopauses
|
||||
@@ -127,7 +125,7 @@
|
||||
|
||||
## The regular expression that matches quoting characters in email
|
||||
## or line-comment introducers in source code. The default is:
|
||||
# set quotestr "^([ ]*([!#%:;>|}]|//|--))+"
|
||||
# set quotestr "^([ ]*([!#%:;>|}]|//))+"
|
||||
|
||||
## Try to work around a mismatching terminfo terminal description.
|
||||
# set rawsequences
|
||||
@@ -135,7 +133,8 @@
|
||||
## Fix Backspace/Delete confusion problem.
|
||||
# set rebinddelete
|
||||
|
||||
## Do extended regular expression searches by default.
|
||||
## Do regular-expression searches by default.
|
||||
## Regular expressions are of the extended type (ERE).
|
||||
# set regexp
|
||||
|
||||
## Put the cursor on the highlighted item in the file browser, and show
|
||||
@@ -239,6 +238,8 @@
|
||||
## yellow, magenta, cyan. For foreground colors, you may use the
|
||||
## prefix "bright" to get a stronger highlight.
|
||||
##
|
||||
## All regexes (regular expressions) are of the extended type (ERE).
|
||||
##
|
||||
## To use multi-line regexes, use the start="regex" end="regex"
|
||||
## [start="regex" end="regex"...] format.
|
||||
##
|
||||
@@ -246,8 +247,6 @@
|
||||
## color will use a transparent color. If you don't want this, be sure
|
||||
## to set the background color to black or white.
|
||||
##
|
||||
## All regexes should be extended regular expressions.
|
||||
##
|
||||
## If you wish, you may put your syntax definitions in separate files.
|
||||
## You can make use of such files as follows:
|
||||
##
|
||||
|
||||
11
po/Makevars
11
po/Makevars
@@ -11,15 +11,12 @@ top_builddir = ..
|
||||
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --keyword=P_:1,2
|
||||
|
||||
# This is the copyright holder that gets inserted into the header of the
|
||||
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
|
||||
# package. (Note that the msgstr strings, extracted from the package's
|
||||
# sources, belong to the copyright holder of the package.) Translators are
|
||||
# expected to transfer the copyright for their translations to this person
|
||||
# or entity, or to disclaim their copyright. The empty string stands for
|
||||
# the public domain; in this case the translators are expected to disclaim
|
||||
# their copyright.
|
||||
# $(DOMAIN).pot file. Translators are expected to disclaim their copyright.
|
||||
COPYRIGHT_HOLDER = Free Software Foundation, Inc.
|
||||
|
||||
# This is the list of locale categories, beyond LC_MESSAGES, for which the
|
||||
# message catalogs shall be used. It is usually empty.
|
||||
EXTRA_LOCALE_CATEGORIES =
|
||||
|
||||
# Don't do fuzzy matching when merging the PO files against the POT file.
|
||||
MSGMERGE_OPTIONS = --no-fuzzy-matching
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
src/browser.c
|
||||
src/color.c
|
||||
src/cut.c
|
||||
src/files.c
|
||||
src/global.c
|
||||
src/help.c
|
||||
@@ -13,3 +14,6 @@ src/search.c
|
||||
src/text.c
|
||||
src/utils.c
|
||||
src/winio.c
|
||||
|
||||
lib/getopt.c
|
||||
lib/regcomp.c
|
||||
|
||||
1297
po/nano.pot
1297
po/nano.pot
File diff suppressed because it is too large
Load Diff
1618
po/pt_BR.po
1618
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
@@ -21,8 +21,11 @@ fi
|
||||
echo "Regenerating POT file and remerging and recompiling PO files..."
|
||||
make update-po
|
||||
|
||||
# Ensure that the PO files are newer than the POT.
|
||||
touch *.po
|
||||
echo "Removing the dead weight of obsolete and fuzzy translations..."
|
||||
for pofile in *.po; do
|
||||
msgattrib --no-obsolete --no-fuzzy $pofile >trimmed.po || exit 4
|
||||
mv trimmed.po $pofile || exit 4
|
||||
done
|
||||
|
||||
# If needed, fix a problem in the Makefile template.
|
||||
grep -q '^datarootdir' Makefile.in.in || \
|
||||
|
||||
1566
po/zh_CN.po
1566
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1606
po/zh_TW.po
1606
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION="4.0"
|
||||
VERSION="4.3"
|
||||
|
||||
./configure -C --enable-tiny && make && ./configure -C &&
|
||||
|
||||
@@ -12,8 +12,8 @@ po/update_linguas.sh &&
|
||||
|
||||
make distcheck && make dist-xz &&
|
||||
|
||||
git add po/*.po &&
|
||||
git commit -a -m "$(git log -1 --grep 'po: up' | grep o: | sed 's/^ //')" &&
|
||||
git add po/*.po po/nano.pot &&
|
||||
git commit -m "$(git log -1 --grep 'po: up' | grep o: | sed 's/^ //')" &&
|
||||
|
||||
gpg -a -b nano-$VERSION.tar.gz &&
|
||||
gpg -a -b nano-$VERSION.tar.xz &&
|
||||
|
||||
@@ -77,8 +77,6 @@ char *do_browser(char *path)
|
||||
present_name = mallocstrcpy(present_name, filelist[selected]);
|
||||
}
|
||||
|
||||
assert(path != NULL && path[strlen(path) - 1] == '/');
|
||||
|
||||
if (dir != NULL) {
|
||||
/* Get the file list, and set longest and width in the process. */
|
||||
read_the_list(path, dir);
|
||||
@@ -223,11 +221,9 @@ char *do_browser(char *path)
|
||||
selected = filelist_len - 1;
|
||||
} else if (func == goto_dir_void) {
|
||||
/* Ask for the directory to go to. */
|
||||
int i = do_prompt(TRUE, FALSE, MGOTODIR, NULL, NULL,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
browser_refresh, _("Go To Directory"));
|
||||
|
||||
if (i < 0) {
|
||||
if (do_prompt(TRUE, FALSE, MGOTODIR, NULL, NULL,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
browser_refresh, _("Go To Directory")) < 0) {
|
||||
statusbar(_("Cancelled"));
|
||||
continue;
|
||||
}
|
||||
@@ -305,13 +301,12 @@ char *do_browser(char *path)
|
||||
} else if (func == (functionptrtype)implant) {
|
||||
implant(first_sc_for(MBROWSER, func)->expansion);
|
||||
#endif
|
||||
} else if (func == do_exit) {
|
||||
/* Exit from the file browser. */
|
||||
break;
|
||||
#ifndef NANO_TINY
|
||||
} else if (kbinput == KEY_WINCH) {
|
||||
;
|
||||
; /* Nothing to do. */
|
||||
#endif
|
||||
} else if (func == do_exit) {
|
||||
break;
|
||||
} else
|
||||
unbound_key(kbinput);
|
||||
|
||||
@@ -394,13 +389,11 @@ void read_the_list(const char *path, DIR *dir)
|
||||
const struct dirent *nextdir;
|
||||
size_t i = 0, path_len = strlen(path);
|
||||
|
||||
assert(path != NULL && path[strlen(path) - 1] == '/' && dir != NULL);
|
||||
|
||||
longest = 0;
|
||||
|
||||
/* Find the length of the longest filename in the current folder. */
|
||||
while ((nextdir = readdir(dir)) != NULL) {
|
||||
size_t name_len = strlenpt(nextdir->d_name);
|
||||
size_t name_len = breadth(nextdir->d_name);
|
||||
|
||||
if (name_len > longest)
|
||||
longest = name_len;
|
||||
@@ -445,8 +438,6 @@ void read_the_list(const char *path, DIR *dir)
|
||||
* filelist, so record it. */
|
||||
filelist_len = i;
|
||||
|
||||
assert(filelist != NULL);
|
||||
|
||||
/* Sort the list of names. */
|
||||
qsort(filelist, filelist_len, sizeof(char *), diralphasort);
|
||||
|
||||
@@ -518,7 +509,7 @@ void browser_refresh(void)
|
||||
struct stat st;
|
||||
const char *thename = tail(filelist[i]);
|
||||
/* The filename we display, minus the path. */
|
||||
size_t namelen = strlenpt(thename);
|
||||
size_t namelen = breadth(thename);
|
||||
/* The length of the filename in columns. */
|
||||
size_t infolen;
|
||||
/* The length of the file information in columns. */
|
||||
@@ -598,7 +589,7 @@ void browser_refresh(void)
|
||||
}
|
||||
|
||||
/* Make sure info takes up no more than infomaxlen columns. */
|
||||
infolen = strlenpt(info);
|
||||
infolen = breadth(info);
|
||||
if (infolen > infomaxlen) {
|
||||
info[actual_x(info, infomaxlen)] = '\0';
|
||||
infolen = infomaxlen;
|
||||
@@ -672,7 +663,7 @@ int filesearch_init(bool forwards)
|
||||
thedefault = charalloc(strlen(disp) + 7);
|
||||
/* We use (COLS / 3) here because we need to see more on the line. */
|
||||
sprintf(thedefault, " [%s%s]", disp,
|
||||
(strlenpt(last_search) > COLS / 3) ? "..." : "");
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
thedefault = mallocstrcpy(NULL, "");
|
||||
|
||||
213
src/chars.c
213
src/chars.c
@@ -70,7 +70,7 @@ bool is_alpha_mbchar(const char *c)
|
||||
wchar_t wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
return iswalpha(wc);
|
||||
} else
|
||||
@@ -86,7 +86,7 @@ bool is_alnum_mbchar(const char *c)
|
||||
wchar_t wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
return iswalnum(wc);
|
||||
} else
|
||||
@@ -102,7 +102,7 @@ bool is_blank_mbchar(const char *c)
|
||||
wchar_t wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
return iswblank(wc);
|
||||
} else
|
||||
@@ -139,7 +139,7 @@ bool is_punct_mbchar(const char *c)
|
||||
wchar_t wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0)
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
return iswpunct(wc);
|
||||
} else
|
||||
@@ -200,36 +200,6 @@ char control_mbrep(const char *c, bool isdata)
|
||||
return control_rep(*c);
|
||||
}
|
||||
|
||||
/* Assess how many bytes the given (multibyte) character occupies. Return -1
|
||||
* if the byte sequence is invalid, and return the number of bytes minus 8
|
||||
* when it encodes an invalid codepoint. Also, in the second parameter,
|
||||
* return the number of columns that the character occupies. */
|
||||
int length_of_char(const char *c, int *width)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
wchar_t wc;
|
||||
int charlen = mbtowc(&wc, c, MAXCHARLEN);
|
||||
|
||||
/* If the sequence is invalid... */
|
||||
if (charlen < 0)
|
||||
return -1;
|
||||
|
||||
/* If the codepoint is invalid... */
|
||||
if (!is_valid_unicode(wc))
|
||||
return charlen - 8;
|
||||
else {
|
||||
*width = wcwidth(wc);
|
||||
/* If the codepoint is unassigned, assume a width of one. */
|
||||
if (*width < 0)
|
||||
*width = 1;
|
||||
return charlen;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This function is equivalent to wcwidth() for multibyte characters. */
|
||||
int mbwidth(const char *c)
|
||||
{
|
||||
@@ -280,6 +250,20 @@ char *make_mbchar(long chr, int *chr_mb_len)
|
||||
return chr_mb;
|
||||
}
|
||||
|
||||
/* Return the length (in bytes) of the character located at *pointer. */
|
||||
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) {
|
||||
int length = mblen(pointer, MAXCHARLEN);
|
||||
|
||||
return (length < 0 ? 1 : length);
|
||||
} else
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Parse a multibyte character from buf. Return the number of bytes
|
||||
* used. If chr isn't NULL, store the multibyte character in it. If
|
||||
* col isn't NULL, add the character's width (in columns) to it. */
|
||||
@@ -328,11 +312,11 @@ int parse_mbchar(const char *buf, char *chr, size_t *col)
|
||||
|
||||
/* Return the index in buf of the beginning of the multibyte character
|
||||
* before the one at pos. */
|
||||
size_t move_mbleft(const char *buf, size_t pos)
|
||||
size_t step_left(const char *buf, size_t pos)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
size_t before, char_len = 0;
|
||||
size_t before, charlen = 0;
|
||||
|
||||
if (pos < 4)
|
||||
before = 0;
|
||||
@@ -355,11 +339,11 @@ size_t move_mbleft(const char *buf, size_t pos)
|
||||
/* Move forward again until we reach the original character,
|
||||
* so we know the length of its preceding character. */
|
||||
while (before < pos) {
|
||||
char_len = parse_mbchar(buf + before, NULL, NULL);
|
||||
before += char_len;
|
||||
charlen = char_length(buf + before);
|
||||
before += charlen;
|
||||
}
|
||||
|
||||
return before - char_len;
|
||||
return before - charlen;
|
||||
} else
|
||||
#endif
|
||||
return (pos == 0 ? 0 : pos - 1);
|
||||
@@ -367,9 +351,9 @@ size_t move_mbleft(const char *buf, size_t pos)
|
||||
|
||||
/* Return the index in buf of the beginning of the multibyte character
|
||||
* after the one at pos. */
|
||||
size_t move_mbright(const char *buf, size_t pos)
|
||||
size_t step_right(const char *buf, size_t pos)
|
||||
{
|
||||
return pos + parse_mbchar(buf + pos, NULL, NULL);
|
||||
return pos + char_length(buf + pos);
|
||||
}
|
||||
|
||||
/* This function is equivalent to strcasecmp() for multibyte strings. */
|
||||
@@ -402,8 +386,8 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n)
|
||||
return difference;
|
||||
}
|
||||
|
||||
s1 += move_mbright(s1, 0);
|
||||
s2 += move_mbright(s2, 0);
|
||||
s1 += char_length(s1);
|
||||
s2 += char_length(s2);
|
||||
n--;
|
||||
}
|
||||
|
||||
@@ -424,13 +408,13 @@ char *mbstrcasestr(const char *haystack, const char *needle)
|
||||
if (mbstrncasecmp(haystack, needle, needle_len) == 0)
|
||||
return (char *)haystack;
|
||||
|
||||
haystack += move_mbright(haystack, 0);
|
||||
haystack += char_length(haystack);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
} else
|
||||
#endif
|
||||
return (char *) strcasestr(haystack, needle);
|
||||
return (char *)strcasestr(haystack, needle);
|
||||
}
|
||||
|
||||
/* This function is equivalent to strstr(), except in that it scans the
|
||||
@@ -496,7 +480,7 @@ char *mbrevstrcasestr(const char *haystack, const char *needle,
|
||||
if (pointer == haystack)
|
||||
return NULL;
|
||||
|
||||
pointer = haystack + move_mbleft(haystack, pointer - haystack);
|
||||
pointer = haystack + step_left(haystack, pointer - haystack);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
@@ -504,134 +488,99 @@ char *mbrevstrcasestr(const char *haystack, const char *needle,
|
||||
}
|
||||
|
||||
/* Count the number of (multibyte) characters in the given string. */
|
||||
size_t mbstrlen(const char *s)
|
||||
size_t mbstrlen(const char *pointer)
|
||||
{
|
||||
size_t maxlen = (size_t)-1;
|
||||
size_t count = 0;
|
||||
|
||||
while (*pointer != '\0') {
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
size_t n = 0;
|
||||
if ((signed char)*pointer < 0) {
|
||||
int length = mblen(pointer, MAXCHARLEN);
|
||||
|
||||
while (*s != '\0' && maxlen > 0) {
|
||||
if ((signed char)*s < 0) {
|
||||
int length = mblen(s, MAXCHARLEN);
|
||||
|
||||
s += (length < 0 ? 1 : length);
|
||||
} else
|
||||
s++;
|
||||
|
||||
maxlen--;
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
} else
|
||||
pointer += (length < 0 ? 1 : length);
|
||||
} else
|
||||
#endif
|
||||
return strnlen(s, maxlen);
|
||||
pointer++;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
|
||||
/* This function is equivalent to strchr() for multibyte strings. */
|
||||
char *mbstrchr(const char *s, const char *c)
|
||||
char *mbstrchr(const char *string, const char *chr)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
bool bad_s_mb = FALSE, bad_c_mb = FALSE;
|
||||
char symbol[MAXCHARLEN];
|
||||
const char *q = s;
|
||||
bool bad_s = FALSE, bad_c = FALSE;
|
||||
wchar_t ws, wc;
|
||||
|
||||
if (mbtowc(&wc, c, MAXCHARLEN) < 0) {
|
||||
wc = (unsigned char)*c;
|
||||
bad_c_mb = TRUE;
|
||||
if (mbtowc(&wc, chr, MAXCHARLEN) < 0) {
|
||||
wc = (unsigned char)*chr;
|
||||
bad_c = TRUE;
|
||||
}
|
||||
|
||||
while (*s != '\0') {
|
||||
int sym_len = parse_mbchar(s, symbol, NULL);
|
||||
while (*string != '\0') {
|
||||
int symlen = mbtowc(&ws, string, MAXCHARLEN);
|
||||
|
||||
if (mbtowc(&ws, symbol, sym_len) < 0) {
|
||||
ws = (unsigned char)*s;
|
||||
bad_s_mb = TRUE;
|
||||
if (symlen < 0) {
|
||||
ws = (unsigned char)*string;
|
||||
bad_s = TRUE;
|
||||
}
|
||||
|
||||
if (bad_s_mb == bad_c_mb && ws == wc)
|
||||
if (ws == wc && bad_s == bad_c)
|
||||
break;
|
||||
|
||||
s += sym_len;
|
||||
q += sym_len;
|
||||
string += symlen;
|
||||
}
|
||||
|
||||
if (*s == '\0')
|
||||
q = NULL;
|
||||
if (*string == '\0')
|
||||
return NULL;
|
||||
|
||||
return (char *)q;
|
||||
return (char *)string;
|
||||
} else
|
||||
#endif
|
||||
return (char *) strchr(s, *c);
|
||||
return strchr(string, *chr);
|
||||
}
|
||||
#endif /* !NANO_TINY || ENABLE_JUSTIFY */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* This function is equivalent to strpbrk() for multibyte strings. */
|
||||
char *mbstrpbrk(const char *s, const char *accept)
|
||||
/* Locate, in the given string, the first occurrence of any of
|
||||
* the characters in accept, searching forward. */
|
||||
char *mbstrpbrk(const char *string, const char *accept)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
for (; *s != '\0'; s += move_mbright(s, 0)) {
|
||||
if (mbstrchr(accept, s) != NULL)
|
||||
return (char *)s;
|
||||
}
|
||||
while (*string != '\0') {
|
||||
if (mbstrchr(accept, string) != NULL)
|
||||
return (char *)string;
|
||||
|
||||
return NULL;
|
||||
} else
|
||||
#endif
|
||||
return (char *) strpbrk(s, accept);
|
||||
}
|
||||
|
||||
/* Locate, in the string that starts at head, the first occurrence of any of
|
||||
* the characters in the string accept, starting from pointer and searching
|
||||
* backwards. */
|
||||
char *revstrpbrk(const char *head, const char *accept, const char *pointer)
|
||||
{
|
||||
if (*pointer == '\0') {
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
pointer--;
|
||||
}
|
||||
|
||||
while (pointer >= head) {
|
||||
if (strchr(accept, *pointer) != NULL)
|
||||
return (char *)pointer;
|
||||
pointer--;
|
||||
string += char_length(string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The same as the preceding function but then for multibyte strings. */
|
||||
/* Locate, in the string that starts at head, the first occurrence of any of
|
||||
* the characters in accept, starting from pointer and searching backwards. */
|
||||
char *mbrevstrpbrk(const char *head, const char *accept, const char *pointer)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
if (*pointer == '\0') {
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
pointer = head + move_mbleft(head, pointer - head);
|
||||
}
|
||||
if (*pointer == '\0') {
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
pointer = head + step_left(head, pointer - head);
|
||||
}
|
||||
|
||||
while (TRUE) {
|
||||
if (mbstrchr(accept, pointer) != NULL)
|
||||
return (char *)pointer;
|
||||
while (TRUE) {
|
||||
if (mbstrchr(accept, pointer) != NULL)
|
||||
return (char *)pointer;
|
||||
|
||||
/* If we've reached the head of the string, we found nothing. */
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
/* If we've reached the head of the string, we found nothing. */
|
||||
if (pointer == head)
|
||||
return NULL;
|
||||
|
||||
pointer = head + move_mbleft(head, pointer - head);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
return revstrpbrk(head, accept, pointer);
|
||||
pointer = head + step_left(head, pointer - head);
|
||||
}
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
|
||||
87
src/color.c
87
src/color.c
@@ -39,11 +39,34 @@
|
||||
#define A_BANDAID A_NORMAL
|
||||
#endif
|
||||
|
||||
/* Assign pair numbers for the colors in the given syntax, giving identical
|
||||
* color pairs the same number. */
|
||||
void set_syntax_colorpairs(syntaxtype *sint)
|
||||
{
|
||||
int new_number = NUMBER_OF_ELEMENTS + 1;
|
||||
colortype *ink;
|
||||
|
||||
for (ink = sint->color; ink != NULL; ink = ink->next) {
|
||||
const colortype *beforenow = sint->color;
|
||||
|
||||
while (beforenow != ink && (beforenow->fg != ink->fg ||
|
||||
beforenow->bg != ink->bg))
|
||||
beforenow = beforenow->next;
|
||||
|
||||
if (beforenow != ink)
|
||||
ink->pairnum = beforenow->pairnum;
|
||||
else
|
||||
ink->pairnum = new_number++;
|
||||
|
||||
ink->attributes |= COLOR_PAIR(ink->pairnum) | A_BANDAID;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the colors for nano's interface, and assign pair numbers
|
||||
* for the colors in each syntax. */
|
||||
* for the colors in each loaded syntax. */
|
||||
void set_colorpairs(void)
|
||||
{
|
||||
const syntaxtype *sint;
|
||||
syntaxtype *sint;
|
||||
bool using_defaults = FALSE;
|
||||
size_t i;
|
||||
|
||||
@@ -82,27 +105,10 @@ void set_colorpairs(void)
|
||||
free(color_combo[i]);
|
||||
}
|
||||
|
||||
/* For each syntax, go through its list of colors and assign each
|
||||
* its pair number, giving identical color pairs the same number. */
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next) {
|
||||
colortype *ink;
|
||||
int new_number = NUMBER_OF_ELEMENTS + 1;
|
||||
|
||||
for (ink = sint->color; ink != NULL; ink = ink->next) {
|
||||
const colortype *beforenow = sint->color;
|
||||
|
||||
while (beforenow != ink && (beforenow->fg != ink->fg ||
|
||||
beforenow->bg != ink->bg))
|
||||
beforenow = beforenow->next;
|
||||
|
||||
if (beforenow != ink)
|
||||
ink->pairnum = beforenow->pairnum;
|
||||
else
|
||||
ink->pairnum = new_number++;
|
||||
|
||||
ink->attributes |= COLOR_PAIR(ink->pairnum) | A_BANDAID;
|
||||
}
|
||||
}
|
||||
/* For each loaded syntax, assign pair numbers to color combinations. */
|
||||
for (sint = syntaxes; sint != NULL; sint = sint->next)
|
||||
if (sint->filename == NULL)
|
||||
set_syntax_colorpairs(sint);
|
||||
}
|
||||
|
||||
/* Initialize the color information. */
|
||||
@@ -163,7 +169,6 @@ bool found_in_list(regexlisttype *head, const char *shibboleth)
|
||||
void color_update(void)
|
||||
{
|
||||
syntaxtype *sint = NULL;
|
||||
colortype *ink;
|
||||
|
||||
/* If the rcfiles were not read, or contained no syntaxes, get out. */
|
||||
if (syntaxes == NULL)
|
||||
@@ -267,22 +272,14 @@ void color_update(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* When the syntax isn't loaded yet, parse it and initialize its colors. */
|
||||
if (sint != NULL && sint->filename != NULL) {
|
||||
parse_one_include(sint->filename, sint);
|
||||
set_syntax_colorpairs(sint);
|
||||
}
|
||||
|
||||
openfile->syntax = sint;
|
||||
openfile->colorstrings = (sint == NULL ? NULL : sint->color);
|
||||
|
||||
/* If a syntax was found, compile its specified regexes (which have
|
||||
* already been checked for validity when they were read in). */
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
if (ink->start == NULL) {
|
||||
ink->start = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(ink->start, ink->start_regex, ink->rex_flags);
|
||||
}
|
||||
|
||||
if (ink->end_regex != NULL && ink->end == NULL) {
|
||||
ink->end = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(ink->end, ink->end_regex, ink->rex_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine whether the matches of multiline regexes are still the same,
|
||||
@@ -334,12 +331,10 @@ void check_the_multis(linestruct *line)
|
||||
/* Allocate (for one line) the cache space for multiline color regexes. */
|
||||
void alloc_multidata_if_needed(linestruct *fileptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (fileptr->multidata == NULL) {
|
||||
fileptr->multidata = (short *)nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
|
||||
for (i = 0; i < openfile->syntax->nmultis; i++)
|
||||
for (int i = 0; i < openfile->syntax->nmultis; i++)
|
||||
fileptr->multidata[i] = -1;
|
||||
}
|
||||
}
|
||||
@@ -355,10 +350,6 @@ void precalc_multicolorinfo(void)
|
||||
if (openfile->colorstrings == NULL || ISSET(NO_COLOR_SYNTAX))
|
||||
return;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Precalculating the multiline color info...\n");
|
||||
#endif
|
||||
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
/* If this is not a multi-line regex, skip it. */
|
||||
if (ink->end == NULL)
|
||||
@@ -380,14 +371,14 @@ void precalc_multicolorinfo(void)
|
||||
/* 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) {
|
||||
&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) {
|
||||
&endmatch, (index == 0) ? 0 : REG_NOTBOL) == 0) {
|
||||
line->multidata[ink->id] = CSTARTENDHERE;
|
||||
index += endmatch.rm_eo;
|
||||
/* If both start and end are mere anchors, step ahead. */
|
||||
@@ -396,7 +387,7 @@ void precalc_multicolorinfo(void)
|
||||
/* When at end-of-line, we're done. */
|
||||
if (line->data[index] == '\0')
|
||||
break;
|
||||
index = move_mbright(line->data, index);
|
||||
index = step_right(line->data, index);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
181
src/cut.c
181
src/cut.c
@@ -35,10 +35,8 @@ void do_deletion(undo_type action)
|
||||
|
||||
/* When in the middle of a line, delete the current character. */
|
||||
if (openfile->current->data[openfile->current_x] != '\0') {
|
||||
int char_len = parse_mbchar(openfile->current->data +
|
||||
openfile->current_x, NULL, NULL);
|
||||
size_t line_len = strlen(openfile->current->data +
|
||||
openfile->current_x);
|
||||
int charlen = char_length(openfile->current->data + openfile->current_x);
|
||||
size_t line_len = strlen(openfile->current->data + openfile->current_x);
|
||||
#ifndef NANO_TINY
|
||||
/* If the type of action changed or the cursor moved to a different
|
||||
* line, create a new undo item, otherwise update the existing item. */
|
||||
@@ -53,13 +51,13 @@ void do_deletion(undo_type action)
|
||||
#endif
|
||||
/* Move the remainder of the line "in", over the current character. */
|
||||
charmove(&openfile->current->data[openfile->current_x],
|
||||
&openfile->current->data[openfile->current_x + char_len],
|
||||
line_len - char_len + 1);
|
||||
&openfile->current->data[openfile->current_x + charlen],
|
||||
line_len - charlen + 1);
|
||||
#ifndef NANO_TINY
|
||||
/* Adjust the mark if it is after the cursor on the current line. */
|
||||
if (openfile->mark == openfile->current &&
|
||||
openfile->mark_x > openfile->current_x)
|
||||
openfile->mark_x -= char_len;
|
||||
openfile->mark_x -= charlen;
|
||||
#endif
|
||||
/* Otherwise, when not at end of buffer, join this line with the next. */
|
||||
} else if (openfile->current != openfile->filebot) {
|
||||
@@ -67,7 +65,7 @@ void do_deletion(undo_type action)
|
||||
|
||||
/* If there is a magic line, and we're before it: don't eat it. */
|
||||
if (joining == openfile->filebot && openfile->current_x != 0 &&
|
||||
ISSET(FINAL_NEWLINE)) {
|
||||
!ISSET(NO_NEWLINES)) {
|
||||
#ifndef NANO_TINY
|
||||
if (action == BACK)
|
||||
add_undo(BACK);
|
||||
@@ -91,7 +89,7 @@ void do_deletion(undo_type action)
|
||||
}
|
||||
#endif
|
||||
unlink_node(joining);
|
||||
renumber(openfile->current);
|
||||
renumber_from(openfile->current);
|
||||
|
||||
/* Two lines were joined, so we need to refresh the screen. */
|
||||
refresh_needed = TRUE;
|
||||
@@ -148,12 +146,10 @@ void chop_word(bool forward)
|
||||
/* Remember the current cursor position. */
|
||||
linestruct *is_current = openfile->current;
|
||||
size_t is_current_x = openfile->current_x;
|
||||
|
||||
/* Remember where the cutbuffer is and then make it seem blank. */
|
||||
/* Remember where the cutbuffer is, then make it seem blank. */
|
||||
linestruct *is_cutbuffer = cutbuffer;
|
||||
linestruct *is_cutbottom = cutbottom;
|
||||
|
||||
cutbuffer = NULL;
|
||||
cutbottom = NULL;
|
||||
|
||||
/* Move the cursor to a word start, to the left or to the right.
|
||||
* If that word is on another line and the cursor was not already
|
||||
@@ -186,12 +182,11 @@ void chop_word(bool forward)
|
||||
openfile->current_x = is_current_x;
|
||||
|
||||
/* Now kill the marked region and a word is gone. */
|
||||
do_cut_text_void();
|
||||
cut_text();
|
||||
|
||||
/* Discard the cut word and restore the cutbuffer. */
|
||||
free_lines(cutbuffer);
|
||||
cutbuffer = is_cutbuffer;
|
||||
cutbottom = is_cutbottom;
|
||||
}
|
||||
|
||||
/* Delete a word leftward. */
|
||||
@@ -203,6 +198,8 @@ void chop_previous_word(void)
|
||||
/* Delete a word rightward. */
|
||||
void chop_next_word(void)
|
||||
{
|
||||
openfile->mark = NULL;
|
||||
|
||||
if (is_cuttable(openfile->current_x > 0))
|
||||
chop_word(FORWARD);
|
||||
}
|
||||
@@ -215,28 +212,15 @@ void cut_line(void)
|
||||
* head of this line to the head of the next line into the cutbuffer;
|
||||
* otherwise, move all of the text of this line into the cutbuffer. */
|
||||
if (openfile->current != openfile->filebot)
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current, 0,
|
||||
openfile->current->next, 0);
|
||||
extract(openfile->current, 0, openfile->current->next, 0);
|
||||
else
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current, 0,
|
||||
extract(openfile->current, 0,
|
||||
openfile->current, strlen(openfile->current->data));
|
||||
|
||||
openfile->placewewant = 0;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Move all marked text from the current buffer into the cutbuffer. */
|
||||
void cut_marked(bool *right_side_up)
|
||||
{
|
||||
linestruct *top, *bot;
|
||||
size_t top_x, bot_x;
|
||||
|
||||
mark_order((const linestruct **)&top, &top_x,
|
||||
(const linestruct **)&bot, &bot_x, right_side_up);
|
||||
|
||||
extract_buffer(&cutbuffer, &cutbottom, top, top_x, bot, bot_x);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
/* Move all text from the cursor position until the end of this line into
|
||||
* the cutbuffer. But when already at the end of a line, then move this
|
||||
* "newline" to the cutbuffer. */
|
||||
@@ -248,87 +232,101 @@ void cut_to_eol(void)
|
||||
* the cutbuffer. Otherwise, when not at the end of the buffer,
|
||||
* move the line separation into the cutbuffer. */
|
||||
if (openfile->current_x < data_len)
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->current, data_len);
|
||||
extract(openfile->current, openfile->current_x,
|
||||
openfile->current, data_len);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
extract_buffer(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->current->next, 0);
|
||||
extract(openfile->current, openfile->current_x,
|
||||
openfile->current->next, 0);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
}
|
||||
|
||||
/* Move all marked text from the current buffer into the cutbuffer. */
|
||||
void cut_marked(bool *right_side_up)
|
||||
{
|
||||
linestruct *top, *bot;
|
||||
size_t top_x, bot_x;
|
||||
|
||||
get_region((const linestruct **)&top, &top_x,
|
||||
(const linestruct **)&bot, &bot_x, right_side_up);
|
||||
|
||||
extract(top, top_x, bot, bot_x);
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
/* Move all text from the cursor position to end-of-file into the cutbuffer. */
|
||||
void cut_to_eof(void)
|
||||
{
|
||||
extract_buffer(&cutbuffer, &cutbottom,
|
||||
openfile->current, openfile->current_x,
|
||||
extract(openfile->current, openfile->current_x,
|
||||
openfile->filebot, strlen(openfile->filebot->data));
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Move text from the current buffer into the cutbuffer. If
|
||||
* copy_text is TRUE, copy the text back into the buffer afterward.
|
||||
* If cut_till_eof is TRUE, move all text from the current cursor
|
||||
* copying is TRUE, copy the text back into the buffer afterward.
|
||||
* If until_eof is TRUE, move all text from the current cursor
|
||||
* position to the end of the file into the cutbuffer. If append
|
||||
* is TRUE (when zapping), always append the cut to the cutbuffer. */
|
||||
void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append)
|
||||
void do_cut_text(bool copying, bool marked, bool until_eof, bool append)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
linestruct *cb_save = NULL;
|
||||
linestruct *was_bottom = NULL;
|
||||
/* The current end of the cutbuffer, before we add text to it. */
|
||||
size_t cb_save_len = 0;
|
||||
size_t botlen = 0;
|
||||
/* The length of the string at the current end of the cutbuffer,
|
||||
* before we add text to it. */
|
||||
bool using_magicline = ISSET(FINAL_NEWLINE);
|
||||
bool using_magicline = !ISSET(NO_NEWLINES);
|
||||
/* Whether an automatic newline should be added at end-of-buffer. */
|
||||
bool right_side_up = TRUE;
|
||||
/* There *is* no region, *or* it is marked forward. */
|
||||
#endif
|
||||
static bool precedent = FALSE;
|
||||
/* Whether the previous operation was a copying operation. */
|
||||
|
||||
/* If cuts were not continuous, or when cutting a region, clear the slate. */
|
||||
if (!append && (!keep_cutbuffer || marked || cut_till_eof)) {
|
||||
if ((!keep_cutbuffer || marked || until_eof || copying != precedent) &&
|
||||
!append) {
|
||||
free_lines(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
/* After a line cut, future line cuts should add to the cutbuffer. */
|
||||
keep_cutbuffer = !marked && !cut_till_eof;
|
||||
}
|
||||
|
||||
/* After a line operation, future ones should add to the cutbuffer. */
|
||||
keep_cutbuffer = !marked && !until_eof;
|
||||
precedent = copying;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (copy_text) {
|
||||
if (copying) {
|
||||
/* If the cutbuffer isn't empty, remember where it currently ends. */
|
||||
if (cutbuffer != NULL) {
|
||||
cb_save = cutbottom;
|
||||
cb_save_len = strlen(cutbottom->data);
|
||||
was_bottom = cutbottom;
|
||||
botlen = strlen(cutbottom->data);
|
||||
}
|
||||
/* Don't add a magic line when moving text to the cutbuffer. */
|
||||
UNSET(FINAL_NEWLINE);
|
||||
SET(NO_NEWLINES);
|
||||
}
|
||||
|
||||
if (cut_till_eof) {
|
||||
/* Move all text up to the end of the file into the cutbuffer. */
|
||||
/* Now move the relevant piece of text into the cutbuffer. */
|
||||
if (until_eof)
|
||||
cut_to_eof();
|
||||
} else if (openfile->mark) {
|
||||
/* Move the marked text to the cutbuffer, and turn the mark off. */
|
||||
else if (openfile->mark) {
|
||||
cut_marked(&right_side_up);
|
||||
openfile->mark = NULL;
|
||||
} else if (ISSET(CUT_FROM_CURSOR))
|
||||
/* Move all text up to the end of the line into the cutbuffer. */
|
||||
cut_to_eol();
|
||||
else
|
||||
#endif
|
||||
/* Move the entire line into the cutbuffer. */
|
||||
cut_line();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (copy_text) {
|
||||
/* Copy the text that is in the cutbuffer (starting at its saved end,
|
||||
* if there is one) back into the current buffer. This effectively
|
||||
* uncuts the text we just cut. */
|
||||
if (copying) {
|
||||
/* Copy the text that was put into the cutbuffer back into the current
|
||||
* file buffer, so that in the end nothing has been deleted. */
|
||||
if (cutbuffer != NULL) {
|
||||
if (cb_save != NULL) {
|
||||
cb_save->data += cb_save_len;
|
||||
copy_from_buffer(cb_save);
|
||||
cb_save->data -= cb_save_len;
|
||||
if (was_bottom != NULL) {
|
||||
was_bottom->data += botlen;
|
||||
copy_from_buffer(was_bottom);
|
||||
was_bottom->data -= botlen;
|
||||
} else
|
||||
copy_from_buffer(cutbuffer);
|
||||
|
||||
@@ -339,11 +337,11 @@ void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append)
|
||||
}
|
||||
/* Restore the magic-line behavior now that we're done fiddling. */
|
||||
if (using_magicline)
|
||||
SET(FINAL_NEWLINE);
|
||||
UNSET(NO_NEWLINES);
|
||||
} else
|
||||
#endif /* !NANO_TINY */
|
||||
#endif
|
||||
set_modified();
|
||||
|
||||
set_modified();
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
@@ -358,8 +356,8 @@ bool is_cuttable(bool test_cliff)
|
||||
(openfile->mark == openfile->current &&
|
||||
openfile->mark_x == openfile->current_x) ||
|
||||
(test_cliff && openfile->current->data[openfile->current_x] == '\0' &&
|
||||
((!ISSET(FINAL_NEWLINE) && openfile->current == openfile->filebot) ||
|
||||
(ISSET(FINAL_NEWLINE) && openfile->current == openfile->filebot->prev))
|
||||
((ISSET(NO_NEWLINES) && openfile->current == openfile->filebot) ||
|
||||
(!ISSET(NO_NEWLINES) && openfile->current == openfile->filebot->prev))
|
||||
#endif
|
||||
)) {
|
||||
#ifndef NANO_TINY
|
||||
@@ -372,7 +370,7 @@ bool is_cuttable(bool test_cliff)
|
||||
}
|
||||
|
||||
/* Move text from the current buffer into the cutbuffer. */
|
||||
void do_cut_text_void(void)
|
||||
void cut_text(void)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
if (!is_cuttable(ISSET(CUT_FROM_CURSOR) && openfile->mark == NULL))
|
||||
@@ -380,11 +378,13 @@ void do_cut_text_void(void)
|
||||
|
||||
/* Only add a new undo item when the current item is not a CUT or when
|
||||
* the current cut is not contiguous with the previous cutting. */
|
||||
if (openfile->last_action != CUT || openfile->current_undo == NULL ||
|
||||
openfile->current_undo->mark_begin_lineno != openfile->current->lineno ||
|
||||
!keep_cutbuffer)
|
||||
if (openfile->last_action != CUT || !keep_cutbuffer) {
|
||||
keep_cutbuffer = FALSE;
|
||||
add_undo(CUT);
|
||||
}
|
||||
|
||||
do_cut_text(FALSE, openfile->mark != NULL, FALSE, FALSE);
|
||||
|
||||
update_undo(CUT);
|
||||
#else
|
||||
if (is_cuttable(FALSE))
|
||||
@@ -396,9 +396,8 @@ void do_cut_text_void(void)
|
||||
/* Move text from the current buffer into the cutbuffer, and copy it
|
||||
* back into the buffer afterward. If the mark is set or the cursor
|
||||
* was moved, blow away previous contents of the cutbuffer. */
|
||||
void do_copy_text(void)
|
||||
void copy_text(void)
|
||||
{
|
||||
static linestruct *next_contiguous_line = NULL;
|
||||
bool mark_is_set = (openfile->mark != NULL);
|
||||
|
||||
/* Remember the current viewport and cursor position. */
|
||||
@@ -407,28 +406,29 @@ void do_copy_text(void)
|
||||
ssize_t is_current_lineno = openfile->current->lineno;
|
||||
size_t is_current_x = openfile->current_x;
|
||||
|
||||
if (mark_is_set || openfile->current != next_contiguous_line)
|
||||
keep_cutbuffer = FALSE;
|
||||
/* If there is nothing to copy, don't even try. */
|
||||
if (openfile->current->next == NULL && openfile->current->data[0] == '\0')
|
||||
return;
|
||||
|
||||
do_cut_text(TRUE, mark_is_set, FALSE, FALSE);
|
||||
|
||||
/* If the mark was set, blow away the cutbuffer on the next copy. */
|
||||
next_contiguous_line = (mark_is_set ? NULL : openfile->current);
|
||||
|
||||
/* If the mark was set, restore the viewport and cursor position. */
|
||||
if (mark_is_set) {
|
||||
openfile->edittop = fsfromline(is_edittop_lineno);
|
||||
openfile->edittop = line_from_number(is_edittop_lineno);
|
||||
openfile->firstcolumn = is_firstcolumn;
|
||||
openfile->current = fsfromline(is_current_lineno);
|
||||
openfile->current = line_from_number(is_current_lineno);
|
||||
openfile->current_x = is_current_x;
|
||||
}
|
||||
} else
|
||||
focusing = FALSE;
|
||||
|
||||
openfile->last_action = OTHER;
|
||||
}
|
||||
|
||||
/* Cut from the current cursor position to the end of the file. */
|
||||
void do_cut_till_eof(void)
|
||||
void cut_till_eof(void)
|
||||
{
|
||||
if ((openfile->current == openfile->filebot && openfile->current->data[0] == '\0') ||
|
||||
(ISSET(FINAL_NEWLINE) && openfile->current->next == openfile->filebot &&
|
||||
(!ISSET(NO_NEWLINES) && openfile->current->next == openfile->filebot &&
|
||||
openfile->current->data[openfile->current_x] == '\0')) {
|
||||
statusbar(_("Nothing was cut"));
|
||||
return;
|
||||
@@ -444,33 +444,28 @@ void zap_text(void)
|
||||
{
|
||||
/* Remember the current cutbuffer so it can be restored after the zap. */
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
linestruct *was_cutbottom = cutbottom;
|
||||
|
||||
if (!is_cuttable(ISSET(CUT_FROM_CURSOR) && openfile->mark == NULL))
|
||||
return;
|
||||
|
||||
/* Add a new undo item only when the current item is not a ZAP or when
|
||||
* the current zap is not contiguous with the previous zapping. */
|
||||
if (openfile->last_action != ZAP || openfile->current_undo == NULL ||
|
||||
openfile->current_undo->mark_begin_lineno != openfile->current->lineno ||
|
||||
openfile->current_undo->xflags & (MARK_WAS_SET|WAS_MARKED_FORWARD))
|
||||
if (openfile->last_action != ZAP || !keep_cutbuffer)
|
||||
add_undo(ZAP);
|
||||
|
||||
/* Use the cutbuffer from the ZAP undo item, so the cut can be undone. */
|
||||
cutbuffer = openfile->current_undo->cutbuffer;
|
||||
cutbottom = openfile->current_undo->cutbottom;
|
||||
|
||||
do_cut_text(FALSE, openfile->mark != NULL, FALSE, TRUE);
|
||||
|
||||
update_undo(ZAP);
|
||||
|
||||
cutbuffer = was_cutbuffer;
|
||||
cutbottom = was_cutbottom;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Copy text from the cutbuffer into the current buffer. */
|
||||
void do_uncut_text(void)
|
||||
void paste_text(void)
|
||||
{
|
||||
ssize_t was_lineno = openfile->current->lineno;
|
||||
/* The line number where we started the paste. */
|
||||
@@ -478,7 +473,7 @@ void do_uncut_text(void)
|
||||
/* The leftedge where we started the paste. */
|
||||
|
||||
if (cutbuffer == NULL) {
|
||||
statusbar(_("The cutbuffer is empty"));
|
||||
statusbar(_("Cutbuffer is empty"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
452
src/files.c
452
src/files.c
@@ -64,37 +64,47 @@ void make_new_buffer(void)
|
||||
{
|
||||
openfilestruct *newnode = nmalloc(sizeof(openfilestruct));
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (openfile == NULL) {
|
||||
/* Make the first open file the only element in the list. */
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
newnode->prev = newnode;
|
||||
newnode->next = newnode;
|
||||
#endif
|
||||
firstfile = newnode;
|
||||
|
||||
startfile = newnode;
|
||||
} else {
|
||||
/* Add the new open file after the current one in the list. */
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
newnode->prev = openfile;
|
||||
newnode->next = openfile->next;
|
||||
openfile->next->prev = newnode;
|
||||
openfile->next = newnode;
|
||||
#endif
|
||||
|
||||
/* There is more than one file open: show "Close" in help lines. */
|
||||
exitfunc->desc = close_tag;
|
||||
more_than_one = !inhelp || more_than_one;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Make the new buffer the current one, and start initializing it. */
|
||||
openfile = newnode;
|
||||
|
||||
openfile->filename = mallocstrcpy(NULL, "");
|
||||
|
||||
initialize_buffer_text();
|
||||
openfile->filetop = make_new_node(NULL);
|
||||
openfile->filetop->data = mallocstrcpy(NULL, "");
|
||||
openfile->filebot = openfile->filetop;
|
||||
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
openfile->current_y = 0;
|
||||
|
||||
openfile->edittop = openfile->filetop;
|
||||
openfile->firstcolumn = 0;
|
||||
|
||||
openfile->totsize = 0;
|
||||
openfile->modified = FALSE;
|
||||
#ifdef ENABLE_WRAPPING
|
||||
openfile->spillage_line = NULL;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
openfile->mark = NULL;
|
||||
|
||||
@@ -114,21 +124,6 @@ void make_new_buffer(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the text and pointers of the current openfile struct. */
|
||||
void initialize_buffer_text(void)
|
||||
{
|
||||
openfile->filetop = make_new_node(NULL);
|
||||
openfile->filetop->data = mallocstrcpy(NULL, "");
|
||||
|
||||
openfile->filebot = openfile->filetop;
|
||||
openfile->edittop = openfile->filetop;
|
||||
openfile->current = openfile->filetop;
|
||||
|
||||
openfile->firstcolumn = 0;
|
||||
openfile->current_x = 0;
|
||||
openfile->totsize = 0;
|
||||
}
|
||||
|
||||
/* Mark the current file as modified if it isn't already, and then
|
||||
* update the titlebar to display the file's new status. */
|
||||
void set_modified(void)
|
||||
@@ -271,7 +266,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
goto free_the_data;
|
||||
}
|
||||
|
||||
openfile->lock_filename = (char *) lockfilename;
|
||||
openfile->lock_filename = (char *)lockfilename;
|
||||
|
||||
free(lockdata);
|
||||
return 1;
|
||||
@@ -300,8 +295,8 @@ int delete_lockfile(const char *lockfilename)
|
||||
* creating the lockfile but we should continue to load the file. */
|
||||
int do_lockfile(const char *filename)
|
||||
{
|
||||
char *namecopy = (char *) mallocstrcpy(NULL, filename);
|
||||
char *secondcopy = (char *) mallocstrcpy(NULL, filename);
|
||||
char *namecopy = mallocstrcpy(NULL, filename);
|
||||
char *secondcopy = mallocstrcpy(NULL, filename);
|
||||
size_t locknamesize = strlen(filename) + strlen(locking_prefix)
|
||||
+ strlen(locking_suffix) + 3;
|
||||
char *lockfilename = charalloc(locknamesize);
|
||||
@@ -353,13 +348,13 @@ int do_lockfile(const char *filename)
|
||||
|
||||
/* TRANSLATORS: The second %s is the name of the user, the third that of the editor. */
|
||||
question = _("File %s is being edited (by %s with %s, PID %s); continue?");
|
||||
room = COLS - strlenpt(question) + 7 - strlenpt(lockuser) -
|
||||
strlenpt(lockprog) - strlenpt(pidstring);
|
||||
room = COLS - breadth(question) + 7 - breadth(lockuser) -
|
||||
breadth(lockprog) - breadth(pidstring);
|
||||
if (room < 4)
|
||||
postedname = mallocstrcpy(NULL, "_");
|
||||
else if (room < strlenpt(filename)) {
|
||||
else if (room < breadth(filename)) {
|
||||
char *fragment = display_string(filename,
|
||||
strlenpt(filename) - room + 3, room, FALSE, FALSE);
|
||||
breadth(filename) - room + 3, room, FALSE, FALSE);
|
||||
postedname = charalloc(strlen(fragment) + 4);
|
||||
strcpy(postedname, "...");
|
||||
strcat(postedname, fragment);
|
||||
@@ -416,6 +411,7 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
{
|
||||
char *realname;
|
||||
/* The filename after tilde expansion. */
|
||||
struct stat fileinfo;
|
||||
FILE *f;
|
||||
int rc;
|
||||
/* rc == -2 means that we have a new file. -1 means that the
|
||||
@@ -434,20 +430,25 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
|
||||
realname = real_dir_from_tilde(filename);
|
||||
|
||||
/* When the specified filename is not empty, and the corresponding
|
||||
* file exists, verify that it is a normal file. */
|
||||
if (*filename != '\0') {
|
||||
struct stat fileinfo;
|
||||
|
||||
if (stat(realname, &fileinfo) == 0 && !(S_ISREG(fileinfo.st_mode) ||
|
||||
(ISSET(NOREAD_MODE) && S_ISFIFO(fileinfo.st_mode)))) {
|
||||
if (S_ISDIR(fileinfo.st_mode))
|
||||
statusline(ALERT, _("\"%s\" is a directory"), realname);
|
||||
else
|
||||
statusline(ALERT, _("\"%s\" is not a normal file"), realname);
|
||||
/* Don't try to open directories, character files, or block files. */
|
||||
if (*filename != '\0' && stat(realname, &fileinfo) == 0) {
|
||||
if (S_ISDIR(fileinfo.st_mode)) {
|
||||
statusline(ALERT, _("\"%s\" is a directory"), realname);
|
||||
free(realname);
|
||||
return FALSE;
|
||||
}
|
||||
if (S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode)) {
|
||||
statusline(ALERT, _("\"%s\" is a device file"), realname);
|
||||
free(realname);
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef NANO_TINY
|
||||
if (S_ISFIFO(fileinfo.st_mode)) {
|
||||
statusline(ALERT, _("\"%s\" is a FIFO"), realname);
|
||||
free(realname);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If we're going to load into a new buffer, first create the new
|
||||
@@ -455,13 +456,14 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
if (new_buffer) {
|
||||
make_new_buffer();
|
||||
|
||||
if (!inhelp && has_valid_path(realname)) {
|
||||
if (has_valid_path(realname)) {
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(LOCKING) && filename[0] != '\0') {
|
||||
/* When not overriding an existing lock, discard the buffer. */
|
||||
if (do_lockfile(realname) < 0) {
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
close_buffer();
|
||||
if (openfile != openfile->next)
|
||||
close_buffer();
|
||||
#endif
|
||||
free(realname);
|
||||
return FALSE;
|
||||
@@ -474,12 +476,17 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
/* If the filename isn't blank, and we are not in NOREAD_MODE,
|
||||
* open the file. Otherwise, treat it as a new file. */
|
||||
rc = (filename[0] != '\0' && !ISSET(NOREAD_MODE)) ?
|
||||
open_file(realname, new_buffer, inhelp, &f) : -2;
|
||||
open_file(realname, new_buffer, &f) : -2;
|
||||
|
||||
/* If we have a non-new file, read it in. Then, if the buffer has
|
||||
* no stat, update the stat, if applicable. */
|
||||
if (rc > 0) {
|
||||
install_handler_for_Ctrl_C();
|
||||
|
||||
read_file(f, rc, realname, !new_buffer);
|
||||
|
||||
restore_handler_for_Ctrl_C();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->current_stat == NULL)
|
||||
stat_with_alloc(realname, &openfile->current_stat);
|
||||
@@ -506,90 +513,51 @@ bool open_buffer(const char *filename, bool new_buffer)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SPELLER
|
||||
/* Open the specified file, and if that succeeds, blow away the text of
|
||||
* the current buffer and read the file contents into its place. */
|
||||
void replace_buffer(const char *filename)
|
||||
/* Open the specified file, and if that succeeds, remove the text of the marked
|
||||
* region or of the entire buffer and read the file contents into its place. */
|
||||
bool replace_buffer(const char *filename, undo_type action, bool marked)
|
||||
{
|
||||
FILE *f;
|
||||
int descriptor;
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
int descriptor;
|
||||
FILE *f;
|
||||
|
||||
/* Open the file quietly. */
|
||||
descriptor = open_file(filename, FALSE, TRUE, &f);
|
||||
descriptor = open_file(filename, FALSE, &f);
|
||||
|
||||
/* If opening failed, forget it. */
|
||||
if (descriptor < 0)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(COUPLE_BEGIN);
|
||||
openfile->undotop->strdata = mallocstrcpy(NULL, _("spelling correction"));
|
||||
#endif
|
||||
|
||||
/* Throw away the text of the file. */
|
||||
/* When nothing is marked, start at the top of the buffer. */
|
||||
if (!marked) {
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
|
||||
/* Throw away the marked region or the whole buffer. */
|
||||
cutbuffer = NULL;
|
||||
openfile->current = openfile->filetop;
|
||||
openfile->current_x = 0;
|
||||
#ifndef NANO_TINY
|
||||
add_undo(CUT_TO_EOF);
|
||||
add_undo(action);
|
||||
#endif
|
||||
do_cut_text(FALSE, FALSE, TRUE, FALSE);
|
||||
do_cut_text(FALSE, marked, !marked, FALSE);
|
||||
#ifndef NANO_TINY
|
||||
update_undo(CUT_TO_EOF);
|
||||
update_undo(action);
|
||||
#endif
|
||||
free_lines(cutbuffer);
|
||||
cutbuffer = was_cutbuffer;
|
||||
|
||||
/* Insert the processed file into its place. */
|
||||
/* Insert the spell-checked file into the cleared area. */
|
||||
read_file(f, descriptor, filename, TRUE);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_undo(COUPLE_END);
|
||||
openfile->undotop->strdata = mallocstrcpy(NULL, _("spelling correction"));
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Open the specified file, and if that succeeds, blow away the text of
|
||||
* the current buffer covered by the mark and read the file
|
||||
* contents into its place. */
|
||||
void replace_marked_buffer(const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int descriptor;
|
||||
bool using_magicline = ISSET(FINAL_NEWLINE);
|
||||
linestruct *was_cutbuffer = cutbuffer;
|
||||
|
||||
descriptor = open_file(filename, FALSE, TRUE, &f);
|
||||
|
||||
if (descriptor < 0)
|
||||
return;
|
||||
|
||||
/* Don't add a magic line when replacing text in the buffer. */
|
||||
UNSET(FINAL_NEWLINE);
|
||||
|
||||
add_undo(COUPLE_BEGIN);
|
||||
openfile->undotop->strdata = mallocstrcpy(NULL, _("spelling correction"));
|
||||
|
||||
/* Throw away the text under the mark. */
|
||||
cutbuffer = NULL;
|
||||
add_undo(CUT);
|
||||
do_cut_text(FALSE, TRUE, FALSE, FALSE);
|
||||
update_undo(CUT);
|
||||
free_lines(cutbuffer);
|
||||
cutbuffer = was_cutbuffer;
|
||||
|
||||
/* Insert the processed file where the marked text was. */
|
||||
read_file(f, descriptor, filename, TRUE);
|
||||
|
||||
/* Restore the magic-line behavior now that we're done fiddling. */
|
||||
if (using_magicline)
|
||||
SET(FINAL_NEWLINE);
|
||||
|
||||
add_undo(COUPLE_END);
|
||||
openfile->undotop->strdata = mallocstrcpy(NULL, _("spelling correction"));
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
#endif /* ENABLE_SPELLER */
|
||||
|
||||
/* Update the titlebar and the multiline cache to match the current buffer. */
|
||||
@@ -631,19 +599,15 @@ void mention_name_and_linecount(void)
|
||||
_("New Buffer") : tail(openfile->filename), count);
|
||||
}
|
||||
|
||||
/* Switch to a neighbouring file buffer; to the next if to_next is TRUE;
|
||||
* otherwise, to the previous one. */
|
||||
void switch_to_adjacent_buffer(bool to_next)
|
||||
/* Update title bar and such after switching to another buffer.*/
|
||||
void redecorate_after_switch(void)
|
||||
{
|
||||
/* If only one file buffer is open, say so and get out. */
|
||||
/* If only one file buffer is open, there is nothing to update. */
|
||||
if (openfile == openfile->next) {
|
||||
statusbar(_("No more open file buffers"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Switch to the next or previous file buffer. */
|
||||
openfile = to_next ? openfile->next : openfile->prev;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When not in softwrap mode, make sure firstcolumn is zero. It might
|
||||
* be nonzero if we had softwrap mode on while in this buffer, and then
|
||||
@@ -655,9 +619,6 @@ void switch_to_adjacent_buffer(bool to_next)
|
||||
/* Update titlebar and multiline info to match the current buffer. */
|
||||
prepare_for_display();
|
||||
|
||||
if (inhelp)
|
||||
return;
|
||||
|
||||
/* Ensure that the main loop will redraw the help lines. */
|
||||
currmenu = MMOST;
|
||||
|
||||
@@ -671,78 +632,46 @@ void switch_to_adjacent_buffer(bool to_next)
|
||||
/* Switch to the previous entry in the list of open files. */
|
||||
void switch_to_prev_buffer(void)
|
||||
{
|
||||
switch_to_adjacent_buffer(BACKWARD);
|
||||
openfile = openfile->prev;
|
||||
redecorate_after_switch();
|
||||
}
|
||||
|
||||
/* Switch to the next entry in the list of open files. */
|
||||
void switch_to_next_buffer(void)
|
||||
{
|
||||
switch_to_adjacent_buffer(FORWARD);
|
||||
openfile = openfile->next;
|
||||
redecorate_after_switch();
|
||||
}
|
||||
|
||||
/* Delete an entry from the circular list of open files, and switch to the
|
||||
* one after it. Return FALSE if just one buffer is open, otherwise TRUE. */
|
||||
bool close_buffer(void)
|
||||
/* Remove the current buffer from the circular list of buffers. */
|
||||
void close_buffer(void)
|
||||
{
|
||||
if (openfile == openfile->next)
|
||||
return FALSE;
|
||||
openfilestruct *orphan = openfile;
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
if (ISSET(POSITIONLOG))
|
||||
update_poshistory(openfile->filename,
|
||||
openfile->current->lineno, xplustabs() + 1);
|
||||
if (orphan == startfile)
|
||||
startfile = startfile->next;
|
||||
|
||||
orphan->prev->next = orphan->next;
|
||||
orphan->next->prev = orphan->prev;
|
||||
|
||||
free(orphan->filename);
|
||||
free_lines(orphan->filetop);
|
||||
#ifndef NANO_TINY
|
||||
free(orphan->current_stat);
|
||||
free(orphan->lock_filename);
|
||||
/* Free the undo stack. */
|
||||
discard_until(NULL, orphan, TRUE);
|
||||
#endif
|
||||
|
||||
switch_to_next_buffer();
|
||||
openfile = orphan->prev;
|
||||
free(orphan);
|
||||
|
||||
/* Delete the old file buffer, and adjust the count in the top bar. */
|
||||
unlink_opennode(openfile->prev);
|
||||
if (!inhelp)
|
||||
titlebar(NULL);
|
||||
|
||||
/* If now just one buffer remains open, show "Exit" in the help lines. */
|
||||
/* When just one buffer remains open, show "Exit" in the help lines. */
|
||||
if (openfile == openfile->next)
|
||||
exitfunc->desc = exit_tag;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* ENABLE_MULTIBUFFER */
|
||||
|
||||
/* Do a quick permissions check by verifying whether the file is appendable.
|
||||
* Err on the side of permissiveness (reporting TRUE when it might be wrong)
|
||||
* to not fluster users editing on odd filesystems by printing incorrect
|
||||
* warnings. */
|
||||
int is_file_writable(const char *filename)
|
||||
{
|
||||
char *full_filename;
|
||||
struct stat fileinfo;
|
||||
int fd;
|
||||
FILE *f;
|
||||
bool result = TRUE;
|
||||
|
||||
if (ISSET(VIEW_MODE))
|
||||
return TRUE;
|
||||
|
||||
full_filename = get_full_path(filename);
|
||||
|
||||
/* If the absolute path is unusable, use the given relative one. */
|
||||
if (full_filename == NULL || stat(full_filename, &fileinfo) == -1)
|
||||
full_filename = mallocstrcpy(NULL, filename);
|
||||
|
||||
if ((fd = open(full_filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR |
|
||||
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1)
|
||||
result = FALSE;
|
||||
else if ((f = fdopen(fd, "a")) == NULL) {
|
||||
result = FALSE;
|
||||
close(fd);
|
||||
} else
|
||||
fclose(f);
|
||||
|
||||
free(full_filename);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Encode any NUL bytes in the given line of text, which is of length buf_len,
|
||||
* and return a dynamically allocated copy of the resultant string. */
|
||||
char *encode_data(char *buf, size_t buf_len)
|
||||
@@ -779,6 +708,8 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
int input_int;
|
||||
/* The current value we read from the file, whether an input
|
||||
* character or EOF. */
|
||||
int errornumber;
|
||||
/* The error code, in case an error occurred during reading. */
|
||||
bool writable = TRUE;
|
||||
/* Whether the file is writable (in case we care). */
|
||||
#ifndef NANO_TINY
|
||||
@@ -800,12 +731,24 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
topline = make_new_node(NULL);
|
||||
bottomline = topline;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
block_sigwinch(TRUE);
|
||||
#endif
|
||||
|
||||
/* Lock the file before starting to read it, to avoid the overhead
|
||||
* of locking it for each single byte that we read from it. */
|
||||
flockfile(f);
|
||||
|
||||
control_C_was_pressed = FALSE;
|
||||
|
||||
/* Read the entire file into the new buffer. */
|
||||
while ((input_int = getc_unlocked(f)) != EOF) {
|
||||
|
||||
if (control_C_was_pressed) {
|
||||
statusline(ALERT, _("Interrupted"));
|
||||
break;
|
||||
}
|
||||
|
||||
input = (char)input_int;
|
||||
|
||||
/* If it's a *nix file ("\n") or a DOS file ("\r\n"), and file
|
||||
@@ -872,16 +815,31 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
#endif
|
||||
}
|
||||
|
||||
errornumber = errno;
|
||||
|
||||
/* We are done with the file, unlock it. */
|
||||
funlockfile(f);
|
||||
|
||||
/* Perhaps this could use some better handling. */
|
||||
if (ferror(f))
|
||||
nperror(filename);
|
||||
#ifndef NANO_TINY
|
||||
block_sigwinch(FALSE);
|
||||
#endif
|
||||
|
||||
/* When reading from stdin, restore the terminal and reenter curses mode. */
|
||||
if (isendwin()) {
|
||||
if (!isatty(STANDARD_INPUT))
|
||||
reconnect_and_store_state();
|
||||
terminal_init();
|
||||
doupdate();
|
||||
}
|
||||
|
||||
/* If there was a real error during the reading, let the user know. */
|
||||
if (ferror(f) && errornumber != EINTR && errornumber != 0)
|
||||
statusline(ALERT, strerror(errornumber));
|
||||
fclose(f);
|
||||
|
||||
if (fd > 0 && !undoable) {
|
||||
close(fd);
|
||||
writable = is_file_writable(filename);
|
||||
writable = (ISSET(VIEW_MODE) || access(filename, W_OK) == 0);
|
||||
}
|
||||
|
||||
/* If the file ended with newline, or it was entirely empty, make the
|
||||
@@ -925,10 +883,6 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
/* Set the desired x position at the end of what was inserted. */
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* If we've read a help file, don't give any feedback. */
|
||||
if (inhelp)
|
||||
return;
|
||||
|
||||
if (!writable)
|
||||
statusline(ALERT, _("File '%s' is unwritable"), filename);
|
||||
#ifndef NANO_TINY
|
||||
@@ -970,7 +924,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
* "New File" if newfie is TRUE, and say "File not found" otherwise.
|
||||
* Return -2 if we say "New File", -1 if the file isn't opened, and the
|
||||
* obtained fd otherwise. *f is set to the opened file. */
|
||||
int open_file(const char *filename, bool newfie, bool quiet, FILE **f)
|
||||
int open_file(const char *filename, bool newfie, FILE **f)
|
||||
{
|
||||
struct stat fileinfo, fileinfo2;
|
||||
int fd;
|
||||
@@ -984,8 +938,7 @@ int open_file(const char *filename, bool newfie, bool quiet, FILE **f)
|
||||
|
||||
if (stat(full_filename, &fileinfo) == -1) {
|
||||
if (newfie) {
|
||||
if (!quiet)
|
||||
statusbar(_("New File"));
|
||||
statusbar(_("New File"));
|
||||
free(full_filename);
|
||||
return -2;
|
||||
}
|
||||
@@ -995,30 +948,37 @@ int open_file(const char *filename, bool newfie, bool quiet, FILE **f)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Don't open directories, character files, or block files. */
|
||||
if (S_ISDIR(fileinfo.st_mode) || S_ISCHR(fileinfo.st_mode) ||
|
||||
S_ISBLK(fileinfo.st_mode)) {
|
||||
statusline(ALERT, S_ISDIR(fileinfo.st_mode) ?
|
||||
_("\"%s\" is a directory") :
|
||||
_("\"%s\" is a device file"), filename);
|
||||
free(full_filename);
|
||||
return -1;
|
||||
}
|
||||
#ifndef NANO_TINY
|
||||
if (S_ISFIFO(fileinfo.st_mode))
|
||||
statusbar(_("Reading from FIFO..."));
|
||||
|
||||
block_sigwinch(TRUE);
|
||||
install_handler_for_Ctrl_C();
|
||||
#endif
|
||||
|
||||
/* Try opening the file. */
|
||||
fd = open(full_filename, O_RDONLY);
|
||||
|
||||
if (fd == -1)
|
||||
statusline(ALERT, _("Error reading %s: %s"), filename, strerror(errno));
|
||||
else {
|
||||
#ifndef NANO_TINY
|
||||
restore_handler_for_Ctrl_C();
|
||||
block_sigwinch(FALSE);
|
||||
#endif
|
||||
|
||||
if (fd == -1) {
|
||||
if (errno == EINTR || errno == 0)
|
||||
statusline(ALERT, _("Interrupted"));
|
||||
else
|
||||
statusline(ALERT, _("Error reading %s: %s"), filename, strerror(errno));
|
||||
} else {
|
||||
/* The file is A-OK. Associate a stream with it. */
|
||||
*f = fdopen(fd, "rb");
|
||||
|
||||
if (*f == NULL) {
|
||||
statusline(ALERT, _("Error reading %s: %s"), filename, strerror(errno));
|
||||
close(fd);
|
||||
} else if (!inhelp)
|
||||
statusbar(_("Reading File"));
|
||||
fd = -1;
|
||||
} else
|
||||
statusbar(_("Reading..."));
|
||||
}
|
||||
|
||||
free(full_filename);
|
||||
@@ -1066,7 +1026,7 @@ char *get_next_filename(const char *name, const char *suffix)
|
||||
* the MULTIBUFFER flag is set. */
|
||||
void do_insertfile(void)
|
||||
{
|
||||
int i;
|
||||
int response;
|
||||
const char *msg;
|
||||
char *given = mallocstrcpy(NULL, "");
|
||||
/* The last answer the user typed at the statusbar prompt. */
|
||||
@@ -1111,30 +1071,30 @@ void do_insertfile(void)
|
||||
|
||||
present_path = mallocstrcpy(present_path, "./");
|
||||
|
||||
i = do_prompt(TRUE, TRUE,
|
||||
response = do_prompt(TRUE, TRUE,
|
||||
#ifndef NANO_TINY
|
||||
execute ? MEXTCMD :
|
||||
execute ? MEXTCMD :
|
||||
#endif
|
||||
MINSERTFILE, given,
|
||||
MINSERTFILE, given,
|
||||
#ifndef NANO_TINY
|
||||
execute ? &execute_history :
|
||||
execute ? &execute_history :
|
||||
#endif
|
||||
NULL, edit_refresh, msg,
|
||||
NULL, edit_refresh, msg,
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
operating_dir != NULL ? operating_dir :
|
||||
operating_dir != NULL ? operating_dir :
|
||||
#endif
|
||||
"./");
|
||||
"./");
|
||||
|
||||
/* If we're in multibuffer mode and the filename or command is
|
||||
* blank, open a new buffer instead of canceling. */
|
||||
if (i == -1 || (i == -2 && !ISSET(MULTIBUFFER))) {
|
||||
if (response == -1 || (response == -2 && !ISSET(MULTIBUFFER))) {
|
||||
statusbar(_("Cancelled"));
|
||||
break;
|
||||
} else {
|
||||
ssize_t was_current_lineno = openfile->current->lineno;
|
||||
size_t was_current_x = openfile->current_x;
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_BROWSER) || defined(ENABLE_MULTIBUFFER)
|
||||
functionptrtype func = func_from_key(&i);
|
||||
functionptrtype func = func_from_key(&response);
|
||||
#endif
|
||||
given = mallocstrcpy(given, answer);
|
||||
|
||||
@@ -1168,7 +1128,7 @@ void do_insertfile(void)
|
||||
|
||||
free(answer);
|
||||
answer = chosen;
|
||||
i = 0;
|
||||
response = 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
@@ -1179,7 +1139,7 @@ void do_insertfile(void)
|
||||
}
|
||||
#endif
|
||||
/* If we don't have a file yet, go back to the prompt. */
|
||||
if (i != 0 && (!ISSET(MULTIBUFFER) || i != -2))
|
||||
if (response != 0 && (!ISSET(MULTIBUFFER) || response != -2))
|
||||
continue;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -1329,8 +1289,6 @@ char *get_full_path(const char *origpath)
|
||||
/* If we didn't find one, then make sure the answer is in the format
|
||||
* "d_here/d_there". */
|
||||
if (last_slash == NULL) {
|
||||
assert(!path_only);
|
||||
|
||||
d_there_file = d_there;
|
||||
d_there = d_here;
|
||||
} else {
|
||||
@@ -1549,8 +1507,6 @@ int copy_file(FILE *inn, FILE *out, bool close_out)
|
||||
size_t charsread;
|
||||
int (*flush_out_fnc)(FILE *) = (close_out) ? fclose : fflush;
|
||||
|
||||
assert(inn != NULL && out != NULL && inn != out);
|
||||
|
||||
do {
|
||||
charsread = fread(buf, sizeof(char), BUFSIZ, inn);
|
||||
if (charsread == 0 && ferror(inn)) {
|
||||
@@ -1599,10 +1555,8 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
mode_t original_umask = 0;
|
||||
/* Our umask, from when nano started. */
|
||||
#ifndef NANO_TINY
|
||||
bool realexists;
|
||||
/* The result of stat(). TRUE if the file exists, FALSE
|
||||
* otherwise. If name is a link that points nowhere, realexists
|
||||
* is FALSE. */
|
||||
bool isactualfile = FALSE;
|
||||
/* TRUE when the file is non-temporary and exists, FALSE otherwise. */
|
||||
#endif
|
||||
struct stat st;
|
||||
/* The status fields filled in by stat(). */
|
||||
@@ -1636,21 +1590,20 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Check whether the file (at the end of the symlink) exists. */
|
||||
realexists = (stat(realname, &st) != -1);
|
||||
if (!tmp)
|
||||
isactualfile = (stat(realname, &st) != -1);
|
||||
|
||||
/* If we haven't stat()d this file before (say, the user just
|
||||
* specified it interactively), stat and save the value now,
|
||||
* or else we will chase null pointers when we do modtime checks,
|
||||
* preserve file times, and so on, during backup. */
|
||||
if (openfile->current_stat == NULL && !tmp && realexists)
|
||||
/* If we haven't stat()d this file before (say, the user just specified
|
||||
* it interactively), stat and save the value now, or else we will chase
|
||||
* null pointers when we do modtime checks and such during backup. */
|
||||
if (openfile->current_stat == NULL && isactualfile)
|
||||
stat_with_alloc(realname, &openfile->current_stat);
|
||||
|
||||
/* We backup only if the backup toggle is set, the file isn't
|
||||
* temporary, and the file already exists. Furthermore, if we
|
||||
* aren't appending, prepending, or writing a selection, we backup
|
||||
* only if the file has not been modified by someone else since nano
|
||||
* opened it. */
|
||||
if (ISSET(BACKUP_FILE) && !tmp && realexists && openfile->current_stat &&
|
||||
/* We back up only if the backup toggle is set, and the file exists and
|
||||
* isn't temporary. Furthermore, if we aren't appending, prepending, or
|
||||
* writing a selection, we back up only if the file has not been modified
|
||||
* by someone else since nano opened it. */
|
||||
if (ISSET(BACKUP_FILE) && isactualfile && openfile->current_stat &&
|
||||
(method != OVERWRITE || openfile->mark ||
|
||||
openfile->current_stat->st_mtime == st.st_mtime)) {
|
||||
static struct timespec filetime[2];
|
||||
@@ -1777,10 +1730,6 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Backing up %s to %s\n", realname, backupname);
|
||||
#endif
|
||||
|
||||
/* Copy the file. */
|
||||
if (copy_file(f, backup_file, FALSE) != 0) {
|
||||
fclose(backup_file);
|
||||
@@ -1803,7 +1752,7 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
free(backupname);
|
||||
}
|
||||
|
||||
skip_backup:
|
||||
skip_backup:
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
if (f_open == NULL) {
|
||||
@@ -1863,21 +1812,35 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (S_ISFIFO(st.st_mode))
|
||||
statusbar(_("Writing to FIFO..."));
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
if (f_open == NULL) {
|
||||
#ifndef NANO_TINY
|
||||
block_sigwinch(TRUE);
|
||||
install_handler_for_Ctrl_C();
|
||||
#endif
|
||||
/* Now open the file in place. Use O_EXCL if tmp is TRUE. This
|
||||
* is copied from joe, because wiggy says so *shrug*. */
|
||||
fd = open(realname, O_WRONLY | O_CREAT | ((method == APPEND) ?
|
||||
O_APPEND : (tmp ? O_EXCL : O_TRUNC)), S_IRUSR |
|
||||
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
restore_handler_for_Ctrl_C();
|
||||
block_sigwinch(FALSE);
|
||||
#endif
|
||||
/* Set the umask back to the user's original value. */
|
||||
umask(original_umask);
|
||||
|
||||
/* If we couldn't open the file, give up. */
|
||||
if (fd == -1) {
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
if (errno == EINTR || errno == 0)
|
||||
statusline(ALERT, _("Interrupted"));
|
||||
else
|
||||
statusline(ALERT, _("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
if (tempname != NULL)
|
||||
unlink(tempname);
|
||||
@@ -1894,6 +1857,9 @@ bool write_file(const char *name, FILE *f_open, bool tmp,
|
||||
}
|
||||
}
|
||||
|
||||
if (!tmp)
|
||||
statusbar(_("Writing..."));
|
||||
|
||||
while (fileptr != NULL) {
|
||||
size_t data_len = strlen(fileptr->data), size;
|
||||
|
||||
@@ -2048,13 +2014,13 @@ bool write_marked_file(const char *name, FILE *f_open, bool tmp,
|
||||
size_t top_x, bot_x;
|
||||
|
||||
/* Partition the buffer so that it contains only the marked text. */
|
||||
mark_order((const linestruct **)&top, &top_x,
|
||||
get_region((const linestruct **)&top, &top_x,
|
||||
(const linestruct **)&bot, &bot_x, NULL);
|
||||
filepart = partition_buffer(top, top_x, bot, bot_x);
|
||||
partition_buffer(top, top_x, bot, bot_x);
|
||||
|
||||
/* If we are using a magic line, and the last line of the partition
|
||||
* isn't blank, then add a newline at the end of the buffer. */
|
||||
if (ISSET(FINAL_NEWLINE) && openfile->filebot->data[0] != '\0') {
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0') {
|
||||
new_magicline();
|
||||
added_magicline = TRUE;
|
||||
}
|
||||
@@ -2065,7 +2031,7 @@ bool write_marked_file(const char *name, FILE *f_open, bool tmp,
|
||||
remove_magicline();
|
||||
|
||||
/* Unpartition the buffer so that it contains all the text again. */
|
||||
unpartition_buffer(&filepart);
|
||||
unpartition_buffer();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -2101,7 +2067,7 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
|
||||
while (TRUE) {
|
||||
const char *msg;
|
||||
int response, choice;
|
||||
int response = 0, choice = 0;
|
||||
functionptrtype func;
|
||||
#ifndef NANO_TINY
|
||||
const char *formatstr, *backupstr;
|
||||
@@ -2256,7 +2222,7 @@ int do_writeout(bool exiting, bool withprompt)
|
||||
if (name_exists) {
|
||||
char *question = _("File \"%s\" exists; OVERWRITE? ");
|
||||
char *name = display_string(answer, 0,
|
||||
COLS - strlenpt(question) + 1, FALSE, FALSE);
|
||||
COLS - breadth(question) + 1, FALSE, FALSE);
|
||||
char *message = charalloc(strlen(question) +
|
||||
strlen(name) + 1);
|
||||
|
||||
@@ -2453,8 +2419,6 @@ char **username_tab_completion(const char *buf, size_t *num_matches,
|
||||
const struct passwd *userdata;
|
||||
#endif
|
||||
|
||||
assert(buf != NULL && num_matches != NULL && buf_len > 0);
|
||||
|
||||
*num_matches = 0;
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
@@ -2519,8 +2483,6 @@ char **cwd_tab_completion(const char *buf, bool allow_files,
|
||||
dirname = mallocstrcpy(NULL, present_path);
|
||||
}
|
||||
|
||||
assert(dirname[strlen(dirname) - 1] == '/');
|
||||
|
||||
dir = opendir(dirname);
|
||||
|
||||
if (dir == NULL) {
|
||||
@@ -2584,9 +2546,6 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
size_t num_matches = 0, buf_len;
|
||||
char **matches = NULL;
|
||||
|
||||
assert(buf != NULL && place != NULL && *place <= strlen(buf) &&
|
||||
lastwastab != NULL && refresh_func != NULL && listed != NULL);
|
||||
|
||||
*listed = FALSE;
|
||||
|
||||
/* If the word starts with `~' and there is no slash in the word,
|
||||
@@ -2643,14 +2602,9 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
glued = charalloc(strlen(present_path) + strlen(mzero) + 1);
|
||||
sprintf(glued, "%s%s", present_path, mzero);
|
||||
|
||||
assert(common_len >= *place);
|
||||
|
||||
if (num_matches == 1 && (is_dir(mzero) || is_dir(glued))) {
|
||||
if (num_matches == 1 && (is_dir(mzero) || is_dir(glued)))
|
||||
mzero[common_len++] = '/';
|
||||
|
||||
assert(common_len > *place);
|
||||
}
|
||||
|
||||
if (num_matches > 1 && (common_len != *place || !*lastwastab))
|
||||
beep();
|
||||
|
||||
@@ -2673,7 +2627,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
|
||||
/* Find the length of the longest among the choices. */
|
||||
for (match = 0; match < num_matches; match++) {
|
||||
size_t namelen = strlenpt(matches[match]);
|
||||
size_t namelen = breadth(matches[match]);
|
||||
|
||||
if (namelen > longest_name)
|
||||
longest_name = namelen;
|
||||
|
||||
173
src/global.c
173
src/global.c
@@ -31,10 +31,8 @@ volatile sig_atomic_t the_window_resized = FALSE;
|
||||
/* Set to TRUE by the handler whenever a SIGWINCH occurs. */
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
bool on_a_vt;
|
||||
/* Whether we're running on a Linux VT or on something else. */
|
||||
#endif
|
||||
bool on_a_vt = FALSE;
|
||||
/* Whether we're running on a Linux console (a VT). */
|
||||
|
||||
bool meta_key;
|
||||
/* Whether the current keystroke is a Meta key. */
|
||||
@@ -46,6 +44,11 @@ bool focusing = TRUE;
|
||||
bool as_an_at = TRUE;
|
||||
/* Whether a 0x0A byte should be shown as a ^@ instead of a ^J. */
|
||||
|
||||
bool control_C_was_pressed = FALSE;
|
||||
/* Whether Ctrl+C was pressed (when a keyboard interrupt is enabled). */
|
||||
|
||||
bool started_curses = FALSE;
|
||||
|
||||
bool suppress_cursorpos = FALSE;
|
||||
/* Should we skip constant position display for current keystroke? */
|
||||
|
||||
@@ -123,12 +126,12 @@ linestruct *cutbottom = NULL;
|
||||
bool keep_cutbuffer = FALSE;
|
||||
/* Whether to add to the cutbuffer instead of clearing it first. */
|
||||
|
||||
partition *filepart = NULL;
|
||||
/* The "partition" where we store a portion of the current file. */
|
||||
openfilestruct *openfile = NULL;
|
||||
/* The list of all open file buffers. */
|
||||
openfilestruct *firstfile = NULL;
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
openfilestruct *startfile = NULL;
|
||||
/* The first open buffer. */
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
char *matchbrackets = NULL;
|
||||
@@ -194,13 +197,13 @@ bool refresh_needed = FALSE;
|
||||
|
||||
int currmenu = MMOST;
|
||||
/* The currently active menu, initialized to a dummy value. */
|
||||
sc *sclist = NULL;
|
||||
keystruct *sclist = NULL;
|
||||
/* The start of the shortcuts list. */
|
||||
subnfunc *allfuncs = NULL;
|
||||
funcstruct *allfuncs = NULL;
|
||||
/* The start of the functions list. */
|
||||
subnfunc *tailfunc;
|
||||
funcstruct *tailfunc;
|
||||
/* The last function in the list. */
|
||||
subnfunc *exitfunc;
|
||||
funcstruct *exitfunc;
|
||||
/* A pointer to the special Exit/Close item. */
|
||||
|
||||
linestruct *search_history = NULL;
|
||||
@@ -269,7 +272,7 @@ size_t light_to_col = 0;
|
||||
/* Return the number of entries in the shortcut list for a given menu. */
|
||||
size_t length_of_list(int menu)
|
||||
{
|
||||
subnfunc *f;
|
||||
funcstruct *f;
|
||||
size_t i = 0;
|
||||
|
||||
for (f = allfuncs; f != NULL; f = f->next)
|
||||
@@ -359,7 +362,7 @@ void do_cancel(void)
|
||||
void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *help,
|
||||
bool blank_after, bool viewok)
|
||||
{
|
||||
subnfunc *f = nmalloc(sizeof(subnfunc));
|
||||
funcstruct *f = nmalloc(sizeof(funcstruct));
|
||||
|
||||
if (allfuncs == NULL)
|
||||
allfuncs = f;
|
||||
@@ -376,28 +379,23 @@ void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *h
|
||||
f->help = help;
|
||||
f->blank_after = blank_after;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Added func %ld (%s) for menus %x\n", (long)func, f->desc, menus);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add a key combo to the shortcut list. */
|
||||
void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
void (*func)(void), int toggle)
|
||||
{
|
||||
static sc *tailsc;
|
||||
static keystruct *tailsc;
|
||||
#ifndef NANO_TINY
|
||||
static int counter = 0;
|
||||
#endif
|
||||
sc *s = nmalloc(sizeof(sc));
|
||||
keystruct *s = nmalloc(sizeof(keystruct));
|
||||
|
||||
/* Start the list, or tack on the next item. */
|
||||
if (sclist == NULL)
|
||||
sclist = s;
|
||||
else
|
||||
tailsc->next = s;
|
||||
tailsc = s;
|
||||
s->next = NULL;
|
||||
|
||||
/* Fill in the data. */
|
||||
@@ -405,29 +403,25 @@ void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
s->func = func;
|
||||
#ifndef NANO_TINY
|
||||
s->toggle = toggle;
|
||||
/* When not the same toggle as the previous one, increment the ID. */
|
||||
if (toggle)
|
||||
s->ordinal = ++counter;
|
||||
s->ordinal = (tailsc->toggle == toggle) ? counter : ++counter;
|
||||
#endif
|
||||
assign_keyinfo(s, scstring, keycode);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Setting keycode to %d for shortcut \"%s\" in menus %x\n", s->keycode, scstring, s->menus);
|
||||
#endif
|
||||
tailsc = s;
|
||||
}
|
||||
|
||||
/* Return the first shortcut in the list of shortcuts that
|
||||
* matches the given func in the given menu. */
|
||||
const sc *first_sc_for(int menu, void (*func)(void))
|
||||
const keystruct *first_sc_for(int menu, void (*func)(void))
|
||||
{
|
||||
const sc *s;
|
||||
const keystruct *s;
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if ((s->menus & menu) && s->func == func)
|
||||
return s;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Whoops, returning null given func %ld in menu %x\n", (long)func, menu);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -435,7 +429,7 @@ const sc *first_sc_for(int menu, void (*func)(void))
|
||||
* current menu, if any; otherwise, return the given default value. */
|
||||
int the_code_for(void (*func)(void), int defaultval)
|
||||
{
|
||||
const sc *s = first_sc_for(currmenu, func);
|
||||
const keystruct *s = first_sc_for(currmenu, func);
|
||||
|
||||
if (s == NULL)
|
||||
return defaultval;
|
||||
@@ -447,7 +441,7 @@ int the_code_for(void (*func)(void), int defaultval)
|
||||
/* Return a pointer to the function that is bound to the given key. */
|
||||
functionptrtype func_from_key(int *kbinput)
|
||||
{
|
||||
const sc *s = get_shortcut(kbinput);
|
||||
const keystruct *s = get_shortcut(kbinput);
|
||||
|
||||
if (s)
|
||||
return s->func;
|
||||
@@ -456,7 +450,7 @@ functionptrtype func_from_key(int *kbinput)
|
||||
}
|
||||
|
||||
/* Set the string and its corresponding keycode for the given shortcut s. */
|
||||
void assign_keyinfo(sc *s, const char *keystring, const int keycode)
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode)
|
||||
{
|
||||
s->keystr = keystring;
|
||||
s->meta = (keystring[0] == 'M' && keycode == 0);
|
||||
@@ -502,22 +496,6 @@ int keycode_from_string(const char *keystring)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void print_sclist(void)
|
||||
{
|
||||
sc *s;
|
||||
const subnfunc *f;
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next) {
|
||||
f = sctofunc(s);
|
||||
if (f)
|
||||
fprintf(stderr, "Shortcut \"%s\", function: %s, menus %x\n", s->keystr, f->desc, f->menus);
|
||||
else
|
||||
fprintf(stderr, "Hmm, didn't find a func for \"%s\"\n", s->keystr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* These two tags are used elsewhere too, so they are global. */
|
||||
/* TRANSLATORS: Try to keep the next two strings at most 10 characters. */
|
||||
const char *exit_tag = N_("Exit");
|
||||
@@ -718,23 +696,20 @@ void shortcut_init(void)
|
||||
N_("Write Out"), WITHORSANS(writeout_gist), TOGETHER, NOVIEW);
|
||||
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
#else
|
||||
/* If we can't replace Insert with Justify, show Insert anyway, to
|
||||
* keep the help items nicely paired also in restricted mode. */
|
||||
if (TRUE) {
|
||||
/* In restricted mode, replace Insert with Justify, when possible;
|
||||
* otherwise, show Insert anyway, to keep the help items paired. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
#endif
|
||||
add_to_funcs(do_insertfile_void, MMAIN,
|
||||
N_("Read File"), WITHORSANS(readfile_gist), BLANKAFTER,
|
||||
/* We allow inserting files in view mode if multibuffer mode
|
||||
* is switched on, so that we can view multiple files. */
|
||||
* is available, so that the user can view multiple files. */
|
||||
CAN_OPEN_OTHER_BUFFER);
|
||||
} else {
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
else
|
||||
add_to_funcs(do_justify_void, MMAIN,
|
||||
N_("Justify"), WITHORSANS(justify_gist), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
/* The description ("x") and blank_after (0) are irrelevant,
|
||||
@@ -757,10 +732,10 @@ void shortcut_init(void)
|
||||
N_("Refresh"), WITHORSANS(browserrefresh_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_cut_text_void, MMAIN,
|
||||
add_to_funcs(cut_text, MMAIN,
|
||||
N_("Cut Text"), WITHORSANS(cut_gist), TOGETHER, NOVIEW);
|
||||
|
||||
add_to_funcs(do_uncut_text, MMAIN,
|
||||
add_to_funcs(paste_text, MMAIN,
|
||||
N_("Paste Text"), WITHORSANS(uncut_gist), BLANKAFTER, NOVIEW);
|
||||
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
@@ -793,7 +768,7 @@ void shortcut_init(void)
|
||||
|
||||
add_to_funcs(do_mark, MMAIN,
|
||||
N_("Mark Text"), WITHORSANS(mark_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_copy_text, MMAIN,
|
||||
add_to_funcs(copy_text, MMAIN,
|
||||
N_("Copy Text"), WITHORSANS(copy_gist), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
|
||||
@@ -948,7 +923,7 @@ void shortcut_init(void)
|
||||
N_("Chop Left"), WITHORSANS(chopwordleft_gist), TOGETHER, NOVIEW);
|
||||
add_to_funcs(chop_next_word, MMAIN,
|
||||
N_("Chop Right"), WITHORSANS(chopwordright_gist), TOGETHER, NOVIEW);
|
||||
add_to_funcs(do_cut_till_eof, MMAIN,
|
||||
add_to_funcs(cut_till_eof, MMAIN,
|
||||
N_("CutTillEnd"), WITHORSANS(cuttilleof_gist), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
|
||||
@@ -1039,7 +1014,7 @@ void shortcut_init(void)
|
||||
N_("No Conversion"), WITHORSANS(convert_gist), TOGETHER, NOVIEW);
|
||||
|
||||
/* Command execution is only available when not in restricted mode. */
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) {
|
||||
add_to_funcs(flip_execute, MINSERTFILE,
|
||||
N_("Execute Command"), WITHORSANS(execute_gist), TOGETHER, NOVIEW);
|
||||
|
||||
@@ -1110,8 +1085,8 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^W", 0, do_search_forward, 0);
|
||||
add_to_sclist(MMAIN, "^\\", 0, do_replace, 0);
|
||||
add_to_sclist(MMAIN, "M-R", 0, do_replace, 0);
|
||||
add_to_sclist(MMOST, "^K", 0, do_cut_text_void, 0);
|
||||
add_to_sclist(MMOST, "^U", 0, do_uncut_text, 0);
|
||||
add_to_sclist(MMOST, "^K", 0, cut_text, 0);
|
||||
add_to_sclist(MMOST, "^U", 0, paste_text, 0);
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
add_to_sclist(MMAIN, "^J", 0, do_justify_void, 0);
|
||||
#endif
|
||||
@@ -1142,8 +1117,8 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN, "M-A", 0, do_mark, 0);
|
||||
add_to_sclist(MMAIN, "^6", 0, do_mark, 0);
|
||||
add_to_sclist(MMAIN, "^^", 0, do_mark, 0);
|
||||
add_to_sclist(MMAIN, "M-6", 0, do_copy_text, 0);
|
||||
add_to_sclist(MMAIN, "M-^", 0, do_copy_text, 0);
|
||||
add_to_sclist(MMAIN, "M-6", 0, copy_text, 0);
|
||||
add_to_sclist(MMAIN, "M-^", 0, copy_text, 0);
|
||||
add_to_sclist(MMAIN, "M-}", 0, do_indent, 0);
|
||||
add_to_sclist(MMAIN, "Tab", TAB_CODE, do_indent, 0);
|
||||
add_to_sclist(MMAIN, "M-{", 0, do_unindent, 0);
|
||||
@@ -1170,11 +1145,11 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMOST|MHELP|MBROWSER, "\xE2\x96\xb6", KEY_RIGHT, do_right, 0);
|
||||
add_to_sclist(MSOME, "^\xE2\x97\x80", CONTROL_LEFT, do_prev_word_void, 0);
|
||||
add_to_sclist(MSOME, "^\xE2\x96\xb6", CONTROL_RIGHT, do_next_word_void, 0);
|
||||
#ifndef NANO_TINY
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
add_to_sclist(MMAIN, "M-\xE2\x97\x80", ALT_LEFT, switch_to_prev_buffer, 0);
|
||||
add_to_sclist(MMAIN, "M-\xE2\x96\xb6", ALT_RIGHT, switch_to_next_buffer, 0);
|
||||
#endif
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_MULTIBUFFER)
|
||||
if (!on_a_vt) {
|
||||
add_to_sclist(MMAIN, "M-\xE2\x97\x80", ALT_LEFT, switch_to_prev_buffer, 0);
|
||||
add_to_sclist(MMAIN, "M-\xE2\x96\xb6", ALT_RIGHT, switch_to_next_buffer, 0);
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
@@ -1183,6 +1158,12 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMOST|MHELP|MBROWSER, "Right", KEY_RIGHT, do_right, 0);
|
||||
add_to_sclist(MSOME, "^Left", CONTROL_LEFT, do_prev_word_void, 0);
|
||||
add_to_sclist(MSOME, "^Right", CONTROL_RIGHT, do_next_word_void, 0);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (!on_a_vt) {
|
||||
add_to_sclist(MMAIN, "M-Left", ALT_LEFT, switch_to_prev_buffer, 0);
|
||||
add_to_sclist(MMAIN, "M-Right", ALT_RIGHT, switch_to_next_buffer, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef NANO_TINY
|
||||
add_to_sclist(MMAIN, "M-B", 0, do_prev_word_void, 0);
|
||||
@@ -1220,10 +1201,16 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN, "M-)", 0, do_para_end_void, 0);
|
||||
add_to_sclist(MMAIN, "M-0", 0, do_para_end_void, 0);
|
||||
#endif
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_UTF8)
|
||||
#ifndef NANO_TINY
|
||||
#ifdef ENABLE_UTF8
|
||||
if (using_utf8()) {
|
||||
add_to_sclist(MMAIN|MHELP, "M-\xE2\x96\xb2", ALT_UP, do_scroll_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP, "M-\xE2\x96\xbc", ALT_DOWN, do_scroll_down, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
add_to_sclist(MMAIN|MHELP, "M-Up", ALT_UP, do_scroll_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP, "M-Down", ALT_DOWN, do_scroll_down, 0);
|
||||
}
|
||||
#endif
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
@@ -1240,7 +1227,7 @@ void shortcut_init(void)
|
||||
#endif
|
||||
add_to_sclist(MMOST, "M-V", 0, do_verbatim_input, 0);
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MMAIN, "M-T", 0, do_cut_till_eof, 0);
|
||||
add_to_sclist(MMAIN, "M-T", 0, cut_till_eof, 0);
|
||||
add_to_sclist(MMAIN, "M-D", 0, do_wordlinechar_count, 0);
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
@@ -1256,9 +1243,10 @@ void shortcut_init(void)
|
||||
/* Group of "Appearance" toggles. */
|
||||
add_to_sclist(MMAIN, "M-X", 0, do_toggle_void, NO_HELP);
|
||||
add_to_sclist(MMAIN, "M-C", 0, do_toggle_void, CONSTANT_SHOW);
|
||||
add_to_sclist(MMAIN, "M-S", 0, do_toggle_void, JUMPY_SCROLLING);
|
||||
add_to_sclist(MMAIN, "M-S", 0, do_toggle_void, SOFTWRAP);
|
||||
add_to_sclist(MMAIN, "M-$", 0, do_toggle_void, SOFTWRAP);
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
add_to_sclist(MMAIN, "M-N", 0, do_toggle_void, LINE_NUMBERS);
|
||||
add_to_sclist(MMAIN, "M-#", 0, do_toggle_void, LINE_NUMBERS);
|
||||
#endif
|
||||
add_to_sclist(MMAIN, "M-P", 0, do_toggle_void, WHITESPACE_DISPLAY);
|
||||
@@ -1309,6 +1297,9 @@ void shortcut_init(void)
|
||||
#endif
|
||||
add_to_sclist(MGOTOLINE, "^Y", 0, to_first_line, 0);
|
||||
add_to_sclist(MGOTOLINE, "^V", 0, to_last_line, 0);
|
||||
/* Some people are used to having these keystrokes in the Search menu. */
|
||||
add_to_sclist(MWHEREIS, "^Y", 0, to_first_line, 0);
|
||||
add_to_sclist(MWHEREIS, "^V", 0, to_last_line, 0);
|
||||
#ifdef ENABLE_BROWSER
|
||||
add_to_sclist(MWHEREISFILE, "^Y", 0, to_first_file, 0);
|
||||
add_to_sclist(MWHEREISFILE, "^V", 0, to_last_file, 0);
|
||||
@@ -1328,7 +1319,7 @@ void shortcut_init(void)
|
||||
add_to_sclist(MWRITEFILE, "M-M", 0, mac_format_void, 0);
|
||||
/* Only when not in restricted mode, allow Appending, Prepending,
|
||||
* making backups, and executing a command. */
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) {
|
||||
add_to_sclist(MWRITEFILE, "M-A", 0, append_void, 0);
|
||||
add_to_sclist(MWRITEFILE, "M-P", 0, prepend_void, 0);
|
||||
add_to_sclist(MWRITEFILE, "M-B", 0, backup_file_void, 0);
|
||||
@@ -1375,26 +1366,12 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "F6", 0, do_search_forward, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F7", 0, do_page_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F8", 0, do_page_down, 0);
|
||||
add_to_sclist(MMOST, "F9", 0, do_cut_text_void, 0);
|
||||
add_to_sclist(MMOST, "F10", 0, do_uncut_text, 0);
|
||||
add_to_sclist(MMOST, "F9", 0, cut_text, 0);
|
||||
add_to_sclist(MMOST, "F10", 0, paste_text, 0);
|
||||
add_to_sclist(MMAIN, "F11", 0, do_cursorpos_void, 0);
|
||||
#ifdef ENABLE_SPELLER
|
||||
add_to_sclist(MMAIN, "F12", 0, do_spell, 0);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
print_sclist();
|
||||
#endif
|
||||
}
|
||||
|
||||
const subnfunc *sctofunc(const sc *s)
|
||||
{
|
||||
subnfunc *f = allfuncs;
|
||||
|
||||
while (f != NULL && f->func != s->func)
|
||||
f = f->next;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -1408,8 +1385,6 @@ const char *flagtostr(int flag)
|
||||
return N_("Help mode");
|
||||
case CONSTANT_SHOW:
|
||||
return N_("Constant cursor position display");
|
||||
case JUMPY_SCROLLING:
|
||||
return N_("Jumpy scrolling (per half-screen)");
|
||||
case SOFTWRAP:
|
||||
return N_("Soft wrapping of overlong lines");
|
||||
case WHITESPACE_DISPLAY:
|
||||
@@ -1441,9 +1416,9 @@ const char *flagtostr(int flag)
|
||||
#ifdef ENABLE_NANORC
|
||||
/* Interpret a function string given in the rc file, and return a
|
||||
* shortcut record with the corresponding function filled in. */
|
||||
sc *strtosc(const char *input)
|
||||
keystruct *strtosc(const char *input)
|
||||
{
|
||||
sc *s = nmalloc(sizeof(sc));
|
||||
keystruct *s = nmalloc(sizeof(keystruct));
|
||||
|
||||
#ifndef NANO_TINY
|
||||
s->toggle = 0;
|
||||
@@ -1477,14 +1452,14 @@ sc *strtosc(const char *input)
|
||||
else if (!strcasecmp(input, "replace"))
|
||||
s->func = do_replace;
|
||||
else if (!strcasecmp(input, "cut"))
|
||||
s->func = do_cut_text_void;
|
||||
s->func = cut_text;
|
||||
else if (!strcasecmp(input, "paste"))
|
||||
s->func = do_uncut_text;
|
||||
s->func = paste_text;
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "cutrestoffile"))
|
||||
s->func = do_cut_till_eof;
|
||||
s->func = cut_till_eof;
|
||||
else if (!strcasecmp(input, "copy"))
|
||||
s->func = do_copy_text;
|
||||
s->func = copy_text;
|
||||
else if (!strcasecmp(input, "zap"))
|
||||
s->func = zap_text;
|
||||
else if (!strcasecmp(input, "mark"))
|
||||
@@ -1661,8 +1636,6 @@ sc *strtosc(const char *input)
|
||||
s->toggle = NO_HELP;
|
||||
else if (!strcasecmp(input, "constantshow"))
|
||||
s->toggle = CONSTANT_SHOW;
|
||||
else if (!strcasecmp(input, "smoothscroll"))
|
||||
s->toggle = JUMPY_SCROLLING;
|
||||
else if (!strcasecmp(input, "softwrap"))
|
||||
s->toggle = SOFTWRAP;
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
|
||||
152
src/help.c
152
src/help.c
@@ -39,45 +39,42 @@ static char *end_of_intro = NULL;
|
||||
static size_t location;
|
||||
/* The offset (in bytes) of the topleft of the shown help text. */
|
||||
|
||||
char *tempfilename = NULL;
|
||||
/* Name of the temporary file used for wrapping the help text. */
|
||||
|
||||
/* Hard-wrap the help text, write it to the existing temporary file, and
|
||||
* read that file into a new buffer. */
|
||||
void wrap_the_help_text(bool redisplaying)
|
||||
/* Hard-wrap the concatenated help text, and write it into a new buffer. */
|
||||
void wrap_help_text_into_buffer()
|
||||
{
|
||||
size_t sum = 0;
|
||||
const char *ptr = start_of_body;
|
||||
FILE *tempfile = fopen(tempfilename, "w+b");
|
||||
|
||||
/* If re-opening the temporary file failed, give up. */
|
||||
if (tempfile == NULL) {
|
||||
statusline(ALERT, _("Error writing temp file: %s"), strerror(errno));
|
||||
return;
|
||||
}
|
||||
make_new_buffer();
|
||||
|
||||
/* Write the body of the help_text into the temporary file. */
|
||||
/* Copy the help text into the just-created new buffer. */
|
||||
while (*ptr != '\0') {
|
||||
int length = help_line_len(ptr);
|
||||
char *oneline = nmalloc(length + 1);
|
||||
|
||||
snprintf(oneline, length + 1, "%s", ptr);
|
||||
free(openfile->current->data);
|
||||
openfile->current->data = oneline;
|
||||
|
||||
fwrite(ptr, sizeof(char), length, tempfile);
|
||||
ptr += length;
|
||||
|
||||
/* Hard-wrap the lines in the help text. */
|
||||
if (*ptr != '\n')
|
||||
fwrite("\n", sizeof(char), 1, tempfile);
|
||||
else while (*ptr == '\n')
|
||||
fwrite(ptr++, sizeof(char), 1, tempfile);
|
||||
ptr--;
|
||||
|
||||
/* Create a new line, and then one more for each extra \n. */
|
||||
do {
|
||||
openfile->current->next = make_new_node(openfile->current);
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current->data = mallocstrcpy(NULL, "");
|
||||
} while (*(++ptr) == '\n');
|
||||
}
|
||||
|
||||
fclose(tempfile);
|
||||
openfile->filebot = openfile->current;
|
||||
openfile->current = openfile->filetop;
|
||||
|
||||
if (redisplaying)
|
||||
close_buffer();
|
||||
|
||||
open_buffer(tempfilename, TRUE);
|
||||
remove_magicline();
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
color_update();
|
||||
#endif
|
||||
prepare_for_display();
|
||||
|
||||
/* Move to the position in the file where we were before. */
|
||||
@@ -112,20 +109,9 @@ void do_help(void)
|
||||
/* A storage place for the current flag settings. */
|
||||
linestruct *line;
|
||||
int length;
|
||||
FILE *fp;
|
||||
|
||||
blank_statusbar();
|
||||
|
||||
/* Get a temporary file for the help text. If it fails, give up. */
|
||||
tempfilename = safe_tempfile(&fp);
|
||||
if (tempfilename == NULL) {
|
||||
statusline(ALERT, _("Error writing temp file: %s"), strerror(errno));
|
||||
free(saved_answer);
|
||||
return;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/* Save the settings of all flags. */
|
||||
memcpy(stash, flags, sizeof(flags));
|
||||
|
||||
@@ -175,7 +161,7 @@ void do_help(void)
|
||||
while (*start_of_body == '\n')
|
||||
start_of_body++;
|
||||
|
||||
wrap_the_help_text(FALSE);
|
||||
wrap_help_text_into_buffer();
|
||||
edit_refresh();
|
||||
|
||||
while (TRUE) {
|
||||
@@ -210,19 +196,16 @@ void do_help(void)
|
||||
} else if (func == (functionptrtype)implant) {
|
||||
implant(first_sc_for(MHELP, func)->expansion);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
} else if (kbinput == KEY_WINCH) {
|
||||
; /* Nothing to do. */
|
||||
#endif
|
||||
#ifdef ENABLE_MOUSE
|
||||
} else if (kbinput == KEY_MOUSE) {
|
||||
int dummy_row, dummy_col;
|
||||
get_mouseinput(&dummy_row, &dummy_col, TRUE);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
} else if (kbinput == KEY_WINCH) {
|
||||
; /* Nothing to do. */
|
||||
#endif
|
||||
} else if (func == do_exit) {
|
||||
/* Exit from the help viewer. */
|
||||
close_buffer();
|
||||
curs_set(0);
|
||||
break;
|
||||
} else
|
||||
unbound_key(kbinput);
|
||||
@@ -240,6 +223,9 @@ void do_help(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Discard the help-text buffer. */
|
||||
close_buffer();
|
||||
|
||||
/* Restore the settings of all flags. */
|
||||
memcpy(flags, stash, sizeof(flags));
|
||||
|
||||
@@ -250,35 +236,33 @@ void do_help(void)
|
||||
tabsize = was_tabsize;
|
||||
#ifdef ENABLE_COLOR
|
||||
syntaxstr = was_syntax;
|
||||
have_palette = FALSE;
|
||||
#endif
|
||||
|
||||
/* Switch back to the buffer we were invoked from. */
|
||||
switch_to_prev_buffer();
|
||||
free(title);
|
||||
title = NULL;
|
||||
free(answer);
|
||||
answer = saved_answer;
|
||||
free(help_text);
|
||||
inhelp = FALSE;
|
||||
|
||||
curs_set(0);
|
||||
refresh_needed = TRUE;
|
||||
|
||||
if (ISSET(NO_HELP)) {
|
||||
currmenu = oldmenu;
|
||||
window_init();
|
||||
} else
|
||||
} else {
|
||||
wipe_statusbar();
|
||||
bottombars(oldmenu);
|
||||
|
||||
free(title);
|
||||
title = NULL;
|
||||
inhelp = FALSE;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (oldmenu == MBROWSER || oldmenu == MWHEREISFILE || oldmenu == MGOTODIR)
|
||||
browser_refresh();
|
||||
else
|
||||
#endif
|
||||
total_refresh();
|
||||
|
||||
free(answer);
|
||||
answer = saved_answer;
|
||||
|
||||
remove(tempfilename);
|
||||
free(tempfilename);
|
||||
|
||||
free(help_text);
|
||||
titlebar(NULL);
|
||||
}
|
||||
|
||||
/* Allocate space for the help text for the current menu, and concatenate
|
||||
@@ -291,8 +275,8 @@ void help_init(void)
|
||||
/* Untranslated help introduction. We break it up into three chunks
|
||||
* in case the full string is too long for the compiler to handle. */
|
||||
char *ptr;
|
||||
const subnfunc *f;
|
||||
const sc *s;
|
||||
const funcstruct *f;
|
||||
const keystruct *s;
|
||||
|
||||
/* First, set up the initial help text for the current function. */
|
||||
if (currmenu == MWHEREIS || currmenu == MREPLACE || currmenu == MREPLACEWITH) {
|
||||
@@ -464,22 +448,22 @@ void help_init(void)
|
||||
allocsize += strlen(htx[2]);
|
||||
|
||||
/* Calculate the length of the shortcut help text. Each entry has
|
||||
* one or two keys, which fill 16 columns, plus translated text,
|
||||
* one or two keys, which fill 17 cells, plus translated text,
|
||||
* plus one or two \n's. */
|
||||
for (f = allfuncs; f != NULL; f = f->next)
|
||||
if (f->menus & currmenu)
|
||||
allocsize += (16 * MAXCHARLEN) + strlen(_(f->help)) + 2;
|
||||
allocsize += strlen(_(f->help)) + 21;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If we're on the main list, we also count the toggle help text.
|
||||
* Each entry has "M-%c\t\t", five chars which fill 16 columns,
|
||||
* plus a space, plus translated text, plus one or two '\n's. */
|
||||
* Each entry has "M-%c\t\t ", six chars which fill 17 cells, plus
|
||||
* two translated texts, plus a space, plus one or two '\n's. */
|
||||
if (currmenu == MMAIN) {
|
||||
size_t endis_len = strlen(_("enable/disable"));
|
||||
size_t onoff_len = strlen(_("enable/disable"));
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if (s->func == do_toggle_void)
|
||||
allocsize += strlen(_(flagtostr(s->toggle))) + endis_len + 8;
|
||||
allocsize += strlen(_(flagtostr(s->toggle))) + onoff_len + 9;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -493,40 +477,39 @@ void help_init(void)
|
||||
if (htx[2] != NULL)
|
||||
strcat(help_text, htx[2]);
|
||||
|
||||
ptr = help_text + strlen(help_text);
|
||||
|
||||
/* Remember this end-of-introduction, start-of-shortcuts. */
|
||||
end_of_intro = ptr;
|
||||
end_of_intro = help_text + strlen(help_text);
|
||||
ptr = end_of_intro;
|
||||
|
||||
/* Now add our shortcut info. */
|
||||
/* Now add the shortcuts and their descriptions. */
|
||||
for (f = allfuncs; f != NULL; f = f->next) {
|
||||
int tally = 0;
|
||||
|
||||
if ((f->menus & currmenu) == 0)
|
||||
continue;
|
||||
|
||||
/* Let's simply show the first two shortcuts from the list. */
|
||||
/* Show the first two shortcuts (if any) for each function. */
|
||||
for (s = sclist; s != NULL; s = s->next) {
|
||||
if ((s->menus & currmenu) && s->func == f->func) {
|
||||
/* Make the first column narrower (6) than the second (10),
|
||||
* but allow it to spill into the second, for "M-Space". */
|
||||
/* Make the first column 7 cells wide and the second 10. */
|
||||
if (++tally == 1) {
|
||||
sprintf(ptr, "%s ", s->keystr);
|
||||
sprintf(ptr, "%s ", s->keystr);
|
||||
/* Unicode arrows take three bytes instead of one. */
|
||||
ptr += (strstr(s->keystr, "\xE2") != NULL ? 8 : 6);
|
||||
ptr += (strstr(s->keystr, "\xE2") != NULL ? 9 : 7);
|
||||
} else {
|
||||
ptr += sprintf(ptr, "(%s)\t", s->keystr);
|
||||
sprintf(ptr, "(%s) ", s->keystr);
|
||||
ptr += (strstr(s->keystr, "\xE2") != NULL ? 12 : 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tally == 0)
|
||||
ptr += sprintf(ptr, "\t\t");
|
||||
ptr += sprintf(ptr, "\t\t ");
|
||||
else if (tally == 1)
|
||||
ptr += 10;
|
||||
|
||||
/* The shortcut's help text. */
|
||||
/* The shortcut's description. */
|
||||
ptr += sprintf(ptr, "%s\n", _(f->help));
|
||||
|
||||
if (f->blank_after)
|
||||
@@ -547,7 +530,7 @@ void help_init(void)
|
||||
counter++;
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if (s->toggle && s->ordinal == counter) {
|
||||
ptr += sprintf(ptr, "%s\t\t%s %s\n", (s->menus == MMAIN ? s->keystr : ""),
|
||||
ptr += sprintf(ptr, "%s\t\t %s %s\n", (s->menus == MMAIN ? s->keystr : ""),
|
||||
_(flagtostr(s->toggle)), _("enable/disable"));
|
||||
if (s->toggle == NO_COLOR_SYNTAX || s->toggle == TABS_TO_SPACES)
|
||||
ptr += sprintf(ptr, "\n");
|
||||
@@ -556,9 +539,6 @@ void help_init(void)
|
||||
}
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
if (strlen(help_text) > allocsize)
|
||||
statusline(ALERT, "Help text spilled over -- please report a bug");
|
||||
}
|
||||
|
||||
/* Return the function that is bound to the given key, accepting certain
|
||||
@@ -610,10 +590,10 @@ size_t help_line_len(const char *ptr)
|
||||
|
||||
/* Get the length of the entire line up to a null or a newline. */
|
||||
while (*(ptr + length) != '\0' && *(ptr + length) != '\n')
|
||||
length = move_mbright(ptr, length);
|
||||
length = step_right(ptr, length);
|
||||
|
||||
/* If the entire line will just fit the screen, don't wrap it. */
|
||||
if (strnlenpt(ptr, length) <= wrapping_point + 1)
|
||||
if (wideness(ptr, length) <= wrapping_point + 1)
|
||||
return length;
|
||||
else if (wrap_location > 0)
|
||||
return wrap_location;
|
||||
|
||||
@@ -119,7 +119,7 @@ void update_history(linestruct **item, const char *text)
|
||||
*htop = after;
|
||||
|
||||
unlink_node(thesame);
|
||||
renumber(after);
|
||||
renumber_from(after);
|
||||
}
|
||||
|
||||
/* If the history is full, delete the oldest item (the one at the
|
||||
@@ -129,7 +129,7 @@ void update_history(linestruct **item, const char *text)
|
||||
|
||||
*htop = (*htop)->next;
|
||||
unlink_node(oldest);
|
||||
renumber(*htop);
|
||||
renumber_from(*htop);
|
||||
}
|
||||
|
||||
/* Store the fresh string in the last item, then create a new item. */
|
||||
@@ -528,7 +528,7 @@ void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
|
||||
poshiststruct *posptr, *theone, *posprev = NULL;
|
||||
char *fullpath = get_full_path(filename);
|
||||
|
||||
if (fullpath == NULL || fullpath[strlen(fullpath) - 1] == '/' || inhelp) {
|
||||
if (fullpath == NULL || fullpath[strlen(fullpath) - 1] == '/') {
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
14
src/move.c
14
src/move.c
@@ -75,7 +75,7 @@ size_t proper_x(linestruct *line, size_t *leftedge, bool forward,
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP) && line->data[index] == '\t' &&
|
||||
((forward && strnlenpt(line->data, index) < *leftedge) ||
|
||||
((forward && wideness(line->data, index) < *leftedge) ||
|
||||
(!forward && column / tabsize == (*leftedge - 1) / tabsize &&
|
||||
column / tabsize < (*leftedge + editwincols - 1) / tabsize))) {
|
||||
index++;
|
||||
@@ -85,7 +85,7 @@ size_t proper_x(linestruct *line, size_t *leftedge, bool forward,
|
||||
}
|
||||
|
||||
if (ISSET(SOFTWRAP))
|
||||
*leftedge = leftedge_for(strnlenpt(line->data, index), line);
|
||||
*leftedge = leftedge_for(wideness(line->data, index), line);
|
||||
#endif
|
||||
|
||||
return index;
|
||||
@@ -278,7 +278,7 @@ void do_prev_word(bool allow_punct)
|
||||
}
|
||||
|
||||
/* Step back one character. */
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x = step_left(openfile->current->data,
|
||||
openfile->current_x);
|
||||
|
||||
if (is_word_mbchar(openfile->current->data + openfile->current_x,
|
||||
@@ -296,7 +296,7 @@ void do_prev_word(bool allow_punct)
|
||||
|
||||
if (step_forward)
|
||||
/* Move one character forward again to sit on the start of the word. */
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x = step_right(openfile->current->data,
|
||||
openfile->current_x);
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ bool do_next_word(bool after_ends, bool allow_punct)
|
||||
seen_space = TRUE;
|
||||
} else {
|
||||
/* Step forward one character. */
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x = step_right(openfile->current->data,
|
||||
openfile->current_x);
|
||||
}
|
||||
|
||||
@@ -570,7 +570,7 @@ void do_left(void)
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
if (openfile->current_x > 0)
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x = step_left(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->filetop) {
|
||||
openfile->current = openfile->current->prev;
|
||||
@@ -586,7 +586,7 @@ void do_right(void)
|
||||
linestruct *was_current = openfile->current;
|
||||
|
||||
if (openfile->current->data[openfile->current_x] != '\0')
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x = step_right(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
openfile->current = openfile->current->next;
|
||||
|
||||
828
src/nano.c
828
src/nano.c
File diff suppressed because it is too large
Load Diff
86
src/nano.h
86
src/nano.h
@@ -113,14 +113,11 @@
|
||||
#define N_(string) gettext_noop(string)
|
||||
/* Mark a string that will be sent to gettext() later. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <regex.h>
|
||||
#include <signal.h>
|
||||
#include <assert.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. */
|
||||
@@ -147,6 +144,8 @@
|
||||
#define BAD_COLOR -2
|
||||
#endif
|
||||
|
||||
#define STANDARD_INPUT 0
|
||||
|
||||
/* Enumeration types. */
|
||||
typedef enum {
|
||||
NIX_FILE, DOS_FILE, MAC_FILE
|
||||
@@ -188,21 +187,14 @@ typedef struct colortype {
|
||||
/* This syntax's foreground color. */
|
||||
short bg;
|
||||
/* This syntax's background color. */
|
||||
int pairnum;
|
||||
/* The color pair number used for this foreground color and
|
||||
* background color. */
|
||||
short pairnum;
|
||||
/* The pair number for this foreground/background color combination. */
|
||||
int attributes;
|
||||
/* Pair number and brightness composed into ready-to-use attributes. */
|
||||
int rex_flags;
|
||||
/* The regex compilation flags (with or without REG_ICASE). */
|
||||
char *start_regex;
|
||||
/* The start (or all) of the regex string. */
|
||||
regex_t *start;
|
||||
/* The compiled start (or all) of the regex string. */
|
||||
char *end_regex;
|
||||
/* The end (if any) of the regex string. */
|
||||
/* The compiled regular expression for 'start=', or the only one. */
|
||||
regex_t *end;
|
||||
/* The compiled end (if any) of the regex string. */
|
||||
/* The compiled regular expression for 'end=', if any. */
|
||||
struct colortype *next;
|
||||
/* Next set of colors. */
|
||||
int id;
|
||||
@@ -216,9 +208,26 @@ typedef struct regexlisttype {
|
||||
/* The next regex. */
|
||||
} regexlisttype;
|
||||
|
||||
typedef struct augmentstruct {
|
||||
char *filename;
|
||||
/* The file where the syntax is extended. */
|
||||
ssize_t lineno;
|
||||
/* The number of the line of the extendsyntax command. */
|
||||
char *data;
|
||||
/* The text of the line. */
|
||||
struct augmentstruct *next;
|
||||
/* Next node. */
|
||||
} augmentstruct;
|
||||
|
||||
typedef struct syntaxtype {
|
||||
char *name;
|
||||
/* The name of this syntax. */
|
||||
char *filename;
|
||||
/* 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;
|
||||
/* List of extendsyntax commands to apply when loaded. */
|
||||
regexlisttype *extensions;
|
||||
/* The list of extensions that this syntax applies to. */
|
||||
regexlisttype *headers;
|
||||
@@ -285,24 +294,6 @@ typedef struct linestruct {
|
||||
#endif
|
||||
} linestruct;
|
||||
|
||||
typedef struct partition {
|
||||
linestruct *filetop;
|
||||
/* The top line of this portion of the file. */
|
||||
linestruct *top_prev;
|
||||
/* The line before the top line of this portion of the file. */
|
||||
char *top_data;
|
||||
/* The text before the beginning of the top line of this portion
|
||||
* of the file. */
|
||||
linestruct *filebot;
|
||||
/* The bottom line of this portion of the file. */
|
||||
linestruct *bot_next;
|
||||
/* The line after the bottom line of this portion of the
|
||||
* file. */
|
||||
char *bot_data;
|
||||
/* The text after the end of the bottom line of this portion of
|
||||
* the file. */
|
||||
} partition;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct undo_group {
|
||||
ssize_t top_line;
|
||||
@@ -330,12 +321,8 @@ typedef struct undo {
|
||||
/* Some flag data we need. */
|
||||
undo_group *grouping;
|
||||
/* Undo info specific to groups of lines. */
|
||||
|
||||
/* Cut-specific stuff we need. */
|
||||
linestruct *cutbuffer;
|
||||
/* Copy of the cutbuffer. */
|
||||
linestruct *cutbottom;
|
||||
/* Copy of cutbottom. */
|
||||
ssize_t mark_begin_lineno;
|
||||
/* Mostly the line number of the current line; sometimes something else. */
|
||||
size_t mark_begin_x;
|
||||
@@ -383,6 +370,10 @@ typedef struct openfilestruct {
|
||||
/* Whether the file has been modified. */
|
||||
struct stat *current_stat;
|
||||
/* The file's current stat information. */
|
||||
#ifdef ENABLE_WRAPPING
|
||||
linestruct *spillage_line;
|
||||
/* The line for prepending stuff to during automatic hard-wrapping. */
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
linestruct *mark;
|
||||
/* The line in the file where the mark is set; NULL if not set. */
|
||||
@@ -426,17 +417,17 @@ typedef struct rcoption {
|
||||
} rcoption;
|
||||
#endif
|
||||
|
||||
typedef struct sc {
|
||||
typedef struct keystruct {
|
||||
const char *keystr;
|
||||
/* The string that describes a keystroke, like "^C" or "M-R". */
|
||||
/* The string that describes the keystroke, like "^C" or "M-R". */
|
||||
bool meta;
|
||||
/* Whether this is a Meta keystroke. */
|
||||
int keycode;
|
||||
/* The integer that, together with meta, identifies the keystroke. */
|
||||
int menus;
|
||||
/* Which menus this applies to. */
|
||||
/* The menus in which this keystroke is bound. */
|
||||
void (*func)(void);
|
||||
/* The function we're going to run. */
|
||||
/* The function to which this keystroke is bound. */
|
||||
#ifndef NANO_TINY
|
||||
int toggle;
|
||||
/* If a toggle, what we're toggling. */
|
||||
@@ -448,11 +439,11 @@ typedef struct sc {
|
||||
char *expansion;
|
||||
/* The string of keycodes to which this shortcut is expanded. */
|
||||
#endif
|
||||
struct sc *next;
|
||||
struct keystruct *next;
|
||||
/* Next in the list. */
|
||||
} sc;
|
||||
} keystruct;
|
||||
|
||||
typedef struct subnfunc {
|
||||
typedef struct funcstruct {
|
||||
void (*func)(void);
|
||||
/* The actual function to call. */
|
||||
int menus;
|
||||
@@ -470,9 +461,9 @@ typedef struct subnfunc {
|
||||
/* Is this function allowed when in view mode? */
|
||||
long toggle;
|
||||
/* If this is a toggle, which toggle to affect. */
|
||||
struct subnfunc *next;
|
||||
struct funcstruct *next;
|
||||
/* Next item in the list. */
|
||||
} subnfunc;
|
||||
} funcstruct;
|
||||
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
typedef struct completion_word {
|
||||
@@ -543,7 +534,6 @@ enum
|
||||
AFTER_ENDS,
|
||||
LET_THEM_ZAP,
|
||||
BREAK_LONG_LINES,
|
||||
FINAL_NEWLINE,
|
||||
JUMPY_SCROLLING,
|
||||
EMPTY_LINE
|
||||
};
|
||||
|
||||
66
src/prompt.c
66
src/prompt.c
@@ -37,13 +37,13 @@ int do_statusbar_mouse(void)
|
||||
|
||||
/* We can click on the statusbar window text to move the cursor. */
|
||||
if (retval == 0 && wmouse_trafo(bottomwin, &click_row, &click_col, FALSE)) {
|
||||
size_t start_col = strlenpt(prompt) + 2;
|
||||
size_t start_col = breadth(prompt) + 2;
|
||||
|
||||
/* Move to where the click occurred. */
|
||||
if (click_row == 0 && click_col >= start_col)
|
||||
typing_x = actual_x(answer,
|
||||
get_statusbar_page_start(start_col, start_col +
|
||||
strnlenpt(answer, typing_x)) + click_col - start_col);
|
||||
wideness(answer, typing_x)) + click_col - start_col);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -61,7 +61,7 @@ int do_statusbar_input(bool *finished)
|
||||
/* The input buffer. */
|
||||
static size_t kbinput_len = 0;
|
||||
/* The length of the input buffer. */
|
||||
const sc *shortcut;
|
||||
const keystruct *shortcut;
|
||||
|
||||
*finished = FALSE;
|
||||
|
||||
@@ -150,8 +150,8 @@ int do_statusbar_input(bool *finished)
|
||||
else if (ISSET(RESTRICTED) && currmenu == MWRITEFILE &&
|
||||
openfile->filename[0] != '\0' &&
|
||||
(shortcut->func == do_verbatim_input ||
|
||||
shortcut->func == do_cut_text_void ||
|
||||
shortcut->func == do_uncut_text ||
|
||||
shortcut->func == cut_text ||
|
||||
shortcut->func == paste_text ||
|
||||
shortcut->func == do_delete ||
|
||||
shortcut->func == do_backspace))
|
||||
;
|
||||
@@ -161,13 +161,13 @@ int do_statusbar_input(bool *finished)
|
||||
#endif
|
||||
else if (shortcut->func == do_verbatim_input)
|
||||
do_statusbar_verbatim_input();
|
||||
else if (shortcut->func == do_cut_text_void)
|
||||
else if (shortcut->func == cut_text)
|
||||
do_statusbar_cut_text();
|
||||
else if (shortcut->func == do_delete)
|
||||
do_statusbar_delete();
|
||||
else if (shortcut->func == do_backspace)
|
||||
do_statusbar_backspace();
|
||||
else if (shortcut->func == do_uncut_text) {
|
||||
else if (shortcut->func == paste_text) {
|
||||
if (cutbuffer != NULL)
|
||||
do_statusbar_uncut_text();
|
||||
} else {
|
||||
@@ -190,7 +190,7 @@ void do_statusbar_output(int *the_input, size_t input_len,
|
||||
{
|
||||
char *output = charalloc(input_len + 1);
|
||||
char onechar[MAXCHARLEN];
|
||||
size_t char_len, i, j = 0;
|
||||
size_t charlen, i, j = 0;
|
||||
|
||||
/* Copy the typed stuff so it can be treated. */
|
||||
for (i = 0; i < input_len; i++)
|
||||
@@ -203,21 +203,21 @@ void do_statusbar_output(int *the_input, size_t input_len,
|
||||
output[j] = '\n';
|
||||
|
||||
/* Interpret the next multibyte character. */
|
||||
char_len = parse_mbchar(output + j, onechar, NULL);
|
||||
charlen = parse_mbchar(output + j, onechar, NULL);
|
||||
|
||||
j += char_len;
|
||||
j += charlen;
|
||||
|
||||
/* When filtering, skip any ASCII control character. */
|
||||
if (filtering && is_ascii_cntrl_char(*(output + j - char_len)))
|
||||
if (filtering && is_ascii_cntrl_char(*(output + j - charlen)))
|
||||
continue;
|
||||
|
||||
/* Insert the typed character into the existing answer string. */
|
||||
answer = charealloc(answer, strlen(answer) + char_len + 1);
|
||||
charmove(answer + typing_x + char_len, answer + typing_x,
|
||||
answer = charealloc(answer, strlen(answer) + charlen + 1);
|
||||
charmove(answer + typing_x + charlen, answer + typing_x,
|
||||
strlen(answer) - typing_x + 1);
|
||||
strncpy(answer + typing_x, onechar, char_len);
|
||||
strncpy(answer + typing_x, onechar, charlen);
|
||||
|
||||
typing_x += char_len;
|
||||
typing_x += charlen;
|
||||
}
|
||||
|
||||
free(output);
|
||||
@@ -239,24 +239,24 @@ void do_statusbar_end(void)
|
||||
void do_statusbar_left(void)
|
||||
{
|
||||
if (typing_x > 0)
|
||||
typing_x = move_mbleft(answer, typing_x);
|
||||
typing_x = step_left(answer, typing_x);
|
||||
}
|
||||
|
||||
/* Move right one character. */
|
||||
void do_statusbar_right(void)
|
||||
{
|
||||
if (answer[typing_x] != '\0')
|
||||
typing_x = move_mbright(answer, typing_x);
|
||||
typing_x = step_right(answer, typing_x);
|
||||
}
|
||||
|
||||
/* Delete one character. */
|
||||
void do_statusbar_delete(void)
|
||||
{
|
||||
if (answer[typing_x] != '\0') {
|
||||
int char_len = parse_mbchar(answer + typing_x, NULL, NULL);
|
||||
int charlen = char_length(answer + typing_x);
|
||||
|
||||
charmove(answer + typing_x, answer + typing_x + char_len,
|
||||
strlen(answer) - typing_x - char_len + 1);
|
||||
charmove(answer + typing_x, answer + typing_x + charlen,
|
||||
strlen(answer) - typing_x - charlen + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ void do_statusbar_delete(void)
|
||||
void do_statusbar_backspace(void)
|
||||
{
|
||||
if (typing_x > 0) {
|
||||
typing_x = move_mbleft(answer, typing_x);
|
||||
typing_x = step_left(answer, typing_x);
|
||||
do_statusbar_delete();
|
||||
}
|
||||
}
|
||||
@@ -288,7 +288,7 @@ void do_statusbar_next_word(void)
|
||||
/* Move forward until we reach either the end or the start of a word,
|
||||
* depending on whether the AFTER_ENDS flag is set or not. */
|
||||
while (answer[typing_x] != '\0') {
|
||||
typing_x = move_mbright(answer, typing_x);
|
||||
typing_x = step_right(answer, typing_x);
|
||||
|
||||
if (ISSET(AFTER_ENDS)) {
|
||||
/* If this is a word character, continue; else it's a separator,
|
||||
@@ -315,7 +315,7 @@ void do_statusbar_prev_word(void)
|
||||
|
||||
/* Move backward until we pass over the start of a word. */
|
||||
while (typing_x != 0) {
|
||||
typing_x = move_mbleft(answer, typing_x);
|
||||
typing_x = step_left(answer, typing_x);
|
||||
|
||||
if (is_word_mbchar(answer + typing_x, FALSE))
|
||||
seen_a_word = TRUE;
|
||||
@@ -328,7 +328,7 @@ void do_statusbar_prev_word(void)
|
||||
|
||||
if (step_forward)
|
||||
/* Move one character forward again to sit on the start of the word. */
|
||||
typing_x = move_mbright(answer, typing_x);
|
||||
typing_x = step_right(answer, typing_x);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
@@ -385,12 +385,12 @@ void put_cursor_at_end_of_answer(void)
|
||||
/* Redraw the promptbar and place the cursor at the right spot. */
|
||||
void draw_the_promptbar(void)
|
||||
{
|
||||
size_t base = strlenpt(prompt) + 2;
|
||||
size_t base = breadth(prompt) + 2;
|
||||
size_t the_page, end_page, column;
|
||||
char *expanded;
|
||||
|
||||
the_page = get_statusbar_page_start(base, base + strnlenpt(answer, typing_x));
|
||||
end_page = get_statusbar_page_start(base, base + strlenpt(answer) - 1);
|
||||
the_page = get_statusbar_page_start(base, base + wideness(answer, typing_x));
|
||||
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]);
|
||||
@@ -404,7 +404,7 @@ void draw_the_promptbar(void)
|
||||
waddstr(bottomwin, expanded);
|
||||
free(expanded);
|
||||
|
||||
if (base + strlenpt(answer) != COLS && the_page < end_page)
|
||||
if (base + breadth(answer) != COLS && the_page < end_page)
|
||||
mvwaddch(bottomwin, 0, COLS - 1, '>');
|
||||
|
||||
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
@@ -414,7 +414,7 @@ void draw_the_promptbar(void)
|
||||
wrefresh(bottomwin);
|
||||
|
||||
/* Place the cursor at the right spot. */
|
||||
column = base + strnlenpt(answer, typing_x);
|
||||
column = base + wideness(answer, typing_x);
|
||||
wmove(bottomwin, 0, column - get_statusbar_page_start(base, column));
|
||||
wnoutrefresh(bottomwin);
|
||||
}
|
||||
@@ -667,7 +667,7 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
if (!ISSET(NO_HELP)) {
|
||||
char shortstr[MAXCHARLEN + 2];
|
||||
/* Temporary string for (translated) " Y", " N" and " A". */
|
||||
const sc *cancelshortcut = first_sc_for(MYESNO, do_cancel);
|
||||
const keystruct *cancelshortcut = first_sc_for(MYESNO, do_cancel);
|
||||
/* The keystroke that is bound to the Cancel function. */
|
||||
|
||||
if (COLS < 32)
|
||||
@@ -738,6 +738,12 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
choice = 2;
|
||||
else if (func_from_key(&kbinput) == do_cancel)
|
||||
choice = -1;
|
||||
/* Interpret ^N and ^Q as "No", to allow exiting in anger. */
|
||||
else if (kbinput == '\x0E' || kbinput == '\x11')
|
||||
choice = 0;
|
||||
/* And interpret ^Y as "Yes". */
|
||||
else if (kbinput == '\x19')
|
||||
choice = 1;
|
||||
#ifdef ENABLE_MOUSE
|
||||
else if (kbinput == KEY_MOUSE) {
|
||||
int mouse_x, mouse_y;
|
||||
|
||||
99
src/proto.h
99
src/proto.h
@@ -29,9 +29,7 @@
|
||||
extern volatile sig_atomic_t the_window_resized;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
extern bool on_a_vt;
|
||||
#endif
|
||||
|
||||
extern bool meta_key;
|
||||
extern bool shift_held;
|
||||
@@ -40,8 +38,12 @@ extern bool focusing;
|
||||
|
||||
extern bool as_an_at;
|
||||
|
||||
extern bool control_C_was_pressed;
|
||||
|
||||
extern bool suppress_cursorpos;
|
||||
|
||||
extern bool started_curses;
|
||||
|
||||
extern message_type lastmessage;
|
||||
|
||||
extern linestruct *pletion_line;
|
||||
@@ -96,9 +98,10 @@ extern linestruct *cutbuffer;
|
||||
extern linestruct *cutbottom;
|
||||
extern bool keep_cutbuffer;
|
||||
|
||||
extern partition *filepart;
|
||||
extern openfilestruct *openfile;
|
||||
extern openfilestruct *firstfile;
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
extern openfilestruct *startfile;
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern char *matchbrackets;
|
||||
@@ -143,9 +146,9 @@ extern bool have_palette;
|
||||
extern bool refresh_needed;
|
||||
|
||||
extern int currmenu;
|
||||
extern sc *sclist;
|
||||
extern subnfunc *allfuncs;
|
||||
extern subnfunc *exitfunc;
|
||||
extern keystruct *sclist;
|
||||
extern funcstruct *allfuncs;
|
||||
extern funcstruct *exitfunc;
|
||||
|
||||
extern linestruct *search_history;
|
||||
extern linestruct *replace_history;
|
||||
@@ -207,12 +210,12 @@ bool is_ascii_cntrl_char(int c);
|
||||
bool is_cntrl_mbchar(const char *c);
|
||||
bool is_word_mbchar(const char *c, bool allow_punct);
|
||||
char control_mbrep(const char *c, bool isdata);
|
||||
int length_of_char(const char *c, int *width);
|
||||
int mbwidth(const char *c);
|
||||
char *make_mbchar(long chr, int *chr_mb_len);
|
||||
int char_length(const char *pointer);
|
||||
int parse_mbchar(const char *buf, char *chr, size_t *col);
|
||||
size_t move_mbleft(const char *buf, size_t pos);
|
||||
size_t move_mbright(const char *buf, size_t pos);
|
||||
size_t step_left(const char *buf, size_t pos);
|
||||
size_t step_right(const char *buf, size_t pos);
|
||||
int mbstrcasecmp(const char *s1, const char *s2);
|
||||
int mbstrncasecmp(const char *s1, const char *s2, size_t n);
|
||||
char *mbstrcasestr(const char *haystack, const char *needle);
|
||||
@@ -252,35 +255,32 @@ void chop_previous_word(void);
|
||||
void chop_next_word(void);
|
||||
void cut_marked(bool *right_side_up);
|
||||
#endif
|
||||
void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append);
|
||||
void do_cut_text(bool copying, bool marked, bool until_eof, bool append);
|
||||
bool is_cuttable(bool test_cliff);
|
||||
void do_cut_text_void(void);
|
||||
void cut_text(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_copy_text(void);
|
||||
void do_cut_till_eof(void);
|
||||
void copy_text(void);
|
||||
void cut_till_eof(void);
|
||||
void zap_text(void);
|
||||
#endif
|
||||
void do_uncut_text(void);
|
||||
void paste_text(void);
|
||||
|
||||
/* Most functions in files.c. */
|
||||
void initialize_buffer_text(void);
|
||||
void make_new_buffer(void);
|
||||
void set_modified(void);
|
||||
bool open_buffer(const char *filename, bool new_buffer);
|
||||
#ifdef ENABLE_SPELLER
|
||||
void replace_buffer(const char *filename);
|
||||
#ifndef NANO_TINY
|
||||
void replace_marked_buffer(const char *filename);
|
||||
#endif
|
||||
bool replace_buffer(const char *filename, undo_type action, bool marked);
|
||||
#endif
|
||||
void prepare_for_display(void);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void mention_name_and_linecount(void);
|
||||
void switch_to_prev_buffer(void);
|
||||
void switch_to_next_buffer(void);
|
||||
bool close_buffer(void);
|
||||
void close_buffer(void);
|
||||
#endif
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable);
|
||||
int open_file(const char *filename, bool newfie, bool quiet, FILE **f);
|
||||
int open_file(const char *filename, bool newfie, FILE **f);
|
||||
char *get_next_filename(const char *name, const char *suffix);
|
||||
void do_insertfile_void(void);
|
||||
char *get_full_path(const char *origpath);
|
||||
@@ -315,24 +315,22 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
|
||||
/* Some functions in global.c. */
|
||||
size_t length_of_list(int menu);
|
||||
const sc *first_sc_for(int menu, void (*func)(void));
|
||||
const keystruct *first_sc_for(int menu, void (*func)(void));
|
||||
int the_code_for(void (*func)(void), int defaultval);
|
||||
functionptrtype func_from_key(int *kbinput);
|
||||
int keycode_from_string(const char *keystring);
|
||||
void assign_keyinfo(sc *s, const char *keystring, const int keycode);
|
||||
void print_sclist(void);
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode);
|
||||
void shortcut_init(void);
|
||||
const subnfunc *sctofunc(const sc *s);
|
||||
const char *flagtostr(int flag);
|
||||
#ifdef ENABLE_NANORC
|
||||
sc *strtosc(const char *input);
|
||||
keystruct *strtosc(const char *input);
|
||||
int name_to_menu(const char *name);
|
||||
char *menu_to_name(int menu);
|
||||
#endif
|
||||
|
||||
/* All functions in help.c. */
|
||||
#ifdef ENABLE_HELP
|
||||
void wrap_the_help_text(bool redisplaying);
|
||||
void wrap_help_text_into_buffer();
|
||||
void do_help(void);
|
||||
void help_init(void);
|
||||
functionptrtype parse_help_input(int *kbinput);
|
||||
@@ -395,18 +393,13 @@ void unlink_node(linestruct *fileptr);
|
||||
void delete_node(linestruct *fileptr);
|
||||
linestruct *copy_buffer(const linestruct *src);
|
||||
void free_lines(linestruct *src);
|
||||
void renumber(linestruct *line);
|
||||
partition *partition_buffer(linestruct *top, size_t top_x,
|
||||
void renumber_from(linestruct *line);
|
||||
void partition_buffer(linestruct *top, size_t top_x,
|
||||
linestruct *bot, size_t bot_x);
|
||||
void unpartition_buffer(partition **p);
|
||||
void extract_buffer(linestruct **file_top, linestruct **file_bot,
|
||||
linestruct *top, size_t top_x, linestruct *bot, size_t bot_x);
|
||||
void unpartition_buffer();
|
||||
void extract(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x);
|
||||
void ingraft_buffer(linestruct *somebuffer);
|
||||
void copy_from_buffer(linestruct *somebuffer);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void unlink_opennode(openfilestruct *fileptr);
|
||||
void delete_opennode(openfilestruct *fileptr);
|
||||
#endif
|
||||
void print_view_warning(void);
|
||||
void show_restricted_warning(void);
|
||||
#ifndef ENABLE_HELP
|
||||
@@ -418,18 +411,25 @@ void emergency_save(const char *die_filename, struct stat *die_stat);
|
||||
void window_init(void);
|
||||
void do_exit(void);
|
||||
void close_and_go(void);
|
||||
void install_handler_for_Ctrl_C(void);
|
||||
void restore_handler_for_Ctrl_C(void);
|
||||
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);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER)
|
||||
void block_sigwinch(bool blockit);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE handle_sigwinch(int signal);
|
||||
void regenerate_screen(void);
|
||||
void do_toggle(int flag);
|
||||
void enable_signals(void);
|
||||
#endif
|
||||
void disable_kb_interrupt(void);
|
||||
void enable_kb_interrupt(void);
|
||||
void disable_flow_control(void);
|
||||
void enable_flow_control(void);
|
||||
void terminal_init(void);
|
||||
@@ -437,7 +437,7 @@ void terminal_init(void);
|
||||
void confirm_margin(void);
|
||||
#endif
|
||||
void unbound_key(int code);
|
||||
bool okay_for_view(const sc *shortcut);
|
||||
bool okay_for_view(const keystruct *shortcut);
|
||||
void do_output(char *output, size_t output_len, bool allow_cntrls);
|
||||
|
||||
/* Most functions in prompt.c. */
|
||||
@@ -465,15 +465,17 @@ int do_yesno_prompt(bool all, const char *msg);
|
||||
|
||||
/* Most functions in rcfile.c. */
|
||||
#ifdef ENABLE_NANORC
|
||||
void display_rcfile_errors();
|
||||
#ifdef ENABLE_COLOR
|
||||
void parse_one_include(char *file, syntaxtype *syntax);
|
||||
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage);
|
||||
bool parse_syntax_commands(char *keyword, char *ptr);
|
||||
#endif
|
||||
void parse_rcfile(FILE *rcstream, bool syntax_only);
|
||||
void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only);
|
||||
void do_rcfiles(void);
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
/* Most functions in search.c. */
|
||||
void tidy_up_after_search(void);
|
||||
int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
size_t *match_len, bool skipone, const linestruct *begin, size_t begin_x);
|
||||
void do_search(void);
|
||||
@@ -520,8 +522,7 @@ void update_multiline_undo(ssize_t lineno, char *indentation);
|
||||
void update_undo(undo_type action);
|
||||
#endif /* !NANO_TINY */
|
||||
#ifdef ENABLE_WRAPPING
|
||||
void wrap_reset(void);
|
||||
bool do_wrap(linestruct *line);
|
||||
bool do_wrap(void);
|
||||
#endif
|
||||
#if defined(ENABLE_HELP) || defined(ENABLED_WRAPORJUSTIFY)
|
||||
ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl);
|
||||
@@ -557,7 +558,6 @@ int digits(ssize_t n);
|
||||
#endif
|
||||
bool parse_num(const char *str, ssize_t *val);
|
||||
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column);
|
||||
void null_at(char **data, size_t index);
|
||||
void unsunder(char *str, size_t true_len);
|
||||
void sunder(char *str);
|
||||
#if !defined(ENABLE_TINY) || defined(ENABLE_TABCOMP) || defined(ENABLE_BROWSER)
|
||||
@@ -568,7 +568,6 @@ bool is_separate_word(size_t position, size_t length, const char *buf);
|
||||
#endif
|
||||
const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *start);
|
||||
void nperror(const char *s);
|
||||
void *nmalloc(size_t howmuch);
|
||||
void *nrealloc(void *ptr, size_t howmuch);
|
||||
char *mallocstrncpy(char *dest, const char *src, size_t n);
|
||||
@@ -577,20 +576,20 @@ char *free_and_assign(char *dest, char *src);
|
||||
size_t get_page_start(size_t column);
|
||||
size_t xplustabs(void);
|
||||
size_t actual_x(const char *text, size_t column);
|
||||
size_t strnlenpt(const char *text, size_t maxlen);
|
||||
size_t strlenpt(const char *text);
|
||||
size_t wideness(const char *text, size_t maxlen);
|
||||
size_t breadth(const char *text);
|
||||
void new_magicline(void);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
void remove_magicline(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void mark_order(const linestruct **top, size_t *top_x,
|
||||
void get_region(const linestruct **top, size_t *top_x,
|
||||
const linestruct **bot, size_t *bot_x, bool *right_side_up);
|
||||
void get_range(const linestruct **top, const linestruct **bot);
|
||||
#endif
|
||||
size_t get_totsize(const linestruct *begin, const linestruct *end);
|
||||
#ifndef NANO_TINY
|
||||
linestruct *fsfromline(ssize_t lineno);
|
||||
linestruct *line_from_number(ssize_t lineno);
|
||||
#endif
|
||||
|
||||
/* Most functions in winio.c. */
|
||||
@@ -613,7 +612,7 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count);
|
||||
#ifdef ENABLE_MOUSE
|
||||
int get_mouseinput(int *mouse_row, int *mouse_col, bool allow_shortcuts);
|
||||
#endif
|
||||
const sc *get_shortcut(int *kbinput);
|
||||
const keystruct *get_shortcut(int *kbinput);
|
||||
void blank_row(WINDOW *win, int y, int x, int n);
|
||||
void blank_edit(void);
|
||||
void blank_statusbar(void);
|
||||
|
||||
520
src/rcfile.c
520
src/rcfile.c
File diff suppressed because it is too large
Load Diff
316
src/search.c
316
src/search.c
@@ -22,9 +22,6 @@
|
||||
#include "proto.h"
|
||||
|
||||
#include <string.h>
|
||||
#ifdef DEBUG
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
static bool came_full_circle = FALSE;
|
||||
/* Have we reached the starting line again while searching? */
|
||||
@@ -88,7 +85,7 @@ void search_init(bool replacing, bool keep_the_answer)
|
||||
thedefault = charalloc(strlen(disp) + 7);
|
||||
/* We use (COLS / 3) here because we need to see more on the line. */
|
||||
sprintf(thedefault, " [%s%s]", disp,
|
||||
(strlenpt(last_search) > COLS / 3) ? "..." : "");
|
||||
(breadth(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
thedefault = mallocstrcpy(NULL, "");
|
||||
@@ -96,15 +93,16 @@ void search_init(bool replacing, bool keep_the_answer)
|
||||
while (TRUE) {
|
||||
functionptrtype func;
|
||||
/* Ask the user what to search for (or replace). */
|
||||
int i = do_prompt(FALSE, FALSE,
|
||||
int response = do_prompt(FALSE, FALSE,
|
||||
inhelp ? MFINDINHELP : (replacing ? MREPLACE : MWHEREIS),
|
||||
answer, &search_history,
|
||||
answer, &search_history, edit_refresh,
|
||||
/* TRANSLATORS: This is the main search prompt. */
|
||||
edit_refresh, "%s%s%s%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: The next four modify the search prompt. */
|
||||
"%s%s%s%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: The next five modify the search prompt. */
|
||||
ISSET(CASE_SENSITIVE) ? _(" [Case Sensitive]") : "",
|
||||
ISSET(USE_REGEXP) ? _(" [Regexp]") : "",
|
||||
ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") : "", replacing ?
|
||||
ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") : "",
|
||||
replacing ?
|
||||
#ifndef NANO_TINY
|
||||
openfile->mark ? _(" (to replace) in selection") :
|
||||
#endif
|
||||
@@ -112,15 +110,13 @@ void search_init(bool replacing, bool keep_the_answer)
|
||||
|
||||
/* If the search was cancelled, or we have a blank answer and
|
||||
* nothing was searched for yet during this session, get out. */
|
||||
if (i == -1 || (i == -2 && *last_search == '\0')) {
|
||||
if (response == -1 || (response == -2 && *last_search == '\0')) {
|
||||
statusbar(_("Cancelled"));
|
||||
tidy_up_after_search();
|
||||
free(thedefault);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If Enter was pressed, prepare to do a replace or a search. */
|
||||
if (i == 0 || i == -2) {
|
||||
if (response == 0 || response == -2) {
|
||||
/* If an actual answer was typed, remember it. */
|
||||
if (*answer != '\0') {
|
||||
last_search = mallocstrcpy(last_search, answer);
|
||||
@@ -139,38 +135,35 @@ void search_init(bool replacing, bool keep_the_answer)
|
||||
go_looking();
|
||||
}
|
||||
|
||||
tidy_up_after_search();
|
||||
free(thedefault);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
func = func_from_key(&i);
|
||||
func = func_from_key(&response);
|
||||
|
||||
/* If we're here, one of the five toggles was pressed, or
|
||||
* a shortcut was executed. */
|
||||
if (func == case_sens_void) {
|
||||
if (func == case_sens_void)
|
||||
TOGGLE(CASE_SENSITIVE);
|
||||
} else if (func == backwards_void) {
|
||||
else if (func == backwards_void)
|
||||
TOGGLE(BACKWARDS_SEARCH);
|
||||
} else if (func == regexp_void) {
|
||||
else if (func == regexp_void)
|
||||
TOGGLE(USE_REGEXP);
|
||||
} else if (func == flip_replace) {
|
||||
else if (func == flip_replace) {
|
||||
if (ISSET(VIEW_MODE)) {
|
||||
print_view_warning();
|
||||
tidy_up_after_search();
|
||||
free(thedefault);
|
||||
return;
|
||||
}
|
||||
replacing = !replacing;
|
||||
} else {
|
||||
if (func == flip_goto)
|
||||
do_gotolinecolumn(openfile->current->lineno,
|
||||
openfile->placewewant + 1, TRUE, TRUE);
|
||||
tidy_up_after_search();
|
||||
free(thedefault);
|
||||
return;
|
||||
}
|
||||
napms(600);
|
||||
} else
|
||||
replacing = !replacing;
|
||||
} else if (func == flip_goto) {
|
||||
do_gotolinecolumn(openfile->current->lineno,
|
||||
openfile->placewewant + 1, TRUE, TRUE);
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
tidy_up_after_search();
|
||||
free(thedefault);
|
||||
}
|
||||
|
||||
/* Look for needle, starting at (current, current_x). begin is the line
|
||||
@@ -230,10 +223,10 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
if (skipone) {
|
||||
skipone = FALSE;
|
||||
if (ISSET(BACKWARDS_SEARCH) && from != line->data) {
|
||||
from = line->data + move_mbleft(line->data, from - line->data);
|
||||
from = line->data + step_left(line->data, from - line->data);
|
||||
found = strstrwrapper(line->data, needle, from);
|
||||
} else if (!ISSET(BACKWARDS_SEARCH) && *from != '\0') {
|
||||
from += move_mbright(from, 0);
|
||||
from += char_length(from);
|
||||
found = strstrwrapper(line->data, needle, from);
|
||||
}
|
||||
} else
|
||||
@@ -248,7 +241,7 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
* if it's not, continue looking in the rest of the line. */
|
||||
if (whole_word_only && !is_separate_word(found - line->data,
|
||||
found_len, line->data)) {
|
||||
from = found + move_mbright(found, 0);
|
||||
from = found + char_length(found);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@@ -389,7 +382,7 @@ void do_findnext(void)
|
||||
void not_found_msg(const char *str)
|
||||
{
|
||||
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE, FALSE);
|
||||
size_t numchars = actual_x(disp, strnlenpt(disp, COLS / 2));
|
||||
size_t numchars = actual_x(disp, wideness(disp, COLS / 2));
|
||||
|
||||
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
|
||||
(disp[numchars] == '\0') ? "" : "...");
|
||||
@@ -402,7 +395,10 @@ void go_looking(void)
|
||||
{
|
||||
linestruct *was_current = openfile->current;
|
||||
size_t was_current_x = openfile->current_x;
|
||||
#ifdef DEBUG
|
||||
|
||||
//#define TIMEIT 12
|
||||
#ifdef TIMEIT
|
||||
#include <time.h>
|
||||
clock_t start = clock();
|
||||
#endif
|
||||
|
||||
@@ -419,7 +415,7 @@ void go_looking(void)
|
||||
else if (didfind == 0)
|
||||
not_found_msg(last_search);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef TIMEIT
|
||||
statusline(HUSH, "Took: %.2f", (double)(clock() - start) / CLOCKS_PER_SEC);
|
||||
#endif
|
||||
|
||||
@@ -472,21 +468,20 @@ int replace_regexp(char *string, bool create)
|
||||
/* Return a copy of the current line with one needle replaced. */
|
||||
char *replace_line(const char *needle)
|
||||
{
|
||||
char *copy;
|
||||
size_t new_size = strlen(openfile->current->data) + 1;
|
||||
size_t match_len;
|
||||
size_t new_line_size = strlen(openfile->current->data) + 1;
|
||||
char *copy;
|
||||
|
||||
/* First adjust the size of the new line for the change. */
|
||||
if (ISSET(USE_REGEXP)) {
|
||||
match_len = regmatches[0].rm_eo - regmatches[0].rm_so;
|
||||
new_line_size += replace_regexp(NULL, FALSE) - match_len;
|
||||
new_size += replace_regexp(NULL, FALSE) - match_len;
|
||||
} else {
|
||||
match_len = strlen(needle);
|
||||
new_line_size += strlen(answer) - match_len;
|
||||
new_size += strlen(answer) - match_len;
|
||||
}
|
||||
|
||||
/* Create the buffer. */
|
||||
copy = charalloc(new_line_size);
|
||||
copy = charalloc(new_size);
|
||||
|
||||
/* Copy the head of the original line. */
|
||||
strncpy(copy, openfile->current->data, openfile->current_x);
|
||||
@@ -497,8 +492,6 @@ char *replace_line(const char *needle)
|
||||
else
|
||||
strcpy(copy + openfile->current_x, answer);
|
||||
|
||||
assert(openfile->current_x + match_len <= strlen(openfile->current->data));
|
||||
|
||||
/* Copy the tail of the original line. */
|
||||
strcat(copy, openfile->current->data + openfile->current_x + match_len);
|
||||
|
||||
@@ -529,8 +522,8 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
|
||||
/* If the mark is on, frame the region, and turn the mark off. */
|
||||
if (openfile->mark) {
|
||||
mark_order((const linestruct **)&top, &top_x,
|
||||
(const linestruct **)&bot, &bot_x, &right_side_up);
|
||||
get_region((const linestruct **)&top, &top_x,
|
||||
(const linestruct **)&bot, &bot_x, &right_side_up);
|
||||
openfile->mark = NULL;
|
||||
modus = INREGION;
|
||||
|
||||
@@ -577,7 +570,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
if (!replaceall) {
|
||||
spotlighted = TRUE;
|
||||
light_from_col = xplustabs();
|
||||
light_to_col = strnlenpt(openfile->current->data,
|
||||
light_to_col = wideness(openfile->current->data,
|
||||
openfile->current_x + match_len);
|
||||
|
||||
/* Refresh the edit window, scrolling it if necessary. */
|
||||
@@ -681,7 +674,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
|
||||
/* If "automatic newline" is enabled, and text has been added to the
|
||||
* magic line, make a new magic line. */
|
||||
if (ISSET(FINAL_NEWLINE) && openfile->filebot->data[0] != '\0')
|
||||
if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
|
||||
new_magicline();
|
||||
|
||||
return numreplaced;
|
||||
@@ -704,22 +697,22 @@ void ask_for_replacement(void)
|
||||
linestruct *edittop_save, *begin;
|
||||
size_t firstcolumn_save, begin_x;
|
||||
ssize_t numreplaced;
|
||||
int i = do_prompt(FALSE, FALSE, MREPLACEWITH, NULL, &replace_history,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
edit_refresh, _("Replace with"));
|
||||
int response = do_prompt(FALSE, FALSE, MREPLACEWITH, NULL,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
&replace_history, edit_refresh, _("Replace with"));
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
/* If the replace string is not "", add it to the replace history list. */
|
||||
if (i == 0)
|
||||
if (response == 0)
|
||||
update_history(&replace_history, answer);
|
||||
#endif
|
||||
|
||||
/* When cancelled, or when a function was run, get out. */
|
||||
if (i == -1 || i > 0) {
|
||||
if (i == -1)
|
||||
statusbar(_("Cancelled"));
|
||||
if (response == -1) {
|
||||
statusbar(_("Cancelled"));
|
||||
return;
|
||||
} else if (response > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save where we are. */
|
||||
edittop_save = openfile->edittop;
|
||||
@@ -762,18 +755,18 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
{
|
||||
if (interactive) {
|
||||
/* Ask for the line and column. */
|
||||
int i = do_prompt(FALSE, FALSE, MGOTOLINE,
|
||||
use_answer ? answer : NULL, NULL,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
edit_refresh, _("Enter line number, column number"));
|
||||
int response = do_prompt(FALSE, FALSE, MGOTOLINE,
|
||||
use_answer ? answer : NULL, NULL, edit_refresh,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
_("Enter line number, column number"));
|
||||
|
||||
/* If the user cancelled or gave a blank answer, get out. */
|
||||
if (i < 0) {
|
||||
if (response < 0) {
|
||||
statusbar(_("Cancelled"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (func_from_key(&i) == flip_goto) {
|
||||
if (func_from_key(&response) == flip_goto) {
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
/* Retain what the user typed so far and switch to searching. */
|
||||
search_init(FALSE, TRUE);
|
||||
@@ -781,7 +774,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
}
|
||||
|
||||
/* If a function was executed, we're done here. */
|
||||
if (i > 0)
|
||||
if (response > 0)
|
||||
return;
|
||||
|
||||
/* Try to extract one or two numbers from the user's response. */
|
||||
@@ -810,7 +803,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
|
||||
/* Take a negative column number to mean: from the end of the line. */
|
||||
if (column < 0)
|
||||
column = strlenpt(openfile->current->data) + column + 2;
|
||||
column = breadth(openfile->current->data) + column + 2;
|
||||
if (column < 1)
|
||||
column = 1;
|
||||
|
||||
@@ -820,8 +813,8 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP) && openfile->placewewant / editwincols >
|
||||
strlenpt(openfile->current->data) / editwincols)
|
||||
openfile->placewewant = strlenpt(openfile->current->data);
|
||||
breadth(openfile->current->data) / editwincols)
|
||||
openfile->placewewant = breadth(openfile->current->data);
|
||||
#endif
|
||||
|
||||
/* When the position was manually given, center the target line. */
|
||||
@@ -858,62 +851,57 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
void do_gotolinecolumn_void(void)
|
||||
{
|
||||
do_gotolinecolumn(openfile->current->lineno,
|
||||
openfile->placewewant + 1, FALSE, TRUE);
|
||||
openfile->placewewant + 1, FALSE, TRUE);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Search for a match to one of the two characters in bracket_set. If
|
||||
* reverse is TRUE, search backwards for the leftmost bracket.
|
||||
* Otherwise, search forwards for the rightmost bracket. Return TRUE if
|
||||
* we found a match, and FALSE otherwise. */
|
||||
bool find_bracket_match(bool reverse, const char *bracket_set)
|
||||
/* Search, starting from the current position, for any of the two characters
|
||||
* in bracket_pair. If reverse is TRUE, search backwards, otherwise forwards.
|
||||
* Return TRUE when one of the brackets was found, and FALSE otherwise. */
|
||||
bool find_a_bracket(bool reverse, const char *bracket_pair)
|
||||
{
|
||||
linestruct *fileptr = openfile->current;
|
||||
const char *rev_start = NULL, *found = NULL;
|
||||
linestruct *line = openfile->current;
|
||||
const char *pointer, *found;
|
||||
|
||||
assert(mbstrlen(bracket_set) == 2);
|
||||
/* Step away from the current bracket, either backwards or forwards. */
|
||||
if (reverse) {
|
||||
if (openfile->current_x == 0) {
|
||||
line = line->prev;
|
||||
if (line == NULL)
|
||||
return FALSE;
|
||||
pointer = line->data + strlen(line->data);
|
||||
} else
|
||||
pointer = line->data + step_left(line->data, openfile->current_x);
|
||||
} else
|
||||
pointer = line->data + step_right(line->data, openfile->current_x);
|
||||
|
||||
/* rev_start might end up 1 character before the start or after the
|
||||
* end of the line. This won't be a problem because we'll skip over
|
||||
* it below in that case, and rev_start will be properly set when
|
||||
* the search continues on the previous or next line. */
|
||||
if (reverse)
|
||||
rev_start = fileptr->data + (openfile->current_x - 1);
|
||||
else
|
||||
rev_start = fileptr->data + (openfile->current_x + 1);
|
||||
|
||||
/* Look for either of the two characters in bracket_set. rev_start
|
||||
* can be 1 character before the start or after the end of the line.
|
||||
* In either case, just act as though no match is found. */
|
||||
/* Now seek for any of the two brackets, either backwards or forwards. */
|
||||
while (TRUE) {
|
||||
if ((rev_start > fileptr->data && *(rev_start - 1) == '\0') ||
|
||||
rev_start < fileptr->data)
|
||||
found = NULL;
|
||||
else if (reverse)
|
||||
found = mbrevstrpbrk(fileptr->data, bracket_set, rev_start);
|
||||
if (reverse)
|
||||
found = mbrevstrpbrk(line->data, bracket_pair, pointer);
|
||||
else
|
||||
found = mbstrpbrk(rev_start, bracket_set);
|
||||
found = mbstrpbrk(pointer, bracket_pair);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
|
||||
if (reverse)
|
||||
fileptr = fileptr->prev;
|
||||
line = line->prev;
|
||||
else
|
||||
fileptr = fileptr->next;
|
||||
line = line->next;
|
||||
|
||||
/* If we've reached the start or end of the buffer, get out. */
|
||||
if (fileptr == NULL)
|
||||
if (line == NULL)
|
||||
return FALSE;
|
||||
|
||||
rev_start = fileptr->data;
|
||||
pointer = line->data;
|
||||
if (reverse)
|
||||
rev_start += strlen(fileptr->data);
|
||||
pointer += strlen(line->data);
|
||||
}
|
||||
|
||||
/* Set the current position to the found matching bracket. */
|
||||
openfile->current = fileptr;
|
||||
openfile->current_x = found - fileptr->data;
|
||||
/* Set the current position to the found bracket. */
|
||||
openfile->current = line;
|
||||
openfile->current_x = found - line->data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -922,104 +910,78 @@ bool find_bracket_match(bool reverse, const char *bracket_set)
|
||||
* there is one. */
|
||||
void do_find_bracket(void)
|
||||
{
|
||||
linestruct *current_save;
|
||||
size_t current_x_save;
|
||||
linestruct *was_current = openfile->current;
|
||||
size_t was_current_x = openfile->current_x;
|
||||
/* The current cursor position, in case we don't find a complement. */
|
||||
const char *ch;
|
||||
/* The location in matchbrackets of the bracket at the current
|
||||
* cursor position. */
|
||||
/* The location in matchbrackets of the bracket under the cursor. */
|
||||
int ch_len;
|
||||
/* The length of ch in bytes. */
|
||||
const char *wanted_ch;
|
||||
/* The location in matchbrackets of the bracket complementing
|
||||
* the bracket at the current cursor position. */
|
||||
/* The location in matchbrackets of the complementing bracket. */
|
||||
int wanted_ch_len;
|
||||
/* The length of wanted_ch in bytes. */
|
||||
char bracket_set[MAXCHARLEN * 2 + 1];
|
||||
char bracket_pair[MAXCHARLEN * 2 + 1];
|
||||
/* The pair of characters in ch and wanted_ch. */
|
||||
size_t i;
|
||||
/* Generic loop variable. */
|
||||
size_t matchhalf;
|
||||
/* The number of single-byte characters in one half of
|
||||
* matchbrackets. */
|
||||
size_t mbmatchhalf;
|
||||
/* The number of multibyte characters in one half of
|
||||
* matchbrackets. */
|
||||
size_t count = 1;
|
||||
size_t halfway = 0;
|
||||
/* The index in matchbrackets where the closing brackets start. */
|
||||
size_t charcount = mbstrlen(matchbrackets) / 2;
|
||||
/* Half the number of characters in matchbrackets. */
|
||||
size_t balance = 1;
|
||||
/* The initial bracket count. */
|
||||
bool reverse;
|
||||
/* The direction we search. */
|
||||
|
||||
assert(mbstrlen(matchbrackets) % 2 == 0);
|
||||
ch = mbstrchr(matchbrackets, openfile->current->data + openfile->current_x);
|
||||
|
||||
ch = openfile->current->data + openfile->current_x;
|
||||
|
||||
if ((ch = mbstrchr(matchbrackets, ch)) == NULL) {
|
||||
if (ch == NULL) {
|
||||
statusbar(_("Not a bracket"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save where we are. */
|
||||
current_save = openfile->current;
|
||||
current_x_save = openfile->current_x;
|
||||
/* Find the halfway point in matchbrackets, where the closing ones start. */
|
||||
for (size_t i = 0; i < charcount; i++)
|
||||
halfway += char_length(matchbrackets + halfway);
|
||||
|
||||
/* If we're on an opening bracket, which must be in the first half
|
||||
* of matchbrackets, we want to search forwards for a closing
|
||||
* bracket. If we're on a closing bracket, which must be in the
|
||||
* second half of matchbrackets, we want to search backwards for an
|
||||
* opening bracket. */
|
||||
matchhalf = 0;
|
||||
mbmatchhalf = mbstrlen(matchbrackets) / 2;
|
||||
/* When on a closing bracket, we have to search backwards for a matching
|
||||
* opening bracket; otherwise, forward for a matching closing bracket. */
|
||||
reverse = (ch >= (matchbrackets + halfway));
|
||||
|
||||
for (i = 0; i < mbmatchhalf; i++)
|
||||
matchhalf += parse_mbchar(matchbrackets + matchhalf, NULL, NULL);
|
||||
|
||||
reverse = ((ch - matchbrackets) >= matchhalf);
|
||||
|
||||
/* If we're on an opening bracket, set wanted_ch to the character
|
||||
* that's matchhalf characters after ch. If we're on a closing
|
||||
* bracket, set wanted_ch to the character that's matchhalf
|
||||
* characters before ch. */
|
||||
/* Step half the number of total characters either backwards or forwards
|
||||
* through matchbrackets to find the wanted complementary bracket. */
|
||||
wanted_ch = ch;
|
||||
|
||||
while (mbmatchhalf > 0) {
|
||||
while (charcount-- > 0) {
|
||||
if (reverse)
|
||||
wanted_ch = matchbrackets + move_mbleft(matchbrackets,
|
||||
wanted_ch - matchbrackets);
|
||||
wanted_ch = matchbrackets + step_left(matchbrackets,
|
||||
wanted_ch - matchbrackets);
|
||||
else
|
||||
wanted_ch += move_mbright(wanted_ch, 0);
|
||||
|
||||
mbmatchhalf--;
|
||||
wanted_ch += char_length(wanted_ch);
|
||||
}
|
||||
|
||||
ch_len = parse_mbchar(ch, NULL, NULL);
|
||||
wanted_ch_len = parse_mbchar(wanted_ch, NULL, NULL);
|
||||
ch_len = char_length(ch);
|
||||
wanted_ch_len = char_length(wanted_ch);
|
||||
|
||||
/* Fill bracket_set in with the values of ch and wanted_ch. */
|
||||
strncpy(bracket_set, ch, ch_len);
|
||||
strncpy(bracket_set + ch_len, wanted_ch, wanted_ch_len);
|
||||
bracket_set[ch_len + wanted_ch_len] = '\0';
|
||||
/* Copy the two complementary brackets into a single string. */
|
||||
strncpy(bracket_pair, ch, ch_len);
|
||||
strncpy(bracket_pair + ch_len, wanted_ch, wanted_ch_len);
|
||||
bracket_pair[ch_len + wanted_ch_len] = '\0';
|
||||
|
||||
while (TRUE) {
|
||||
if (find_bracket_match(reverse, bracket_set)) {
|
||||
/* If we found an identical bracket, increment count. If we
|
||||
* found a complementary bracket, decrement it. */
|
||||
count += (strncmp(openfile->current->data + openfile->current_x,
|
||||
ch, ch_len) == 0) ? 1 : -1;
|
||||
while (find_a_bracket(reverse, bracket_pair)) {
|
||||
/* Increment/decrement balance for an identical/other bracket. */
|
||||
balance += (strncmp(openfile->current->data + openfile->current_x,
|
||||
ch, ch_len) == 0) ? 1 : -1;
|
||||
|
||||
/* If count is zero, we've found a matching bracket. Update
|
||||
* the screen and get out. */
|
||||
if (count == 0) {
|
||||
edit_redraw(current_save, FLOWING);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* We didn't find either an opening or closing bracket.
|
||||
* Indicate this, restore where we were, and get out. */
|
||||
statusbar(_("No matching bracket"));
|
||||
openfile->current = current_save;
|
||||
openfile->current_x = current_x_save;
|
||||
break;
|
||||
/* When balance reached zero, we've found the complementary bracket. */
|
||||
if (balance == 0) {
|
||||
edit_redraw(was_current, FLOWING);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
statusbar(_("No matching bracket"));
|
||||
|
||||
/* Restore the cursor position. */
|
||||
openfile->current = was_current;
|
||||
openfile->current_x = was_current_x;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
817
src/text.c
817
src/text.c
File diff suppressed because it is too large
Load Diff
76
src/utils.c
76
src/utils.c
@@ -159,13 +159,6 @@ bool parse_line_column(const char *str, ssize_t *line, ssize_t *column)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Null a string at a certain index and align it. */
|
||||
void null_at(char **data, size_t index)
|
||||
{
|
||||
*data = charealloc(*data, index + 1);
|
||||
(*data)[index] = '\0';
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so encode its nulls as newlines. */
|
||||
void unsunder(char *str, size_t true_len)
|
||||
@@ -209,7 +202,7 @@ bool is_separate_word(size_t position, size_t length, const char *buf)
|
||||
size_t word_end = position + length;
|
||||
|
||||
/* Get the characters before and after the word, if any. */
|
||||
parse_mbchar(buf + move_mbleft(buf, position), before, NULL);
|
||||
parse_mbchar(buf + step_left(buf, position), before, NULL);
|
||||
parse_mbchar(buf + word_end, after, NULL);
|
||||
|
||||
/* If the word starts at the beginning of the line OR the character before
|
||||
@@ -253,7 +246,7 @@ const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
/* If this is the last possible match, don't try to advance. */
|
||||
if (last_find == ceiling)
|
||||
break;
|
||||
next_rung = move_mbright(haystack, last_find);
|
||||
next_rung = step_right(haystack, last_find);
|
||||
regmatches[0].rm_so = next_rung;
|
||||
regmatches[0].rm_eo = far_end;
|
||||
if (regexec(&search_regexp, haystack, 1, regmatches,
|
||||
@@ -294,17 +287,6 @@ const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
return mbstrcasestr(start, needle);
|
||||
}
|
||||
|
||||
/* This is a wrapper for the perror() function. The wrapper temporarily
|
||||
* leaves curses mode, calls perror() (which writes to stderr), and then
|
||||
* reenters curses mode, updating the screen in the process. Note that
|
||||
* nperror() causes the window to flicker once. */
|
||||
void nperror(const char *s)
|
||||
{
|
||||
endwin();
|
||||
perror(s);
|
||||
doupdate();
|
||||
}
|
||||
|
||||
/* This is a wrapper for the malloc() function that properly handles
|
||||
* things when we run out of memory. */
|
||||
void *nmalloc(size_t howmuch)
|
||||
@@ -336,10 +318,6 @@ char *mallocstrncpy(char *dest, const char *src, size_t n)
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (src == dest)
|
||||
fprintf(stderr, "\r*** Copying a string to itself -- please report a bug ***");
|
||||
#endif
|
||||
dest = charealloc(dest, n);
|
||||
strncpy(dest, src, n);
|
||||
|
||||
@@ -379,7 +357,7 @@ size_t get_page_start(size_t column)
|
||||
* column position of the cursor. */
|
||||
size_t xplustabs(void)
|
||||
{
|
||||
return strnlenpt(openfile->current->data, openfile->current_x);
|
||||
return wideness(openfile->current->data, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Return the index in text of the character that (when displayed) will
|
||||
@@ -405,10 +383,9 @@ size_t actual_x(const char *text, size_t column)
|
||||
|
||||
/* A strnlen() with tabs and multicolumn characters factored in:
|
||||
* how many columns wide are the first maxlen bytes of text? */
|
||||
size_t strnlenpt(const char *text, size_t maxlen)
|
||||
size_t wideness(const char *text, size_t maxlen)
|
||||
{
|
||||
size_t width = 0;
|
||||
/* The screen display width to text[maxlen]. */
|
||||
|
||||
if (maxlen == 0)
|
||||
return 0;
|
||||
@@ -427,7 +404,7 @@ size_t strnlenpt(const char *text, size_t maxlen)
|
||||
}
|
||||
|
||||
/* Return the number of columns that the given text occupies. */
|
||||
size_t strlenpt(const char *text)
|
||||
size_t breadth(const char *text)
|
||||
{
|
||||
size_t span = 0;
|
||||
|
||||
@@ -454,7 +431,7 @@ void remove_magicline(void)
|
||||
if (openfile->filebot->data[0] == '\0' &&
|
||||
openfile->filebot != openfile->filetop) {
|
||||
openfile->filebot = openfile->filebot->prev;
|
||||
free_lines(openfile->filebot->next);
|
||||
delete_node(openfile->filebot->next);
|
||||
openfile->filebot->next = NULL;
|
||||
openfile->totsize--;
|
||||
}
|
||||
@@ -462,15 +439,15 @@ void remove_magicline(void)
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Set (top, top_x) and (bot, bot_x) to the start and end "coordinates" of
|
||||
* the marked region. If right_side_up isn't NULL, set it to TRUE when the
|
||||
* mark is at the top of the marked region, and to FALSE otherwise. */
|
||||
void mark_order(const linestruct **top, size_t *top_x,
|
||||
const linestruct **bot, size_t *bot_x, bool *right_side_up)
|
||||
/* Return in (top, top_x) and (bot, bot_x) the start and end "coordinates"
|
||||
* of the marked region. If right_side_up isn't NULL, set it to TRUE when
|
||||
* the mark is at the top of the marked region, and to FALSE otherwise. */
|
||||
void get_region(const linestruct **top, size_t *top_x,
|
||||
const linestruct **bot, size_t *bot_x, bool *right_side_up)
|
||||
{
|
||||
if ((openfile->current->lineno == openfile->mark->lineno &&
|
||||
openfile->current_x > openfile->mark_x) ||
|
||||
openfile->current->lineno > openfile->mark->lineno) {
|
||||
if (openfile->mark->lineno < openfile->current->lineno ||
|
||||
(openfile->mark == openfile->current &&
|
||||
openfile->mark_x < openfile->current_x)) {
|
||||
*top = openfile->mark;
|
||||
*top_x = openfile->mark_x;
|
||||
*bot = openfile->current;
|
||||
@@ -498,7 +475,7 @@ void get_range(const linestruct **top, const linestruct **bot)
|
||||
} else {
|
||||
size_t top_x, bot_x;
|
||||
|
||||
mark_order(top, &top_x, bot, &bot_x, NULL);
|
||||
get_region(top, &top_x, bot, &bot_x, NULL);
|
||||
|
||||
if (bot_x == 0 && *bot != *top && !also_the_last)
|
||||
*bot = (*bot)->prev;
|
||||
@@ -507,24 +484,19 @@ void get_range(const linestruct **top, const linestruct **bot)
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a line number, return a pointer to the corresponding struct. */
|
||||
linestruct *fsfromline(ssize_t lineno)
|
||||
/* Return a pointer to the line that has the given line number. */
|
||||
linestruct *line_from_number(ssize_t number)
|
||||
{
|
||||
linestruct *f = openfile->current;
|
||||
linestruct *line = openfile->current;
|
||||
|
||||
if (lineno <= openfile->current->lineno)
|
||||
while (f->lineno != lineno && f->prev != NULL)
|
||||
f = f->prev;
|
||||
if (line->lineno > number)
|
||||
while (line->lineno != number)
|
||||
line = line->prev;
|
||||
else
|
||||
while (f->lineno != lineno && f->next != NULL)
|
||||
f = f->next;
|
||||
while (line->lineno != number)
|
||||
line = line->next;
|
||||
|
||||
if (f->lineno != lineno) {
|
||||
statusline(ALERT, "Gone undo line -- please report a bug");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return f;
|
||||
return line;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
|
||||
219
src/winio.c
219
src/winio.c
@@ -27,6 +27,9 @@
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#ifdef ENABLE_UTF8
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef REVISION
|
||||
#define BRANDING REVISION
|
||||
@@ -656,7 +659,7 @@ int parse_kbinput(WINDOW *win)
|
||||
#ifndef NANO_TINY
|
||||
/* When <Tab> is pressed while the mark is on, do an indent. */
|
||||
if (retval == TAB_CODE && openfile->mark && currmenu == MMAIN) {
|
||||
const sc *command = first_sc_for(MMAIN, do_indent);
|
||||
const keystruct *command = first_sc_for(MMAIN, do_indent);
|
||||
|
||||
meta_key = command->meta;
|
||||
return command->keycode;
|
||||
@@ -1654,7 +1657,7 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
{
|
||||
MEVENT mevent;
|
||||
bool in_bottomwin;
|
||||
subnfunc *f;
|
||||
funcstruct *f;
|
||||
|
||||
/* First, get the actual mouse event. */
|
||||
if (getmouse(&mevent) == ERR)
|
||||
@@ -1729,7 +1732,7 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
|
||||
/* And put the corresponding key into the keyboard buffer. */
|
||||
if (f != NULL) {
|
||||
const sc *s = first_sc_for(currmenu, f->func);
|
||||
const keystruct *s = first_sc_for(currmenu, f->func);
|
||||
unget_kbinput(s->keycode, s->meta);
|
||||
}
|
||||
return 1;
|
||||
@@ -1769,9 +1772,9 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
* key itself) and meta_key (whether the key is a meta sequence). The
|
||||
* returned shortcut will be the first in the list that corresponds to
|
||||
* the given sequence. */
|
||||
const sc *get_shortcut(int *kbinput)
|
||||
const keystruct *get_shortcut(int *kbinput)
|
||||
{
|
||||
sc *s;
|
||||
keystruct *s;
|
||||
|
||||
/* Plain characters cannot be shortcuts, so just skip those. */
|
||||
if (!meta_key && ((*kbinput >= 0x20 && *kbinput < 0x7F) ||
|
||||
@@ -1871,7 +1874,7 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
{
|
||||
size_t start_index = actual_x(buf, column);
|
||||
/* The index of the first character that the caller wishes to show. */
|
||||
size_t start_col = strnlenpt(buf, start_index);
|
||||
size_t start_col = wideness(buf, start_index);
|
||||
/* The actual column where that first character starts. */
|
||||
char *converted;
|
||||
/* The expanded string we will return. */
|
||||
@@ -1888,6 +1891,13 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
/* Allocate enough space for converting the relevant part of the line. */
|
||||
converted = charalloc(strlen(buf) * (MAXCHARLEN + tabsize) + 1);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (span > HIGHEST_POSITIVE) {
|
||||
statusline(ALERT, "Span has underflowed -- please report a bug");
|
||||
converted[0] = '\0';
|
||||
return converted;
|
||||
}
|
||||
#endif
|
||||
/* If the first character starts before the left edge, or would be
|
||||
* overwritten by a "<" token, then show placeholders instead. */
|
||||
if (*buf != '\0' && *buf != '\t' && (start_col < column ||
|
||||
@@ -1896,7 +1906,7 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
if (start_col < column) {
|
||||
converted[index++] = control_mbrep(buf, isdata);
|
||||
column++;
|
||||
buf += parse_mbchar(buf, NULL, NULL);
|
||||
buf += char_length(buf);
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -1909,21 +1919,30 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
/* Display the right half of a two-column character as ']'. */
|
||||
converted[index++] = ']';
|
||||
column++;
|
||||
buf += parse_mbchar(buf, NULL, NULL);
|
||||
buf += char_length(buf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
while (*buf != '\0' && (column < beyond || mbwidth(buf) == 0)) {
|
||||
int charlength, charwidth = 1;
|
||||
#ifdef ENABLE_UTF8
|
||||
#define ISO8859_CHAR FALSE
|
||||
#else
|
||||
#define ISO8859_CHAR ((unsigned char)*buf > 0x9F)
|
||||
#endif
|
||||
|
||||
while (*buf != '\0' && (column < beyond || mbwidth(buf) == 0)) {
|
||||
/* A plain printable ASCII character is one byte, one column. */
|
||||
if (((signed char)*buf > 0x20 && *buf != DEL_CODE) || ISO8859_CHAR) {
|
||||
converted[index++] = *(buf++);
|
||||
column++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Show a space as a visible character, or as a space. */
|
||||
if (*buf == ' ') {
|
||||
/* Show a space as a visible character, or as a space. */
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(WHITESPACE_DISPLAY)) {
|
||||
int i = whitelen[0];
|
||||
|
||||
while (i < whitelen[0] + whitelen[1])
|
||||
for (int i = whitelen[0]; i < whitelen[0] + whitelen[1];)
|
||||
converted[index++] = whitespace[i++];
|
||||
} else
|
||||
#endif
|
||||
@@ -1931,15 +1950,15 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
column++;
|
||||
buf++;
|
||||
continue;
|
||||
} else if (*buf == '\t') {
|
||||
/* Show a tab as a visible character, or as as a space. */
|
||||
}
|
||||
|
||||
/* Show a tab as a visible character plus spaces, or as just spaces. */
|
||||
if (*buf == '\t') {
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(WHITESPACE_DISPLAY) && (index > 0 || !isdata ||
|
||||
!ISSET(SOFTWRAP) || column % tabsize == 0 ||
|
||||
column == start_col)) {
|
||||
int i = 0;
|
||||
|
||||
while (i < whitelen[0])
|
||||
for (int i = 0; i < whitelen[0];)
|
||||
converted[index++] = whitespace[i++];
|
||||
} else
|
||||
#endif
|
||||
@@ -1954,47 +1973,54 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
continue;
|
||||
}
|
||||
|
||||
charlength = length_of_char(buf, &charwidth);
|
||||
|
||||
/* If buf contains a control character, represent it. */
|
||||
/* Represent a control character with a leading caret. */
|
||||
if (is_cntrl_mbchar(buf)) {
|
||||
converted[index++] = '^';
|
||||
converted[index++] = control_mbrep(buf, isdata);
|
||||
buf += char_length(buf);
|
||||
column += 2;
|
||||
buf += charlength;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If buf contains a valid non-control character, simply copy it. */
|
||||
if (charlength > 0) {
|
||||
for (; charlength > 0; charlength--)
|
||||
converted[index++] = *(buf++);
|
||||
#ifdef ENABLE_UTF8
|
||||
int charlength, charwidth;
|
||||
wchar_t wc;
|
||||
|
||||
/* Convert a multibyte character to a single code. */
|
||||
charlength = mbtowc(&wc, buf, MAXCHARLEN);
|
||||
|
||||
/* Represent an invalid character with the Replacement Character. */
|
||||
if (charlength < 0 || !is_valid_unicode(wc)) {
|
||||
converted[index++] = '\xEF';
|
||||
converted[index++] = '\xBF';
|
||||
converted[index++] = '\xBD';
|
||||
buf += (charlength > 0 ? charlength : 1);
|
||||
column++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* For any valid character, just copy its bytes. */
|
||||
for (; charlength > 0; charlength--)
|
||||
converted[index++] = *(buf++);
|
||||
|
||||
/* Determine whether the character occupies one or two columns. */
|
||||
charwidth = wcwidth(wc);
|
||||
|
||||
/* If the codepoint is unassigned, assume a width of one. */
|
||||
column += (charwidth < 0 ? 1 : charwidth);
|
||||
|
||||
column += charwidth;
|
||||
#ifdef USING_OLD_NCURSES
|
||||
if (charwidth > 1)
|
||||
seen_wide = TRUE;
|
||||
if (charwidth > 1)
|
||||
seen_wide = TRUE;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Represent an invalid starter byte with the Replacement Character. */
|
||||
converted[index++] = '\xEF';
|
||||
converted[index++] = '\xBF';
|
||||
converted[index++] = '\xBD';
|
||||
column++;
|
||||
buf++;
|
||||
|
||||
/* For invalid codepoints, skip extra bytes. */
|
||||
if (charlength < -1)
|
||||
buf += charlength + 7;
|
||||
#endif /* ENABLE_UTF8 */
|
||||
}
|
||||
|
||||
/* If there is more text than can be shown, make room for the ">". */
|
||||
if (column > beyond || (*buf != '\0' && (isprompt ||
|
||||
(isdata && !ISSET(SOFTWRAP))))) {
|
||||
do {
|
||||
index = move_mbleft(converted, index);
|
||||
index = step_left(converted, index);
|
||||
} while (mbwidth(converted + index) == 0);
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -2016,7 +2042,7 @@ int buffer_number(openfilestruct *buffer)
|
||||
{
|
||||
int count = 1;
|
||||
|
||||
while (buffer != firstfile) {
|
||||
while (buffer != startfile) {
|
||||
buffer = buffer->prev;
|
||||
count++;
|
||||
}
|
||||
@@ -2081,7 +2107,7 @@ void titlebar(const char *path)
|
||||
if (more_than_one) {
|
||||
indicator = charalloc(24);
|
||||
sprintf(indicator, "[%i/%i]", buffer_number(openfile),
|
||||
buffer_number(firstfile->prev));
|
||||
buffer_number(startfile->prev));
|
||||
upperleft = indicator;
|
||||
} else
|
||||
#endif
|
||||
@@ -2099,16 +2125,16 @@ void titlebar(const char *path)
|
||||
else if (ISSET(RESTRICTED))
|
||||
state = _("Restricted");
|
||||
|
||||
pluglen = strlenpt(_("Modified")) + 1;
|
||||
pluglen = breadth(_("Modified")) + 1;
|
||||
}
|
||||
|
||||
/* Determine the widths of the four elements, including their padding. */
|
||||
verlen = strlenpt(upperleft) + 3;
|
||||
prefixlen = strlenpt(prefix);
|
||||
verlen = breadth(upperleft) + 3;
|
||||
prefixlen = breadth(prefix);
|
||||
if (prefixlen > 0)
|
||||
prefixlen++;
|
||||
pathlen = strlenpt(path);
|
||||
statelen = strlenpt(state) + 2;
|
||||
pathlen = breadth(path);
|
||||
statelen = breadth(state) + 2;
|
||||
if (statelen > 2) {
|
||||
pathlen++;
|
||||
pluglen = 0;
|
||||
@@ -2204,16 +2230,15 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
(lastmessage == MILD && importance == HUSH))
|
||||
return;
|
||||
|
||||
va_start(ap, msg);
|
||||
|
||||
/* Curses mode is turned off. If we use wmove() now, it will muck
|
||||
* up the terminal settings. So we just use vfprintf(). */
|
||||
if (isendwin()) {
|
||||
fprintf(stderr, "\n");
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
#ifndef NANO_TINY
|
||||
/* Curses mode shouldn't be off when trying to write to the status bar. */
|
||||
if (!started_curses || isendwin()) {
|
||||
fprintf(stderr, "Out of curses -- please report a bug\n");
|
||||
lastmessage = HUSH;
|
||||
napms(1400);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the ALERT status has been reset, reset the counter. */
|
||||
if (lastmessage == HUSH)
|
||||
@@ -2241,12 +2266,13 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
|
||||
/* Construct the message out of all the arguments. */
|
||||
compound = charalloc(MAXCHARLEN * (COLS + 1));
|
||||
va_start(ap, msg);
|
||||
vsnprintf(compound, MAXCHARLEN * (COLS + 1), msg, ap);
|
||||
va_end(ap);
|
||||
message = display_string(compound, 0, COLS, FALSE, FALSE);
|
||||
free(compound);
|
||||
|
||||
start_col = (COLS - strlenpt(message)) / 2;
|
||||
start_col = (COLS - breadth(message)) / 2;
|
||||
bracketed = (start_col > 1);
|
||||
|
||||
wmove(bottomwin, 0, (bracketed ? start_col - 2 : start_col));
|
||||
@@ -2286,8 +2312,8 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
void bottombars(int menu)
|
||||
{
|
||||
size_t number, itemwidth, i;
|
||||
subnfunc *f;
|
||||
const sc *s;
|
||||
funcstruct *f;
|
||||
const keystruct *s;
|
||||
|
||||
/* Set the global variable to the given menu. */
|
||||
currmenu = menu;
|
||||
@@ -2341,7 +2367,7 @@ void post_one_key(const char *keystroke, const char *tag, int width)
|
||||
wattroff(bottomwin, interface_color_pair[KEY_COMBO]);
|
||||
|
||||
/* If the remaning space is too small, skip the description. */
|
||||
width -= strlenpt(keystroke);
|
||||
width -= breadth(keystroke);
|
||||
if (width < 2)
|
||||
return;
|
||||
|
||||
@@ -2487,8 +2513,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
|
||||
/* If the match is of length zero, skip it. */
|
||||
if (match.rm_so == match.rm_eo) {
|
||||
index = move_mbright(fileptr->data,
|
||||
index + match.rm_eo);
|
||||
index = step_right(fileptr->data, index + match.rm_eo);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2502,16 +2527,15 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
continue;
|
||||
|
||||
start_col = (match.rm_so <= from_x) ?
|
||||
0 : strnlenpt(fileptr->data,
|
||||
0 : wideness(fileptr->data,
|
||||
match.rm_so) - from_col;
|
||||
|
||||
thetext = converted + actual_x(converted, start_col);
|
||||
|
||||
paintlen = actual_x(thetext, strnlenpt(fileptr->data,
|
||||
paintlen = actual_x(thetext, wideness(fileptr->data,
|
||||
match.rm_eo) - from_col - start_col);
|
||||
|
||||
mvwaddnstr(edit, row, margin + start_col,
|
||||
thetext, paintlen);
|
||||
mvwaddnstr(edit, row, margin + start_col, thetext, paintlen);
|
||||
}
|
||||
goto tail_of_loop;
|
||||
}
|
||||
@@ -2574,7 +2598,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
endmatch.rm_so == endmatch.rm_eo) {
|
||||
if (start_line->data[index] == '\0')
|
||||
break;
|
||||
index = move_mbright(start_line->data, index);
|
||||
index = step_right(start_line->data, index);
|
||||
}
|
||||
/* If there is no later start on this line, next step. */
|
||||
if (regexec(varnish->start, start_line->data + index,
|
||||
@@ -2606,7 +2630,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
|
||||
/* Only if it is visible, paint the part to be coloured. */
|
||||
if (endmatch.rm_eo > from_x) {
|
||||
paintlen = actual_x(converted, strnlenpt(fileptr->data,
|
||||
paintlen = actual_x(converted, wideness(fileptr->data,
|
||||
endmatch.rm_eo) - from_col);
|
||||
mvwaddnstr(edit, row, margin, converted, paintlen);
|
||||
}
|
||||
@@ -2626,7 +2650,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
startmatch.rm_eo += index;
|
||||
|
||||
start_col = (startmatch.rm_so <= from_x) ?
|
||||
0 : strnlenpt(fileptr->data,
|
||||
0 : wideness(fileptr->data,
|
||||
startmatch.rm_so) - from_col;
|
||||
|
||||
thetext = converted + actual_x(converted, start_col);
|
||||
@@ -2642,7 +2666,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
* it is more than zero characters long. */
|
||||
if (endmatch.rm_eo > from_x &&
|
||||
endmatch.rm_eo > startmatch.rm_so) {
|
||||
paintlen = actual_x(thetext, strnlenpt(fileptr->data,
|
||||
paintlen = actual_x(thetext, wideness(fileptr->data,
|
||||
endmatch.rm_eo) - from_col - start_col);
|
||||
|
||||
mvwaddnstr(edit, row, margin + start_col,
|
||||
@@ -2656,7 +2680,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
endmatch.rm_so == endmatch.rm_eo) {
|
||||
if (fileptr->data[index] == '\0')
|
||||
break;
|
||||
index = move_mbright(fileptr->data, index);
|
||||
index = step_right(fileptr->data, index);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -2695,7 +2719,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
|
||||
if (*(converted + target_x) != '\0') {
|
||||
charlen = parse_mbchar(converted + target_x, striped_char, NULL);
|
||||
target_column = strnlenpt(converted, target_x);
|
||||
target_column = wideness(converted, target_x);
|
||||
} else if (target_column + 1 == editwincols) {
|
||||
/* Defeat a VTE bug -- see https://sv.gnu.org/bugs/?55896. */
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -2732,7 +2756,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
int paintlen = -1;
|
||||
/* The number of characters to paint. Negative means "all". */
|
||||
|
||||
mark_order(&top, &top_x, &bot, &bot_x, NULL);
|
||||
get_region(&top, &top_x, &bot, &bot_x, NULL);
|
||||
|
||||
if (top->lineno < fileptr->lineno || top_x < from_x)
|
||||
top_x = from_x;
|
||||
@@ -2742,7 +2766,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
/* Only paint if the marked part of the line is on this page. */
|
||||
if (top_x < till_x && bot_x > from_x) {
|
||||
/* Compute on which screen column to start painting. */
|
||||
start_col = strnlenpt(fileptr->data, top_x) - from_col;
|
||||
start_col = wideness(fileptr->data, top_x) - from_col;
|
||||
|
||||
if (start_col < 0)
|
||||
start_col = 0;
|
||||
@@ -2752,7 +2776,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
/* If the end of the mark is onscreen, compute how many
|
||||
* characters to paint. Otherwise, just paint all. */
|
||||
if (bot_x < till_x) {
|
||||
size_t end_col = strnlenpt(fileptr->data, bot_x) - from_col;
|
||||
size_t end_col = wideness(fileptr->data, bot_x) - from_col;
|
||||
paintlen = actual_x(thetext, end_col - start_col);
|
||||
}
|
||||
|
||||
@@ -2786,20 +2810,11 @@ int update_line(linestruct *fileptr, size_t index)
|
||||
|
||||
row = fileptr->lineno - openfile->edittop->lineno;
|
||||
|
||||
/* If the line is offscreen, don't even try to display it. */
|
||||
if (row < 0 || row >= editwinrows) {
|
||||
#ifndef NANO_TINY
|
||||
statusline(ALERT, "Badness: tried to display a line on row %i"
|
||||
" -- please report a bug", row);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* First, blank out the row. */
|
||||
blank_row(edit, row, 0, COLS);
|
||||
|
||||
/* Next, find out from which column to start displaying the line. */
|
||||
from_col = get_page_start(strnlenpt(fileptr->data, index));
|
||||
from_col = get_page_start(wideness(fileptr->data, index));
|
||||
|
||||
/* Expand the line, replacing tabs with spaces, and control
|
||||
* characters with their displayed forms. */
|
||||
@@ -2814,7 +2829,7 @@ int update_line(linestruct *fileptr, size_t index)
|
||||
mvwaddch(edit, row, margin, '<');
|
||||
wattroff(edit, hilite_attribute);
|
||||
}
|
||||
if (strlenpt(fileptr->data) > from_col + editwincols) {
|
||||
if (breadth(fileptr->data) > from_col + editwincols) {
|
||||
wattron(edit, hilite_attribute);
|
||||
mvwaddch(edit, row, COLS - 1, '>');
|
||||
wattroff(edit, hilite_attribute);
|
||||
@@ -3010,20 +3025,13 @@ void edit_scroll(bool direction)
|
||||
{
|
||||
linestruct *line;
|
||||
size_t leftedge;
|
||||
int remainder = 0, nrows = 1;
|
||||
int nrows = 1;
|
||||
|
||||
/* Move the top line of the edit window one row up or down. */
|
||||
if (direction == BACKWARD)
|
||||
remainder = go_back_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
go_back_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
else
|
||||
remainder = go_forward_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
|
||||
if (remainder > 0) {
|
||||
#ifndef NANO_TINY
|
||||
statusline(ALERT, "Could not scroll -- please report a bug");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
go_forward_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
|
||||
/* Actually scroll the text of the edit window one row up or down. */
|
||||
scrollok(edit, TRUE);
|
||||
@@ -3197,7 +3205,7 @@ size_t actual_last_column(size_t leftedge, size_t column)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
bool last_chunk;
|
||||
bool last_chunk = FALSE;
|
||||
size_t end_col = get_softwrap_breakpoint(openfile->current->data,
|
||||
leftedge, &last_chunk) - leftedge;
|
||||
|
||||
@@ -3384,9 +3392,10 @@ void total_refresh(void)
|
||||
if (currmenu != MBROWSER && currmenu != MWHEREISFILE && currmenu != MGOTODIR)
|
||||
titlebar(title);
|
||||
#ifdef ENABLE_HELP
|
||||
if (inhelp)
|
||||
wrap_the_help_text(TRUE);
|
||||
else
|
||||
if (inhelp) {
|
||||
close_buffer();
|
||||
wrap_help_text_into_buffer();
|
||||
} else
|
||||
#endif
|
||||
if (currmenu != MBROWSER && currmenu != MWHEREISFILE && currmenu != MGOTODIR)
|
||||
edit_refresh();
|
||||
@@ -3401,7 +3410,7 @@ void do_cursorpos(bool force)
|
||||
{
|
||||
char saved_byte;
|
||||
size_t sum, cur_xpt = xplustabs() + 1;
|
||||
size_t cur_lenpt = strlenpt(openfile->current->data) + 1;
|
||||
size_t cur_lenpt = breadth(openfile->current->data) + 1;
|
||||
int linepct, colpct, charpct;
|
||||
|
||||
/* If the showing needs to be suppressed, don't suppress it next time. */
|
||||
@@ -3661,7 +3670,7 @@ void do_credits(void)
|
||||
else
|
||||
what = credits[crpos];
|
||||
|
||||
start_col = COLS / 2 - strlenpt(what) / 2 - 1;
|
||||
start_col = COLS / 2 - breadth(what) / 2 - 1;
|
||||
mvwaddstr(edit, editwinrows - 1 - (editwinrows % 2),
|
||||
start_col, what);
|
||||
}
|
||||
|
||||
@@ -10,12 +10,11 @@ color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
||||
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)\>"
|
||||
color green "\<((s?size)|((u_?)?int(8|16|32|64|ptr)))_t\>"
|
||||
color green "\<([[:lower:]]+|(u_?)?int(8|16|32|64|ptr))_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 brightyellow "\<(try|throw|catch|operator|new|delete)\>"
|
||||
color magenta "\<(goto|continue|break|return)\>"
|
||||
color brightcyan "^[[:space:]]*#[[:space:]]*(define|include(_next)?|(un|ifn?)def|endif|el(if|se)|if|warning|error|pragma)"
|
||||
color brightmagenta "'([^'\]|(\\["'abfnrtv\\]))'" "'\\(([0-3]?[0-7]{1,2}))'" "'\\x[0-9A-Fa-f]{1,2}'"
|
||||
|
||||
# GCC builtins.
|
||||
@@ -23,11 +22,15 @@ color cyan "__attribute__[[:space:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidd
|
||||
|
||||
# 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 ""([^"]|\\")*"" "<[^[:blank:]=]*>"
|
||||
color brightyellow ""([^"]|\\")*"" "#[[:space:]]*include[[:space:]]+<[^[:blank:]=]*>"
|
||||
# Multiline strings. This regex is VERY resource intensive,
|
||||
# and sometimes colours things that shouldn't be coloured.
|
||||
###color brightyellow start=""(\\.|[^"])*\\[[:space:]]*$" end="^(\\.|[^"])*""
|
||||
|
||||
# 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)\>"
|
||||
|
||||
# Comments.
|
||||
color brightblue "//.*"
|
||||
color brightblue start="/\*" end="\*/"
|
||||
|
||||
@@ -11,7 +11,7 @@ color cyan "^[[:space:]]*#.*"
|
||||
color ,red " + +"
|
||||
|
||||
# Nano's name, including version.
|
||||
color brightred "(GNU )?[Nn]ano [1-3]\.[0-9][-.[:alnum:]]*\>"
|
||||
color brightred "(GNU )?[Nn]ano [1-4]\.[0-9][-.[:alnum:]]*\>"
|
||||
|
||||
# Email addresses.
|
||||
color magenta "<[[:alnum:].%_+-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}>"
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
## Here is an example for manpages.
|
||||
## Syntax highlighting for man pages.
|
||||
|
||||
syntax man "\.[1-9]x?$"
|
||||
magic "troff or preprocessor input"
|
||||
comment ".\""
|
||||
|
||||
color green "\.(SH|SS|TH) .*"
|
||||
color brightgreen "\.(SH|SS|TH) " "\.([HIT]P)"
|
||||
color brightred "\.(B[IR]?|I[BR]?|R[BI]|S[BM]) .*"
|
||||
color brightblue "\.(B[IR]?|I[BR]?|R[BI]|S[BM]) " "\.([LP]?P)$"
|
||||
# Section headers, title line, and indented paragraphs.
|
||||
color green "^\.(SH|SS|TH) .*"
|
||||
color brightgreen "^\.(SH|SS|TH) " "^\.([HIT]P)"
|
||||
# Type faces, and normal paragraphs.
|
||||
color brightred "^\.(B[IR]?|I[BR]?|R[BI]|S[BM]) .*"
|
||||
color brightblue "^\.(B[IR]?|I[BR]?|R[BI]|S[BM]) " "^\.([LP]?P)$"
|
||||
# Inline type faces.
|
||||
color magenta "\\f[BIPR]"
|
||||
color yellow "\.(br|DT|RS|RE|PD)"
|
||||
# Relative margins, hyperlinks, and various other stuff.
|
||||
color yellow "^\.(RS|RE|UR|UE|PD|DT)"
|
||||
color yellow "^\.(ad|bp|br|ce|de|ds|el|ie|if|fi|ft|hy|ig|in|na|ne|nf|nh|ps|so|sp|ti|tr)"
|
||||
|
||||
# Comments.
|
||||
color cyan "\.?\\\".*"
|
||||
color cyan "(^\.)?\\\".*"
|
||||
|
||||
# Trailing whitespace.
|
||||
color ,green "[[:space:]]+$"
|
||||
|
||||
@@ -18,7 +18,7 @@ icolor brightgreen "^[[:space:]]*(syntax|linter)[[:space:]]+[^[:blank:]]+"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|extendsyntax)\>"
|
||||
|
||||
# Strings
|
||||
color brightmagenta "".+"([[:space:]]|$)"
|
||||
color brightmagenta "([[:space:]]|(start|end)=)".+"([[:space:]]|$)"
|
||||
|
||||
# Colors
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
|
||||
@@ -22,7 +22,7 @@ color yellow " (no-)?[-[:alpha:]]+-format(,|$)"
|
||||
color brightmagenta "%([1-9]\$)?[a-z]*"
|
||||
# Quotes and escaped characters.
|
||||
color yellow "\""
|
||||
color cyan "\\[abcefnrtv"\]"
|
||||
color cyan "\\([abcefnrtv"\]|x[0-9abcdefABCDEF]{2}|[0-7]{3})"
|
||||
# Reminders.
|
||||
color brightwhite,yellow "(FIXME|TODO|XXX)"
|
||||
# Obsolete strings.
|
||||
|
||||
@@ -22,14 +22,15 @@ color brightcyan "\<(exec|print)([[:blank:]]|$)"
|
||||
# Special values.
|
||||
color brightmagenta "\<(False|None|True)\>"
|
||||
|
||||
# Single-quoted strings.
|
||||
color brightgreen "'([^'\]|\\.)+'"
|
||||
color brightgreen ""([^"\]|\\.)+""
|
||||
# Mono-quoted strings.
|
||||
color brightgreen "'([^'\]|\\.)*'|'''"
|
||||
color brightgreen ""([^"\]|\\.)*"|""""
|
||||
color normal "'''|""""
|
||||
# Comments.
|
||||
color brightred "(^|[[:blank:]])#.*"
|
||||
# Triple-quoted strings.
|
||||
color brightgreen start="'''([^'),]|$)" end="(^|[^(\])'''"
|
||||
color brightgreen start="\"\"\"([^"),]|$)" end="(^|[^(\])\"\"\""
|
||||
color brightgreen start=""""([^"),]|$)" end="(^|[^(\])""""
|
||||
|
||||
# Reminders.
|
||||
color brightwhite,yellow "(FIXME|TODO|XXX)"
|
||||
|
||||
Reference in New Issue
Block a user