Compare commits
229 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21a54a3cf6 | ||
|
|
a0147c5a72 | ||
|
|
553940760e | ||
|
|
faa0eb991e | ||
|
|
f54cd02652 | ||
|
|
6dd308d0fb | ||
|
|
4872f42cd2 | ||
|
|
62007c84c6 | ||
|
|
d0f37205af | ||
|
|
f05874ea23 | ||
|
|
0d9080a22c | ||
|
|
1ae90e205a | ||
|
|
d53086d38d | ||
|
|
0b6bb37c56 | ||
|
|
c43a6fdcc1 | ||
|
|
0c613cb1ac | ||
|
|
1e5064ef84 | ||
|
|
5b40bad629 | ||
|
|
45f8fc77e0 | ||
|
|
94347f0811 | ||
|
|
1a4a3de68b | ||
|
|
bf8bd02558 | ||
|
|
544d426d86 | ||
|
|
30a984661b | ||
|
|
7ab8a4d835 | ||
|
|
0353a24400 | ||
|
|
d4304ca88c | ||
|
|
02d8da3bdd | ||
|
|
7a09b655c1 | ||
|
|
c8b26baee8 | ||
|
|
bb394990cd | ||
|
|
7c5d099c6f | ||
|
|
152cc24d1f | ||
|
|
8965103a4d | ||
|
|
d0d293b8af | ||
|
|
839743fd24 | ||
|
|
0b30835dd0 | ||
|
|
a865c25eea | ||
|
|
cf1129a8b4 | ||
|
|
0cd833e64b | ||
|
|
cbf226476d | ||
|
|
9fcfee18e8 | ||
|
|
27eccbec23 | ||
|
|
0bce5ba4d9 | ||
|
|
f9415e347a | ||
|
|
f3c4dadcf6 | ||
|
|
20d1823d90 | ||
|
|
e01bcddf16 | ||
|
|
570fb6c606 | ||
|
|
1de3667555 | ||
|
|
5726514869 | ||
|
|
88234c90bc | ||
|
|
02719ec4bf | ||
|
|
415bf82690 | ||
|
|
9bce8bfeb3 | ||
|
|
2c024a74a9 | ||
|
|
ab8698df47 | ||
|
|
206d89b739 | ||
|
|
eff2e0e291 | ||
|
|
c5e20164c3 | ||
|
|
0f1f53a441 | ||
|
|
bf1a080923 | ||
|
|
b7f8d4819b | ||
|
|
30fc197b66 | ||
|
|
c88a2fd9ca | ||
|
|
b9de5525c4 | ||
|
|
f4d1ef1c4e | ||
|
|
dd157f1494 | ||
|
|
624918800b | ||
|
|
8b8c6bb818 | ||
|
|
b830a7dd38 | ||
|
|
3e5b0ea5fd | ||
|
|
a1132c81a1 | ||
|
|
0496aed4ab | ||
|
|
373e3b880f | ||
|
|
7b1f3f4fe7 | ||
|
|
9517972b58 | ||
|
|
95989e7dfe | ||
|
|
dcda98fb73 | ||
|
|
336fa40055 | ||
|
|
93318b972d | ||
|
|
8656f160d7 | ||
|
|
0e30177db7 | ||
|
|
3089a98169 | ||
|
|
1b704e7c8c | ||
|
|
efb9192ee5 | ||
|
|
f0734dae3e | ||
|
|
e8505b2d3e | ||
|
|
1ebb1da382 | ||
|
|
1fb3218a14 | ||
|
|
a7b1f0f03f | ||
|
|
c782b4cb72 | ||
|
|
5234475781 | ||
|
|
80605c3918 | ||
|
|
d3012be095 | ||
|
|
03bc19fd0c | ||
|
|
e4cef3086b | ||
|
|
9936a6357a | ||
|
|
899bf0ae3a | ||
|
|
1f7384ebd2 | ||
|
|
95fffa99aa | ||
|
|
22f7861694 | ||
|
|
ba96d507dd | ||
|
|
9bf57e5ca0 | ||
|
|
f9103a5cb5 | ||
|
|
e9eabdcdcb | ||
|
|
a1be8b6a19 | ||
|
|
de4fbadf20 | ||
|
|
bdd8920081 | ||
|
|
ae9ec6d4ad | ||
|
|
8f1a657a37 | ||
|
|
7f88eff96f | ||
|
|
3b8c898880 | ||
|
|
6f4f1878fc | ||
|
|
082e5db4b7 | ||
|
|
5eccaa7633 | ||
|
|
d9ac785a07 | ||
|
|
01457ae3d3 | ||
|
|
c757aee235 | ||
|
|
48749a9500 | ||
|
|
4cd3987791 | ||
|
|
aa41eb69c0 | ||
|
|
54103d8ed1 | ||
|
|
53a10ddcaf | ||
|
|
65bf04060b | ||
|
|
a95fb64dd6 | ||
|
|
b235404ade | ||
|
|
ffebd31cbb | ||
|
|
e55227f65f | ||
|
|
b77b54bf73 | ||
|
|
2428620b16 | ||
|
|
cb0289f0dc | ||
|
|
b027263a37 | ||
|
|
1a926d79c5 | ||
|
|
c79fe1a160 | ||
|
|
fef195bce9 | ||
|
|
dd9766c2e0 | ||
|
|
5b870a7632 | ||
|
|
0cf455bc48 | ||
|
|
3e1fc6385b | ||
|
|
544cda6a62 | ||
|
|
28933cf572 | ||
|
|
1635060ba6 | ||
|
|
7a038adfd4 | ||
|
|
f1b5be4bbf | ||
|
|
9ceeabda38 | ||
|
|
204e1b8353 | ||
|
|
d865d7ac8f | ||
|
|
16d237ba1b | ||
|
|
c3031b9b8f | ||
|
|
d289510724 | ||
|
|
60f1090da0 | ||
|
|
8f6ee22b41 | ||
|
|
a083d7f1e1 | ||
|
|
919df09ffa | ||
|
|
ddbff6dcb2 | ||
|
|
4295baa5fe | ||
|
|
467cc8edf3 | ||
|
|
6d111c9343 | ||
|
|
bb667beb5a | ||
|
|
eed765f4f7 | ||
|
|
361267cf25 | ||
|
|
ed493bb99b | ||
|
|
ae7366616f | ||
|
|
58ed3a8152 | ||
|
|
e11021a7a5 | ||
|
|
83c264939b | ||
|
|
d48f3e5e7b | ||
|
|
b18e76d4d8 | ||
|
|
f5c87a7fee | ||
|
|
90ebff00ca | ||
|
|
cdc9a29598 | ||
|
|
ddc1de1939 | ||
|
|
18bf2af9c1 | ||
|
|
452008c81d | ||
|
|
97cbbb0cc8 | ||
|
|
7b9bd65362 | ||
|
|
f72fecee9b | ||
|
|
97a8a62128 | ||
|
|
f095e20a86 | ||
|
|
fa7e9b11df | ||
|
|
838b175d4f | ||
|
|
ba1f990582 | ||
|
|
6795d079b1 | ||
|
|
e739448cd0 | ||
|
|
8e328e43c2 | ||
|
|
cb56a575fd | ||
|
|
a429dc4a76 | ||
|
|
91073be49c | ||
|
|
d5f9be7dc8 | ||
|
|
4ad0490ce4 | ||
|
|
d85098abda | ||
|
|
13f8ddcaf2 | ||
|
|
37e9ada964 | ||
|
|
a99158c7c0 | ||
|
|
3981217e5a | ||
|
|
96b47f2877 | ||
|
|
7da391beb7 | ||
|
|
90cf4838d2 | ||
|
|
4c7ec18a55 | ||
|
|
704a7d7b4f | ||
|
|
64366d9992 | ||
|
|
bd97ae7255 | ||
|
|
2ff398c685 | ||
|
|
4b24ce1c11 | ||
|
|
00c1105c1b | ||
|
|
6a4d88cb4c | ||
|
|
898c4c6fbb | ||
|
|
c1bb6485de | ||
|
|
4bcce96a4f | ||
|
|
caeed6821c | ||
|
|
eb1bf8f927 | ||
|
|
2c8b99d5e9 | ||
|
|
091dd71f08 | ||
|
|
837475519b | ||
|
|
31540e3e7e | ||
|
|
ae3b8579fa | ||
|
|
e1199cd94d | ||
|
|
45d2458b47 | ||
|
|
4c505e5127 | ||
|
|
e3b13ae124 | ||
|
|
e5440b390e | ||
|
|
2a17527381 | ||
|
|
8067efa6cc | ||
|
|
0bb6c0234f | ||
|
|
7947d9d2a5 | ||
|
|
c9ccb39752 | ||
|
|
ada78dc89d | ||
|
|
c6f367268b |
264
ChangeLog
264
ChangeLog
@@ -1,3 +1,267 @@
|
||||
Changes between v2.9.5 and v2.9.6:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (39):
|
||||
build: do not prefix an alternative rcfilename with a dot
|
||||
build: fix compilation when configured with --disable-help
|
||||
bump version numbers and add a news item for the 2.9.6 release
|
||||
command-execution: do not crash when opening the pipe would fail
|
||||
completion: correctly do a signed comparison, to avoid a segfault
|
||||
files: prevent a hang when a call to sigaction() would fail
|
||||
formatting, linting: redetermine the argument list for every run
|
||||
gnulib: update to its current upstream state
|
||||
memory: use a reallocation to reduce the amount of leakage
|
||||
prompt: recognize Yes/No/All in English when the locale gives no match
|
||||
rcfile: skip color commands where some color name is invalid
|
||||
scrolling: don't redraw entire edit window when cursor goes offscreen
|
||||
search: always go forward by default, also when coming from Goto-Line
|
||||
search: use a better value to mean "nothing was typed"
|
||||
speller: don't add an extra newline when saving the text to a tempfile
|
||||
syntax: po: highlight also other escaped characters, not just \n
|
||||
syntax: sh: colorize options only when they are preceded by whitespace
|
||||
tweaks: adjust the translator hint about Yes/No/All
|
||||
tweaks: correct or improve a couple of comments
|
||||
tweaks: elide a function that is called just once
|
||||
tweaks: fix a typo, remove a blank line, and improve some comments
|
||||
tweaks: frob a couple of comments
|
||||
tweaks: group some more of the empty functions together
|
||||
tweaks: improve some comments, and exit with nonzero status upon error
|
||||
tweaks: improve the ordering of a couple of functions
|
||||
tweaks: invert two conditions and reshuffle, to reduce duplication
|
||||
tweaks: move a function to its proper location
|
||||
tweaks: move a function to its proper location
|
||||
tweaks: rearrange a few if statements more symmetrically
|
||||
tweaks: remove the group handling for undoing/redoing (un)indents
|
||||
tweaks: rename a function, to be more distinct from its caller
|
||||
tweaks: rename a function, to be more fitting and descriptive
|
||||
tweaks: rename a variable, for clarity
|
||||
tweaks: rename a variable, to be a bit more fitting
|
||||
tweaks: rename a variable, to be more clear and to match another
|
||||
tweaks: rename a variable, to match another and to be more visible
|
||||
tweaks: reshuffle two declarations
|
||||
tweaks: set the correct flags just once for each spell-fixing session
|
||||
tweaks: use meaningful names instead of puzzling values
|
||||
|
||||
Liu Hao (1):
|
||||
replacing: always clear the backwards flag for ^\, just like for ^W
|
||||
|
||||
|
||||
Changes between v2.9.4 and v2.9.5:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (45):
|
||||
build: exclude more things when configured with --disable-multibuffer
|
||||
build: fix compilation again when configured with --enable-tiny
|
||||
build: fix compilation when configured with --disable-multibuffer
|
||||
build: fix compilation with --enable-{tiny,help,multibuffer}
|
||||
bump version numbers and add a news item for the 2.9.5 release
|
||||
cut: avoid calling renumber() on what might be NULL
|
||||
docs: clarify how the Linux console is deficient: in the arrow keys
|
||||
docs: clarify what the scrollup and scrolldown bindable functions do
|
||||
docs: document the newly added color name "normal"
|
||||
docs: mention in the FAQ that <Shift+Insert> pastes from the clipboard
|
||||
files: prevent an infinite loop when reading from standard input fails
|
||||
files: prevent the undo of reading a file into a new buffer
|
||||
help: describe the Scroll-Up and Scroll-Down commands more precisely
|
||||
help: do not reserve space for line numbers, as they are absent
|
||||
linting: drop messages for other files when configured for one buffer
|
||||
memory: plug a leak, by actually freeing a discarded undo struct
|
||||
scrolling: first move the cursor before pushing current chunk offscreen
|
||||
scrolling: let Scroll-Up/Down keep the cursor in the same text position
|
||||
selecting: don't cancel a softmark when just scrolling the screen
|
||||
small addition: understand color name "normal" to mean the default color
|
||||
syntax: sh: color also the 'cut', 'head', 'tail', and 'sort' commands
|
||||
syntax: sh: color options distinctively, and color also long options
|
||||
syntax: sh: uncolor "tar" when it's part of a filename
|
||||
tweaks: adjust a couple of types, to reduce the number of warnings
|
||||
tweaks: adjust or correct some comments, and rename a function
|
||||
tweaks: adjust the indentation after the previous changes
|
||||
tweaks: bundle some settings for a new buffer
|
||||
tweaks: change a parameter of open_buffer() and invert its logic
|
||||
tweaks: condense some code, to remove a bit of duplication
|
||||
tweaks: drop a handful of unhelpful asserts
|
||||
tweaks: elide an unneeded and shadowing variable
|
||||
tweaks: elide a parameter, as it's always the inverse of another
|
||||
tweaks: elide a parameter that is always 1
|
||||
tweaks: elide two parameters and thus a pair of wrapper functions
|
||||
tweaks: factor out the check for 'viewok' into its own function
|
||||
tweaks: fix a typo and adjust some wording and formatting in the FAQ
|
||||
tweaks: frob some comments plus miscellaneous other stuff
|
||||
tweaks: fuse two ifs into one
|
||||
tweaks: move an 'if' and then remove an unneeded label
|
||||
tweaks: reduce the font size of the questions in the FAQ
|
||||
tweaks: remove an inconsistent space from two pointer declarations
|
||||
tweaks: remove unneeded settings and unsettings of MULTIBUFFER
|
||||
tweaks: reshuffle some movement code, to reduce the number of conditions
|
||||
tweaks: revert commit c88a2fd9 -- the extra variable is needed
|
||||
tweaks: rewrap and amend some lines in the NEWS file
|
||||
|
||||
David Lawrence Ramsey (1):
|
||||
tweaks: correct several parameter types
|
||||
|
||||
Kamil Dudka (1):
|
||||
input: do not crash if sctofunc() returns NULL
|
||||
|
||||
Liu Hao (1):
|
||||
build: fix compilation error when configured with --disable-justify
|
||||
|
||||
|
||||
Changes between v2.9.3 and v2.9.4:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (65):
|
||||
bindings: make a key defined as string work also in browser and viewer
|
||||
bindings: rename the bindable function 'gototext' to 'flipgoto'
|
||||
bindings: revert the ^/ changes, as ^/ is not always Go-To-Line
|
||||
bindings: show ^/ instead of ^_ for Go-To-Line
|
||||
build: fix compilation when configured with --enable-tiny
|
||||
bump version numbers and add a news item for the 2.9.4 release
|
||||
docs: mention that a key can be bound to a string
|
||||
docs: note also in the Info manual that text can be selected with Shift
|
||||
editing: when --smooth is used, make <Enter>-at-bottom scroll one row
|
||||
general: detect in a better way whether we're running on a Linux console
|
||||
gnulib: update to its current upstream state
|
||||
goto: avoid a segfault, by initializing 'answer' when it is NULL
|
||||
help: mention that some keys work on a region when the mark is on
|
||||
help: tweak the descriptions of ^X and ^R
|
||||
input: handle the implant() function separately also for the prompt
|
||||
input: handle the implant() function separately, as it is special
|
||||
memory: avoid a leak when toggling from Search to Goto
|
||||
memory: squeal when there is something wrong, instead of stumbling on
|
||||
new feature: allow binding a key to a string (in a nanorc file)
|
||||
prompt: disallow pasting when in restricted mode
|
||||
rcfile: allow a syntax name to be unquoted
|
||||
search: clear the existing answer when starting a new search
|
||||
search: get rid of some unneeded recursion when just toggling things
|
||||
selecting: cancel the softmark upon any attempt to move the cursor
|
||||
small addition: allow customizing the color of an error message
|
||||
syntax: color also ^/ in nano's help texts and in nanorc files
|
||||
syntaxes: remove quotes from each syntax name, and color it differently
|
||||
syntax: nanorc: color also bindings to a string as valid
|
||||
tweaks: adjust comments and indentation after the previous change
|
||||
tweaks: adjust two comments, move two declarations, rewrap three lines
|
||||
tweaks: appease valgrind concerning syscalls with uninitialized values
|
||||
tweaks: condense a comment and elide an 'if'
|
||||
tweaks: correct a typo in NEWS
|
||||
tweaks: correct a typo that broke binding a key to a string
|
||||
tweaks: do not needlessly renumber the lines in the buffer
|
||||
tweaks: don't call strcmp() to determine whether a string is empty
|
||||
tweaks: drop an assert, add a warning, and change a 'for' to a 'while'
|
||||
tweaks: drop some debugging stuff, and adjust what remains of it
|
||||
tweaks: elide another variable, to call a function less often
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: elide an unneeded variable
|
||||
tweaks: elide an unused variable and parameter
|
||||
tweaks: elide two unneeded booleans
|
||||
tweaks: exclude an unlikely error message from the tiny version
|
||||
tweaks: exclude an unlikely warning from the tiny version
|
||||
tweaks: fix a copy-and-paste error
|
||||
tweaks: make the fsfromline() call only for the undo types that need it
|
||||
tweaks: plug a memory leak when using Verbatim Input at a prompt
|
||||
tweaks: refactor the implanting of a key expansion
|
||||
tweaks: remove another superfluous check
|
||||
tweaks: remove a superfluous check
|
||||
tweaks: remove two deprecated options and six rebindable function names
|
||||
tweaks: remove two superfluous checks, and restrict two others
|
||||
tweaks: rename a parameter and a variable, to be more fitting
|
||||
tweaks: rename a variable to be more distinct and greppable
|
||||
tweaks: rename two variables, to be more meaningful
|
||||
tweaks: reshuffle some code, to be slightly less ugly
|
||||
tweaks: reshuffle some of the search-and-replace cleanup calls
|
||||
tweaks: reshuffle the undo types into mostly the same order everywhere
|
||||
tweaks: shorten the name of two record elements
|
||||
tweaks: slightly rewrap the FAQ's table of contents
|
||||
tweaks: transform a 'do' to a 'while', and reshuffle a comment
|
||||
tweaks: unabbreviate two variable names
|
||||
undo: when redoing, don't try to find a line number that might not exist
|
||||
|
||||
Brand Huntsman (1):
|
||||
color: remove unneeded bright comparision to prevent duplicate pairs
|
||||
|
||||
David Lawrence Ramsey (3):
|
||||
docs: mention that errorcolor does have default colors
|
||||
input: don't stop prepending when the user adds text via a shortcut
|
||||
tweaks: fix typo in rebindable function name
|
||||
|
||||
Tom Levy (1):
|
||||
syntax: go: highlight also floats with leading zeroes as valid
|
||||
|
||||
|
||||
Changes between v2.9.2 and v2.9.3:
|
||||
----------------------------------
|
||||
|
||||
Benno Schulenberg (65):
|
||||
build: fix compilation when configured with --enable(tiny,color,nanorc}
|
||||
build: fix compilation with --enable-tiny --enable-justify
|
||||
build: let ./configure fail (not just warn) when curses.h is missing
|
||||
bump version numbers and add a news item for the 2.9.3 release
|
||||
copyright: update the years for the FSF
|
||||
display: wipe the status bar when doing a total refresh
|
||||
docs: remove the note about needing a recent ncurses for macros to work
|
||||
docs: update the FAQ for the changed default location of history files
|
||||
docs: update the TODO file to the current state of affairs
|
||||
gnulib: update to its current upstream state
|
||||
help: don't get stuck when there is an unwrappable piece of text
|
||||
input: consume only the actual length of an escape sequence
|
||||
input: fully reset state when a three-digit character code is cut short
|
||||
input: make <Shift+Tab> do an unindent also on a Manjaro console
|
||||
input: recognize escape sequences for <Shift+PageUp> and <Shift+PageDown>
|
||||
input: recognize more escape sequences for <Shift+Home> and <Shift+End>
|
||||
input: recognize the deviant keycode for <Ctrl+End> in urxvt
|
||||
options: recognize -M and --trimblanks on the command line
|
||||
painting: look for an end match only after a start match, if any
|
||||
prompt: show whitespace only in the filename, not in the whole line
|
||||
replacing: don't skip the first character of a backwards-marked region
|
||||
search: suppress the occurrence at the cursor only when replacing
|
||||
startup: allow a named pipe as file argument when --noread is used
|
||||
startup: make an error message succinct and to the point
|
||||
startup: move the initialization of colors, so any error gets printed
|
||||
syntax: go: colorize only valid octal numbers
|
||||
syntax: lua: do not color debug.setinfo as it doesn't exist
|
||||
syntax: nanohelp: color also the Sh-Tab key combo
|
||||
tweaks: change a 'do' to a 'while', and return early to elide an 'if'
|
||||
tweaks: check for the type of terminal far earlier
|
||||
tweaks: condense a condition and a comment, and reshuffle a line
|
||||
tweaks: condense and rewrap some comments, and reindent two lines
|
||||
tweaks: condense the conditional compilation of shortcut reassignments
|
||||
tweaks: don't bother freeing the key buffer, just reallocate it
|
||||
tweaks: don't bother to reallocate when the keybuffer size decreases
|
||||
tweaks: drop a superfluous parameter, as it is always 1
|
||||
tweaks: drop a useless assert, and don't abort over an unhandled option
|
||||
tweaks: drop two unneeded initializations, and trim a comment
|
||||
tweaks: elide a tiny intermediate buffer, and rename two variables
|
||||
tweaks: exclude --trimblanks when no wrapping or justifying is configured
|
||||
tweaks: fully include Savefile and Wherewas in the tiny version
|
||||
tweaks: indenting text files with tabs is not a good idea
|
||||
tweaks: mark the two blocks that have a deviant indentation
|
||||
tweaks: move a bunch of comments to the lines that they refer to
|
||||
tweaks: move two functions to their proper place, orderingwise
|
||||
tweaks: remove a fragment of dead code
|
||||
tweaks: remove a handful of redundant (because always true) asserts
|
||||
tweaks: remove a superfluous case -- there can never be four digits
|
||||
tweaks: remove a superfluous check, as we insert always one code
|
||||
tweaks: rename a function, for aptness, and drop a superfluous check
|
||||
tweaks: rename a function, to be more distinct
|
||||
tweaks: rename a variable, and further condense some comments
|
||||
tweaks: rename a variable, for more contrast
|
||||
tweaks: rename a variable, to better fit its usage
|
||||
tweaks: rename two variables, and swap their declaration order
|
||||
tweaks: rename two variables, for preciseness and shortness
|
||||
tweaks: reshuffle a couple of lines
|
||||
tweaks: reshuffle a couple of lines, to make a bit more sense
|
||||
tweaks: reshuffle some stuff, and avoid a memory leak
|
||||
tweaks: reshuffle two condition series, to look better
|
||||
tweaks: rewrap a bunch of lines in the NEWS file
|
||||
tweaks: set a modifier in a single place, for conciseness
|
||||
tweaks: swap the row and col parameters to a more consistent order
|
||||
tweaks: transform a parameter, from a pointer to the value itself
|
||||
wrapping: don't trim a blank character that the user just typed
|
||||
|
||||
Brand Huntsman (1):
|
||||
startup: parse interface colors when they are read, not when initialized
|
||||
|
||||
|
||||
Changes between v2.9.1 and v2.9.2:
|
||||
----------------------------------
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@ Improvements in GNU nano
|
||||
========================
|
||||
|
||||
Since 2.9.0:
|
||||
- Addition of the color name "normal", meaning the default color.
|
||||
- A key can be bound to a string -- any mix of text and commands.
|
||||
- Error messages are shown by default in bright white on red.
|
||||
- <Tab> and <Shift+Tab> can be used to indent/unindent a marked region.
|
||||
- Can snip trailing whitespace while typing, with 'set trimblanks'.
|
||||
- The ability to record and replay a series of keystrokes (a macro).
|
||||
|
||||
92
README
92
README
@@ -1,76 +1,76 @@
|
||||
|
||||
GNU nano -- an enhanced clone of the Pico text editor
|
||||
GNU nano -- an enhanced clone of the Pico text editor
|
||||
|
||||
Overview
|
||||
|
||||
The nano project was started because of a few "problems" with the
|
||||
wonderfully easy-to-use and friendly Pico text editor.
|
||||
The nano project was started because of a few "problems" with the
|
||||
wonderfully easy-to-use and friendly Pico text editor.
|
||||
|
||||
First and foremost was its license: the Pine suite does not use
|
||||
the GPL or a GPL-friendly license, and has unclear restrictions on
|
||||
redistribution. Because of this, Pine and Pico are not included
|
||||
with many GNU/Linux distributions. Also, other features (like
|
||||
go-to-line-number or search-and-replace) were unavailable until
|
||||
recently or require a command-line flag. Yuck.
|
||||
First and foremost was its license: the Pine suite does not use
|
||||
the GPL or a GPL-friendly license, and has unclear restrictions on
|
||||
redistribution. Because of this, Pine and Pico are not included
|
||||
with many GNU/Linux distributions. Also, other features (like
|
||||
go-to-line-number or search-and-replace) were unavailable until
|
||||
recently or require a command-line flag. Yuck.
|
||||
|
||||
nano aims to solve these problems by emulating the functionality of
|
||||
Pico as closely as possible while addressing the problems above and
|
||||
providing other extra functionality.
|
||||
nano aims to solve these problems by emulating the functionality of
|
||||
Pico as closely as possible while addressing the problems above and
|
||||
providing other extra functionality.
|
||||
|
||||
The nano editor is an official GNU package. For more information on
|
||||
GNU and the Free Software Foundation, please see http://www.gnu.org/.
|
||||
The nano editor is an official GNU package. For more information on
|
||||
GNU and the Free Software Foundation, please see http://www.gnu.org/.
|
||||
|
||||
How to compile and install nano
|
||||
|
||||
Download the nano source code, then:
|
||||
Download the nano source code, then:
|
||||
|
||||
tar xvzf nano-x.y.z.tar.gz
|
||||
cd nano-x.y.z
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
tar xvzf nano-x.y.z.tar.gz
|
||||
cd nano-x.y.z
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
It's that simple. Use --prefix with configure to override the
|
||||
default installation directory of /usr/local.
|
||||
It's that simple. Use --prefix with configure to override the
|
||||
default installation directory of /usr/local.
|
||||
|
||||
If you haven't configured with the --disable-nanorc option, after
|
||||
installation you may want to copy the doc/sample.nanorc file to
|
||||
your home directory, rename it to ".nanorc", and then edit it
|
||||
according to your taste.
|
||||
If you haven't configured with the --disable-nanorc option, after
|
||||
installation you may want to copy the doc/sample.nanorc file to
|
||||
your home directory, rename it to ".nanorc", and then edit it
|
||||
according to your taste.
|
||||
|
||||
Web Page
|
||||
|
||||
https://nano-editor.org/
|
||||
https://nano-editor.org/
|
||||
|
||||
Mailing Lists
|
||||
|
||||
There are three nano-related mailing-lists.
|
||||
There are three nano-related mailing-lists.
|
||||
|
||||
+ info-nano@gnu.org is a very low traffic list used to announce
|
||||
new nano versions or other important info about the project.
|
||||
+ help-nano@gnu.org is for those seeking to get help without
|
||||
wanting to hear about the technical details of its development.
|
||||
+ nano-devel@gnu.org is the list used by the people that make nano
|
||||
and a general development discussion list, with moderate traffic.
|
||||
+ info-nano@gnu.org is a very low traffic list used to announce
|
||||
new nano versions or other important info about the project.
|
||||
+ help-nano@gnu.org is for those seeking to get help without
|
||||
wanting to hear about the technical details of its development.
|
||||
+ nano-devel@gnu.org is the list used by the people that make nano
|
||||
and a general development discussion list, with moderate traffic.
|
||||
|
||||
To subscribe, send email to <name>-request@gnu.org with a subject
|
||||
of "subscribe", where <name> is the list you want to subscribe to.
|
||||
To subscribe, send email to <name>-request@gnu.org with a subject
|
||||
of "subscribe", where <name> is the list you want to subscribe to.
|
||||
|
||||
Bug Reports
|
||||
|
||||
To report a bug, please file a description of the problem on nano's
|
||||
bug tracker (https://savannah.gnu.org/bugs/?group=nano -- hover on
|
||||
"Bugs", then click "Submit new"). The issue may have already been
|
||||
reported, so please look first.
|
||||
To report a bug, please file a description of the problem on nano's
|
||||
bug tracker (https://savannah.gnu.org/bugs/?group=nano -- hover on
|
||||
"Bugs", then click "Submit new"). The issue may have already been
|
||||
reported, so please look first.
|
||||
|
||||
Current Status
|
||||
|
||||
Since version 2.5.0, GNU nano has abandoned the distinction between
|
||||
a stable and a development branch: it is now on a "rolling" release
|
||||
-- fixing bugs and adding new features go hand in hand.
|
||||
Since version 2.5.0, GNU nano has abandoned the distinction between
|
||||
a stable and a development branch: it is now on a "rolling" release
|
||||
-- fixing bugs and adding new features go hand in hand.
|
||||
|
||||
Copyright Years
|
||||
|
||||
When in any file of this package a copyright notice mentions a
|
||||
year range (such as 1999-2011), it is a shorthand for a list of
|
||||
all the years in that interval.
|
||||
When in any file of this package a copyright notice mentions a
|
||||
year range (such as 1999-2011), it is a shorthand for a list of
|
||||
all the years in that interval.
|
||||
|
||||
16
TODO
16
TODO
@@ -2,11 +2,9 @@ A list of desired features
|
||||
--------------------------
|
||||
|
||||
Somewhat urgent:
|
||||
- Make undo/redo work also for justifying and indenting.
|
||||
- Make undo/redo work also for justifying.
|
||||
- Detect when text is being pasted, so that we can handle it faster.
|
||||
See https://savannah.gnu.org/bugs/?40060.
|
||||
- Allow to define and execute a macro: a stored sequence of keystrokes.
|
||||
See https://savannah.gnu.org/bugs/?50314.
|
||||
- Allow color syntaxes to apply to more than just color, so that we can
|
||||
e.g. specify a different alternate spell checker depending on which
|
||||
file type we have open.
|
||||
@@ -15,15 +13,16 @@ Somewhat urgent:
|
||||
See also https://savannah.gnu.org/bugs/?28993.
|
||||
|
||||
Vague musings:
|
||||
- FriBidi support?
|
||||
- Add support for right-to-left text (RTL), through FriBidi?
|
||||
- Allow setting marks (saved positions, not to be confused with the
|
||||
mark set via Ctrl-^) at various lines and/or columns in the buffer,
|
||||
and allow movement between them with a single keystroke?
|
||||
- Make matching bracket searches sophisticated enough to skip over
|
||||
brackets inside comments?
|
||||
- Allow indentation of marked text by spaces as well as tabs?
|
||||
- Allow indentation to add just enough columns to reach the nearest
|
||||
multiple of tabsize, rather than always adding tabsize columns?
|
||||
|
||||
For version 2.9:
|
||||
- Make undo/redo work also for indenting. [DONE]
|
||||
- Allow to record and replay a macro: a stored series of keystrokes. [DONE]
|
||||
|
||||
For version 2.8:
|
||||
- Allow text searches in the help viewer. [DONE]
|
||||
@@ -41,8 +40,7 @@ For version 2.2:
|
||||
- Undo/Redo keys (M-U and M-E)? [DONE]
|
||||
- Fix problems with color syntaxes highlighting lines too aggressively. [DONE]
|
||||
- Allow nano to work like a pager (reading from stdin). [DONE]
|
||||
- Allow color syntaxes to be selected based on more than just filename
|
||||
extension. [DONE]
|
||||
- Select a color syntax based on more than just the filename extension. [DONE]
|
||||
- Allow soft wrapping as well as hard wrapping? [DONE]
|
||||
|
||||
For version 2.0:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="44100f563482fe469a33abecda5797da04fc3c61"
|
||||
gnulib_hash="214bf852d8dab02bf62900e61facef2c9f48f2f4"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
10
configure.ac
10
configure.ac
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
AC_INIT([GNU nano], [2.9.2], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [2.9.6], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.14])
|
||||
@@ -565,10 +565,10 @@ if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
fi
|
||||
|
||||
if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
AC_MSG_WARN([
|
||||
*** No curses lib available. Consider getting the official ncurses
|
||||
*** distribution from ftp://ftp.gnu.org/pub/gnu/ncurses if you get
|
||||
*** errors compiling nano.])
|
||||
AC_MSG_ERROR([
|
||||
*** No curses lib was found. Please install the curses header files
|
||||
*** from libncursesw5-dev (Debian), ncurses-devel (Fedora), or similar.
|
||||
*** (Or install ncurses from https://ftp.gnu.org/gnu/ncurses/.)])
|
||||
else
|
||||
AC_MSG_RESULT([Using $CURSES_LIB_NAME as the curses library])
|
||||
fi
|
||||
|
||||
150
doc/faq.html
150
doc/faq.html
@@ -7,21 +7,23 @@
|
||||
<body text="#330000" bgcolor="#ffffff" link="#0000ef" vlink="#51188e" alink="#ff0000">
|
||||
|
||||
<h1>The GNU nano editor FAQ</h1>
|
||||
<h2>Table of Contents</h2>
|
||||
<h2><a href="#1">1. General</a></h2>
|
||||
<h3>Table of Contents</h3>
|
||||
<h3><a href="#1">1. General</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#1.1">1.1. What is GNU nano?</a><br>
|
||||
<a href="#1.2">1.2. What is the history behind nano?</a><br>
|
||||
<a href="#1.3">1.3. Why the name change from TIP?</a><br>
|
||||
<a href="#1.4">1.4. What is the current version of nano?</a><br>
|
||||
<a href="#1.5">1.5. I want to read the manpage without having to download the program!</a></p></blockquote>
|
||||
<h2><a href="#2">2. Where to get GNU nano.</a></h2>
|
||||
<a href="#1.5">1.5. I want to read the manpage without having to download the program!</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#2">2. Where to get GNU nano.</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#2.1">2.1. FTP and WWW sites that carry nano.</a><br>
|
||||
<a href="#2.2">2.2. RedHat and derivatives (.rpm) packages.</a><br>
|
||||
<a href="#2.3">2.3. Debian (.deb) packages.</a><br>
|
||||
<a href="#2.4">2.4. By GIT (for the brave).</a></p></blockquote>
|
||||
<h2><a href="#3">3. Installation and Configuration</a></h2>
|
||||
<a href="#2.4">2.4. By GIT (for the brave).</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#3">3. Installation and Configuration</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#3.1">3.1. How do I install the RPM or DEB package?</a><br>
|
||||
<a href="#3.2">3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</a><br>
|
||||
@@ -31,46 +33,52 @@
|
||||
<a href="#3.7">3.7. Tell me more about this multibuffer stuff!</a><br>
|
||||
<a href="#3.8">3.8. Tell me more about this verbatim input stuff!</a><br>
|
||||
<a href="#3.9a">3.9a. How do I make a .nanorc file that nano will read when I start it?</a><br>
|
||||
<a href="#3.9b">3.9b. How about in Win32?</a></p></blockquote>
|
||||
<h2><a href="#4">4. Running</a></h2>
|
||||
<a href="#3.9b">3.9b. How about in Win32?</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#4">4. Running</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#4.1">4.1. How do I open a file with a name beginning with '+' from the command line?</a><br>
|
||||
<a href="#4.2">4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</a><br>
|
||||
<a href="#4.3">4.3. Ack! My numeric keypad's keys don't work properly when NumLock is off! What can I do?</a><br>
|
||||
<a href="#4.4">4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</a><br>
|
||||
<a href="#4.5">4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</a><br>
|
||||
<a href="#4.6">4.6. nano crashes when I type <insert keystroke here>!</a><br>
|
||||
<a href="#4.6">4.6. nano crashes when I type <insert keystrokes here>!</a><br>
|
||||
<a href="#4.7">4.7. nano crashes when I resize my window. How can I fix that?</a><br>
|
||||
<a href="#4.8a">4.8a. When I paste text into a document, each line gets indented further than the last. Why does nano do this, and how can I avoid it?</a><br>
|
||||
<a href="#4.8b">4.8b. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?<a><br>
|
||||
<a href="#4.8a">4.8a. With what keystroke can I paste text from the clipboard into nano?</a><br>
|
||||
<a href="#4.8b">4.8b. When I paste text into a document, each line gets indented further than the last. Why? And how can I stop this?</a><br>
|
||||
<a href="#4.8c">4.8c. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?<a><br>
|
||||
<a href="#4.9">4.9. I've compiled nano with color support, but I don't see any color when I run it!</a><br>
|
||||
<a href="#4.10">4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</a><br>
|
||||
<a href="#4.11">4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and nano's mouse support is turned on?</a><br>
|
||||
<a href="#4.12">4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</a></p></blockquote>
|
||||
<h2><a href="#5">5. Internationalization</a></h2>
|
||||
<a href="#4.12">4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#5">5. Internationalization</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#5.1">5.1. There's no translation for my language!</a><br>
|
||||
<a href="#5.2">5.2. I don't like the translation for <x> in my language. How can I fix it?</a><br>
|
||||
<a href="#5.3">5.3. What is the status of Unicode support?</a></p></blockquote>
|
||||
<h2><a href="#6">6. Advocacy and Licensing</a></h2>
|
||||
<a href="#5.3">5.3. What is the status of Unicode support?</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#6">6. Advocacy and Licensing</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#6.1">6.1. Why should I use nano instead of Pico?</a><br>
|
||||
<a href="#6.2">6.2. Why should I use Pico instead of nano?</a><br>
|
||||
<a href="#6.3">6.3. What is so bad about the older Pine license?</a><br>
|
||||
<a href="#6.4">6.4. Okay, well, what mail program should I use then?</a></p></blockquote>
|
||||
<h2><a href="#7">7. Miscellaneous</a></h2>
|
||||
<a href="#6.4">6.4. Okay, well, what mail program should I use then?</a>
|
||||
</p></blockquote>
|
||||
<h3><a href="#7">7. Miscellaneous</a></h3>
|
||||
<blockquote><p>
|
||||
<a href="#7.1">7.1. Where can I ask questions or send suggestions?</a><br>
|
||||
<a href="#7.2">7.2. How do I submit a bug report or patch?</a><br>
|
||||
<a href="#7.3">7.3. I want to send the development team a big load of cash (or just a thank you).</a><br>
|
||||
<a href="#7.4">7.4. How do I join the development team?</a><br>
|
||||
<a href="#7.5">7.5. Can I have write access to the GIT tree?</a></p></blockquote>
|
||||
<a href="#7.5">7.5. Can I have write access to the GIT tree?</a>
|
||||
</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="1"></a>1. General</h1>
|
||||
<h2><a name="1.1"></a>1.1. What is GNU nano?</h2>
|
||||
<h3><a name="1.1"></a>1.1. What is GNU nano?</h3>
|
||||
<blockquote><p>GNU nano is designed to be a free replacement for the Pico text editor, part of the Pine email suite from <a href="http://www.washington.edu/pine/">The University of Washington</a>. It aims to "emulate Pico as closely as possible and then include extra functionality".</p></blockquote>
|
||||
<h2><a name="1.2"></a>1.2. What is the history behind nano?</h2>
|
||||
<h3><a name="1.2"></a>1.2. What is the history behind nano?</h3>
|
||||
<blockquote><p>Funny you should ask!</p>
|
||||
<p><b>In the beginning...</b></p>
|
||||
<p>For years Pine was THE program used to read email on a Unix system. The Pico text editor is the portion of the program one would use to compose his or her mail messages. Many beginners to Unix flocked to Pico and Pine because of their well organized, easy to use interfaces. With the proliferation of GNU/Linux in the mid to late 90's, many University students became intimately familiar with the strengths (and weaknesses) of Pine and Pico.</p>
|
||||
@@ -80,30 +88,30 @@
|
||||
<p>It was in late 1999 when Chris Allegretta (our hero) was yet again complaining to himself about the less-than-perfect license Pico was distributed under, the 1000 makefiles that came with it and how just a few small improvements could make it the Best Editor in the World (TM). Having been a convert from Slackware to Debian, he missed having a simple binary package that included Pine and Pico, and had grown tired of downloading them himself.</p>
|
||||
<p>Finally something snapped inside and Chris coded and hacked like a madman for many hours straight one weekend to make a (barely usable) Pico clone, at the time called TIP (Tip Isn't Pico). The program could not be invoked without a filename, could not save files, had no help text display, spell checker, and so forth. But over time it improved, and with the help of a few great coders it matured to the (hopefully) stable state it is in today.</p>
|
||||
<p>In February 2001, nano was declared an official GNU program by Richard Stallman. nano also reached its first production release on March 22, 2001.</p></blockquote>
|
||||
<h2><a name="1.3"></a>1.3. Why the name change from TIP?</h2>
|
||||
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
|
||||
<blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program "establishes a full duplex terminal connection to a remote host", and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote>
|
||||
<h2><a name="1.4"></a>1.4. What is the current version of nano?</h2>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>2.9.2</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<h2><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h2>
|
||||
<h3><a name="1.4"></a>1.4. What is the current version of nano?</h3>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>2.9.6</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<h3><a name="1.5"></a>1.5. I want to read the man page without having to download the program!</h3>
|
||||
<blockquote><p>Jeez, demanding, aren't we? Okay, look <a href="https://nano-editor.org/dist/latest/nano.1.html">here</a>.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="2"></a>2. Where to get GNU nano.</h1>
|
||||
<h2><a name="2.1"></a>2.1. Web sites that carry nano.</h2>
|
||||
<h3><a name="2.1"></a>2.1. Web sites that carry nano.</h3>
|
||||
<blockquote><p>The nano source tarballs can be downloaded from the following web sites:</p>
|
||||
<ul>
|
||||
<li><a href="https://nano-editor.org/dist/">https://nano-editor.org/dist/</a></li>
|
||||
<li><a href="https://ftp.gnu.org/gnu/nano/">https://ftp.gnu.org/gnu/nano/</a></li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<h2><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h2>
|
||||
<h3><a name="2.2"></a>2.2. RPM packages (RedHat, OpenSuse, and derivatives).</h3>
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li><a href="https://kojipkgs.fedoraproject.org//packages/nano/">https://kojipkgs.fedoraproject.org//packages/nano/</a></li>
|
||||
<li><a href="https://software.opensuse.org/package/nano">https://software.opensuse.org/package/nano</a></li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<h2><a name="2.3"></a>2.3. Deb packages (Debian and derivatives):</h2>
|
||||
<h3><a name="2.3"></a>2.3. Deb packages (Debian and derivatives):</h3>
|
||||
<blockquote><p>Debian users can check out the current nano packages for:</p>
|
||||
<ul>
|
||||
<li><a href="http://packages.debian.org/stable/editors/nano">stable</a></li>
|
||||
@@ -112,14 +120,14 @@
|
||||
</ul>
|
||||
<p>You can also have a look at the <a href="ftp://ftp.debian.org/debian/pool/main/n/nano/">Package Pool</a> to see all the available binary and source packages.</p>
|
||||
</blockquote>
|
||||
<h2><a name="2.4"></a>2.4. By GIT (for the brave).</h2>
|
||||
<h3><a name="2.4"></a>2.4. By GIT (for the brave).</h3>
|
||||
<blockquote><p>For the 'bleeding edge' current version of nano, you can use GIT to download the current source code. <b>Note:</b> believe it or not, by downloading code that has not yet stabilized into an official release, there could quite possibly be bugs, in fact the code may not even compile! Anyway, see <a href="http://git.savannah.gnu.org/cgit/nano.git/tree/README.GIT">the nano GIT document</a> for info on anonymous GIT access to the nano source.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="3"></a>3. Installation and Configuration</h1>
|
||||
<h2><a name="3.1"></a>3.1. How do I install the RPM or DEB package?</h2>
|
||||
<h3><a name="3.1"></a>3.1. How do I install the RPM or DEB package?</h3>
|
||||
<blockquote><p>It's simple really! As root, type <b>rpm -Uvh nano-x.y.z-1.i386.rpm</b> if you have a RedHat-ish system or <b>dpkg -i nano_x.y.z-1.deb</b> if you have a Debian-ish system, where <b>x.y.z</b> is the release of nano. There are other programs to install packages, and if you wish to use those, knock yourself out.</p></blockquote>
|
||||
<h2><a name="3.2"></a>3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h2>
|
||||
<h3><a name="3.2"></a>3.2. Compiling from source: WHAT THE HECK DO I DO NOW?</h3>
|
||||
<blockquote><p>Okay, take a deep breath, this really isn't hard. Unpack the nano source with a command like:</p>
|
||||
<p><b>tar -xvf nano-x.y.z.tar.gz</b></p>
|
||||
<p>Then you need to run <b>configure</b> with any options you might want (if any).</p>
|
||||
@@ -128,13 +136,13 @@
|
||||
<b>./configure</b><br>
|
||||
<b>make</b><br>
|
||||
<b>make install</b> (as root, of course)</p></blockquote>
|
||||
<h2><a name="3.3"></a>3.3. Why does everything go into /usr/local?</h2>
|
||||
<h3><a name="3.3"></a>3.3. Why does everything go into /usr/local?</h3>
|
||||
<blockquote><p>Well, that's what the <b>configure</b> script defaults to. If you wish to change this, simply do this:</p>
|
||||
<p><b>./configure --prefix=/usr</b></p>
|
||||
<p>to put nano into /usr/bin when you run <b>make install</b>.</p></blockquote>
|
||||
<h2><a name="3.5"></a>3.5. nano should automatically run strip on the binary when installing it!</h2>
|
||||
<h3><a name="3.5"></a>3.5. nano should automatically run strip on the binary when installing it!</h3>
|
||||
<blockquote><p>Actually, it does, but you have to use <b>make install-strip</b>. The default make install does not, and will not, run strip automatically.</p></blockquote>
|
||||
<h2><a name="3.6"></a>3.6. How can I make the executable smaller? This is too bloated!</h2>
|
||||
<h3><a name="3.6"></a>3.6. How can I make the executable smaller? This is too bloated!</h3>
|
||||
<blockquote><p>Actually, there are several parts of the editor that can be disabled. You can pass arguments to the <b>configure</b> script that disable certain features. Here's a brief list:</p>
|
||||
<pre>
|
||||
<b>--disable-browser</b> Disable the built-in file browser
|
||||
@@ -157,49 +165,51 @@
|
||||
<p>There's also the <b>--enable-tiny</b> option which disables everything above, as well as some larger chunks of the program (like the marker code that you use with Control-^ to select text). Also, if you know you aren't going to be using other languages, you can use <b>--disable-nls</b> to disable internationalization and save a few K to a few dozen K depending on whether you have locale support on your system. And finally, there's always good old <b>strip</b> to strip all debugging code and code that exists in libraries on your system.</p>
|
||||
<p>With <b>--disable-wrapping-as-root</b> you can disable any hard-wrapping by default when the user is root, useful to prevent accidentally changing long lines in system configuration files.</p>
|
||||
</blockquote>
|
||||
<h2><a name="3.7"></a>3.7. Tell me more about this multibuffer stuff!</h2>
|
||||
<blockquote><p>To use multiple file buffers, you must not have configured nano with <b>--disable-multibuffer</b> nor with <b>--enable-tiny</b> (use <b>nano -V</b> to check the compilation options). Then when you want to insert a file into its own buffer instead of into the current file, just hit <b>Meta-F</b> after typing <b>^R</b>. If you always want files to be loaded into their own buffers, use the <b>--multibuffer</b> or <b>-F</b> flag when you invoke nano.</p>
|
||||
<p>You can move between the buffers you have open with the <b>Meta-<</b> and <b>Meta-></b> keys, or more easily without holding Shift: <b>Meta-,</b> and <b>Meta-.</b> (clear as mud, right? =-). When you have more than one file buffer open, the ^X shortcut will say "Close", instead of the normal "Exit" when only one buffer is open.</p></blockquote>
|
||||
<h2><a name="3.8"></a>3.8. Tell me more about this verbatim input stuff!</h2>
|
||||
<h3><a name="3.7"></a>3.7. Tell me more about this multibuffer stuff!</h3>
|
||||
<blockquote><p>To use multiple file buffers, you must not have configured nano with <b>--disable-multibuffer</b> nor with <b>--enable-tiny</b> (use <b>nano -V</b> to check the compilation options). Then when you want to insert a file into its own buffer instead of into the current file, just hit <b>Meta-F</b> after typing <b>^R</b>. If you always want files to be loaded into their own buffers, use the <b>-F</b> or <b>--multibuffer</b> flag when you invoke nano, or add <b>set multibuffer</b> to your .nanorc file.</p>
|
||||
<p>You can move between the buffers you have open with the <b>Meta-<</b> and <b>Meta-></b> keys, or more easily without holding Shift: <b>Meta-,</b> and <b>Meta-.</b> (clear as mud, right? =-). When you have more than one buffer open, the ^X shortcut will say "Close", instead of "Exit".</p></blockquote>
|
||||
<h3><a name="3.8"></a>3.8. Tell me more about this verbatim input stuff!</h3>
|
||||
<blockquote><p>When you want to insert a literal character into the file you're editing, such as a control character that nano usually treats as a command, first press <b>Meta-V</b> (if you're not at a prompt, you'll get the message "Verbatim Input" on the status bar), then press the key(s) that generate the character you want.</p>
|
||||
<p>Alternatively, if you've enabled Unicode support (see section <a href="#5.3">5.3</a>), you can press <b>Meta-V</b> and then type a six-digit hexadecimal code (from 000000 to 10FFFF, case-insensitive), and the character with the corresponding value will be inserted. The statubar will change to "Unicode Input: ......" when you do this.</p></blockquote>
|
||||
<h2><a name="3.9a"></a>3.9a. How do I make a .nanorc file that will be read when I start nano?</h2>
|
||||
<p>Alternatively, if Unicode support is enabled (see section <a href="#5.3">5.3</a>), you can press <b>Meta-V</b> and then type a six-digit hexadecimal code (from 000000 to 10FFFF, case-insensitive), and the character with the corresponding value will be inserted. The status bar will change to "Unicode Input: ......" when you do this.</p></blockquote>
|
||||
<h3><a name="3.9a"></a>3.9a. How do I make a .nanorc file that will be read when I start nano?</h3>
|
||||
<blockquote><p>It's not hard at all! But, your nano must <b>not</b> have been compiled with <b>--disable-nanorc</b>. Then simply copy the <b>sample.nanorc</b> that came with the nano source or your nano package (most likely in /usr/doc/nano) to .nanorc in your home directory. If you didn't get one, the syntax of the file is simple. Flags are turned on and off by using the words <b>set</b> and <b>unset</b> plus the long option name for the feature. For example, "set nowrap" or "set smarthome".</p></blockquote>
|
||||
<h2><a name="3.9b"></a>3.9b. How about in Win32?</h2>
|
||||
<h3><a name="3.9b"></a>3.9b. How about in Win32?</h3>
|
||||
<blockquote><p>If you're using the official nano .zip file and have extracted all the files, you should take the file nano.rc and place it somewhere on your Win32 system (for example, if you have write permission to do so, at the top of C:\). Then you must create an Environment variable called HOME which points to the directory where you put nano.rc. In Windows XP, you can get to Environment variables by right-clicking "My Computer" either on the desktop or in the Start Menu, and selecting Properties. This should bring up the System Properties panel. Then click the Advanced Tab, and there should be a button called Environment Variables. Click that to bring up the Environment Variables section. Now, under User Variables you should be able to click the New button, and make a new Variables Name called HOME, with the Variable Value of whatever path you copied nano.rc into (just the directory name; don't add nano.rc onto the end).</p>
|
||||
<p>We're still working on documentation for enabling syntax highlighting on Win32; please bear with us.</p>
|
||||
<p>Note that the nano.rc file must remain Unix-formatted in order for nano to understand it. In other words, you should probably use only nano to edit its config file. Other programs like Wordpad and Notepad will convert the file to DOS format when saving, and the latter does not even properly read Unix-formatted files to begin with.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="4"></a>4. Running</h1>
|
||||
<h2><a name="4.1"></a>4.1. How do I open a file with a name beginning with '+' from the command line?</h2>
|
||||
<h3><a name="4.1"></a>4.1. How do I open a file with a name beginning with '+' from the command line?</h3>
|
||||
<blockquote><p>If a command-line option that begins with '+' is followed by another option, the former is always treated as a starting line and column number, and the latter is always treated as a filename. If a command-line option that begins with '+' isn't followed by another option, it's always treated as a filename. Examples:</p>
|
||||
<p>To open '+filename.txt' starting on line 1: <b>nano +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 10: <b>nano +10 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 1, column 20: <b>nano +,20 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 10, column 20: <b>nano +10,20 +filename.txt</b><br>
|
||||
To open '+filename.txt' starting on line 1 and 'filename.txt' starting on line 40 (if nano has been compiled with multibuffer support): <b>nano +1 +filename.txt +40 filename.txt</b></p></blockquote>
|
||||
<h2><a name="4.2"></a>4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</h2>
|
||||
<h3><a name="4.2"></a>4.2. Ack! My Backspace/Delete/Enter/Meta/double bucky key doesn't seem to work! What can I do?</h3>
|
||||
<blockquote><p>Try setting your $TERM variable to 'vt100'. nano doesn't yet support every term entry under the sun.</p>
|
||||
<p>Bourne shell users (bash and sh): <b>export TERM=vt100</b><br>
|
||||
C Shell users (tcsh and csh): <b>setenv TERM vt100</b></p></blockquote>
|
||||
<h2><a name="4.3"></a>4.3. Ack! My numeric keypad's keys don't work properly when NumLock is off! What can I do?</h2>
|
||||
<h3><a name="4.3"></a>4.3. Ack! My numeric keypad's keys don't work properly when NumLock is off! What can I do?</h3>
|
||||
<blockquote><p>You can use the <b>-K</b> or <b>--rebindkeypad</b> option on the command line, or add the line <b>set rebindkeypad</b> to your .nanorc. However, nano's mouse support won't work properly if you do any of these things.</p></blockquote>
|
||||
<h2><a name="4.4"></a>4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</h2>
|
||||
<h3><a name="4.4"></a>4.4. Ack! When I hold down a Meta key combination for a while, the character of the held key gets inserted now and then. What gives?</h3>
|
||||
<blockquote><p>This was a bug in how nano handled consecutive escape sequences. It should be fixed since version 2.6.0.</p></blockquote>
|
||||
<h2><a name="4.5"></a>4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</h2>
|
||||
<h3><a name="4.5"></a>4.5. How do I type the F13-F16 keys listed in the help viewer? My keyboard only has F1-F12!</h3>
|
||||
<blockquote><p>It depends on the terminal type you're using. On some terminals, such as the FreeBSD console, xterm, konsole, and gnome-terminal, Shift-F1 to Shift-F4 will generate F13 to F16. On other terminals, such as the Linux console, rxvt, and Eterm, Shift-F3 to Shift-F6 will generate F13 to F16.</p></blockquote>
|
||||
<h2><a name="4.6"></a>4.6. nano crashes when I type <insert keystroke here>!</h2>
|
||||
<h3><a name="4.6"></a>4.6. nano crashes when I type <insert keystrokes here>!</h3>
|
||||
<blockquote><p>If you aren't trying some bizarre keystroke combination with some bizarre $TERM entry, chances are you have found a bug. You are welcome to submit it to the <a href="mailto:nano-devel@gnu.org">nano-devel</a> list or in the <a href="https://savannah.gnu.org/bugs/?group=nano">bug tracker</a> on Savannah.</p></blockquote>
|
||||
<h2><a name="4.7"></a>4.7. nano crashes when I resize my window. How can I fix that?</h2>
|
||||
<h3><a name="4.7"></a>4.7. nano crashes when I resize my window. How can I fix that?</h3>
|
||||
<blockquote><p>Older versions of nano had this problem. Please upgrade to version 2.7.0 or newer.</p></blockquote>
|
||||
<h2><a name="4.8a"></a>4.8a. When I paste text into a document, each line gets indented further than the last. Why does nano do this, and how can I avoid it?</h2>
|
||||
<blockquote><p>You have the autoindent feature turned on. Hit Meta-I to turn it off, paste your text, and then hit Meta-I again to turn it back on.</p></blockquote>
|
||||
<h2><a name="4.8b"></a>4.8b. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</h2>
|
||||
<h3><a name="4.8a"></a>4.8a. With what keystroke can I paste text from the clipboard into nano?</h3>
|
||||
<blockquote><p>In most desktop environments <b>Shift+Insert</b> will paste the contents of the clipboard.</p></blockquote>
|
||||
<h3><a name="4.8b"></a>4.8b. When I paste text into a document, each line gets indented further than the last. Why? And how can I stop this?</h3>
|
||||
<blockquote><p>You have the <i>autoindent</i> feature turned on. Hit <b>Meta-I</b> to turn it off, paste your text, and then hit <b>Meta-I</b> again to turn it back on.</p></blockquote>
|
||||
<h3><a name="4.8c"></a>4.8c. When I paste from Windows into a remote nano, nano rewraps the lines. What gives?</h3>
|
||||
<blockquote><p>When pasting from Windows, in some situations linefeeds are sent instead of carriage returns (Enters). And linefeeds are <b>^J</b>s, which make nano justify (rewrap) the current paragraph. To prevent these linefeeds from causing these unwanted justifications, add this line to your .nanorc on the remote Linux box: <b>unbind ^J main</b> or <b>bind ^J enter main</b>, depending on whether the paste contains CR + LF or only LF.</p></blockquote>
|
||||
<h2><a name="4.9"></a>4.9. I've compiled nano with color support, but I don't see any color when I run it!</h2>
|
||||
<h3><a name="4.9"></a>4.9. I've compiled nano with color support, but I don't see any color when I run it!</h3>
|
||||
<blockquote><p>If you want nano to actually use color, you have to specify the color configurations you want it to use in your .nanorc. Several example configurations are in the <b>syntax/</b> subdirectory of the nano source, which are normally installed to <b>/usr/local/share/nano/</b>. To enable all of them, uncomment the line <b># include "/usr/local/share/nano/*.nanorc"</b> in your nanorc. See also section <a href="#3.9a">3.9a</a>.</p></blockquote>
|
||||
<h2><a name="4.10"></a>4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</h2>
|
||||
<h3><a name="4.10"></a>4.10. How do I make nano my default editor (in Pine, mutt, etc.)?</h3>
|
||||
<blockquote><p>You need to make nano your $EDITOR. If you want this to be saved, you should put a line like this in your <b>.bashrc</b> if you use bash (or <b>.zshrc</b> if you believe in zsh):</p>
|
||||
<p><b>export EDITOR=/usr/local/bin/nano</b></p>
|
||||
<p>or, if you use tcsh, put this in your <b>.cshrc</b> file:</p>
|
||||
@@ -212,53 +222,53 @@
|
||||
<p>If you're a mutt user, you should see an effect immediately the next time you log in. No further configuration is needed. However, if you want to let people know you use nano to compose your email messages, you can put a line like this in your <b>.muttrc</b>:</p>
|
||||
<p><b>my_hdr X-Composer: nano x.y.z</b></p>
|
||||
<p>Again, replace x.y.z with the version of nano you use.</p></blockquote>
|
||||
<h2><a name="4.11"></a>4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and nano's mouse support is turned on?</h2>
|
||||
<h3><a name="4.11"></a>4.11. How do I select text for or paste text from the clipboard in an X terminal when I'm running nano in one and nano's mouse support is turned on?</h3>
|
||||
<blockquote><p>Try holding down the Shift key and selecting or pasting the text as you normally would.</p></blockquote>
|
||||
<h2><a name="4.12"></a>4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</h2>
|
||||
<h3><a name="4.12"></a>4.12. On startup I get a message that says "Detected a legacy nano history file". Now older nano versions can't find my search history!</h3>
|
||||
<blockquote><p>In nano 2.3.0, cursor-position history was introduced, and both history files now reside in a .nano subdirectory in your home directory. A newer nano will move an existing search-history file to this new location so it can continue to be used. This means that if you then try and use an earlier version of nano, it will be unable to see your current search history. To fix this, run the following command:</p>
|
||||
<p><b>ln -sf ~/.nano/search_history ~/.nano_history</b></p>
|
||||
<p>The "migration service" (moving the search-history file to its new location) will be deleted from nano in early 2018.</p></blockquote>
|
||||
<p>The "migration service" (moving the search-history file to its new location) has been deleted from nano in late 2017, since version 2.9.0. The search-history and position-history files will now be looked for first in ~/.nano/ and, when not found there, then in ~/.local/share/nano/.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="5"></a>5. Internationalization</h1>
|
||||
<h2><a name="5.1"></a>5.1. There's no translation for my language!</h2>
|
||||
<h3><a name="5.1"></a>5.1. There's no translation for my language!</h3>
|
||||
<blockquote><p>In June 2001, GNU nano entered the <a href="http://translationproject.org/html/welcome.html">Translation Project</a> and since then, translations should be managed from there.</p>
|
||||
<p>If there isn't a translation for your language, you could ask <a href="http://translationproject.org/team/">your language team</a> to translate nano, or better still, join that team and do it yourself. Joining a team is easy. You just need to ask the team leader to add you, and then send a <a href="http://translationproject.org/disclaim.txt">translation disclaimer to the FSF</a> (this is necessary as nano is an official GNU package, but it does <b>not</b> mean that you transfer the rights of your work to the FSF, it's just so the FSF can legally manage them).</p>
|
||||
<p>In any case, translating nano is very easy. Just grab the latest <b>nano.pot</b> file listed on <a href="http://translationproject.org/domain/nano.html">nano's page</a> at the TP, and translate each <b>msgid</b> line into your native language on the <b>msgstr</b> line. When you're done, you should send it to the TP's central po repository.</p></blockquote>
|
||||
<h2><a name="5.2"></a>5.2. I don't like the translation for <x> in my language. How can I fix it?</h2>
|
||||
<blockquote><p>The best way would probably be to send an e-mail to the team's mailing listed mentione in the <code>Language-Team:</code> field in the <b><your_language>.po</b> file with your suggested corrections, and then they can make the changes reach the nano-devel list.</p></blockquote>
|
||||
<h2><a name="5.3"></a>5.3. What is the status of Unicode support?</h2>
|
||||
<blockquote><p>Since versions 1.3.12, Unicode should be usable. With your terminal, locale (LC_ALL and similar environment variables), and encoding configured to properly support UTF-8, you should be able to enter and save Unicode text.</p></blockquote>
|
||||
<p>In any case, translating nano is easy. Just grab the latest <b>nano.pot</b> file listed on <a href="http://translationproject.org/domain/nano.html">nano's page</a> at the TP, and translate each <b>msgid</b> line into your native language on the <b>msgstr</b> line. When you're done, you should send it to the TP's central PO-file repository.</p></blockquote>
|
||||
<h3><a name="5.2"></a>5.2. I don't like the translation for <x> in my language. How can I fix it?</h3>
|
||||
<blockquote><p>The best way is to send an e-mail with your suggested corrections to the team's mailing list. The address is mentioned in the <code>Language-Team:</code> field in the relevant PO file. The team leader or the assigned translator can then make the changes reach the nano-devel list.</p></blockquote>
|
||||
<h3><a name="5.3"></a>5.3. What is the status of Unicode support?</h3>
|
||||
<blockquote><p>Unicode should be fully usable nowadays. When the encoding of your terminal is set to UTF-8, and your locale (mainly the LANG environment variable) is UTF-8 too, then you should be able to read, enter and save Unicode text.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="6"></a>6. Advocacy and Licensing</h1>
|
||||
<h2><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h2>
|
||||
<h3><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h3>
|
||||
<blockquote><p>There are many reasons to use nano instead of Pico. A more complete list can be found at the <a href="https://nano-editor.org/">nano homepage</a>.</p></blockquote>
|
||||
<h2><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h2>
|
||||
<h3><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h3>
|
||||
<blockquote><p>Again, check out the <a href="https://nano-editor.org/">nano homepage</a> for a good summary of reasons. It really is a matter of personal preference as to which editor you should use. If you're the type of person who likes using the original version of a program, then Pico is the editor for you. If you don't mind sacrificing mailer integration with Pine, and are looking for a few more features, as well as a 'better' license in terms of adding your own changes, nano is the way to go.</p>
|
||||
<p>Note that the last of these no longer applies to the new version of Pine, <a href="http://www.washington.edu/alpine/">Alpine</a>, which is under the Apache License, version 2.0.</p></blockquote>
|
||||
<h2><a name="6.3"></a>6.3. What is so bad about the older Pine license?</h2>
|
||||
<h3><a name="6.3"></a>6.3. What is so bad about the older Pine license?</h3>
|
||||
<blockquote><p>The U of W license for older versions of Pine and Pico is not considered truly Free Software according to both the Free Software Foundation and the <a href="http://www.debian.org/social_contract#guidelines">Debian Free Software Guidelines</a>. The main problem regards the limitations on distributing derived works: according to UW, you can distribute their software, and you can modify it, but you can not do both, i.e. distribute modified binaries.</p></blockquote>
|
||||
<h2><a name="6.4"></a>6.4. Okay, well, what mail program should I use then?</h2>
|
||||
<h3><a name="6.4"></a>6.4. Okay, well, what mail program should I use then?</h3>
|
||||
<blockquote><p>If you are looking to use a Free Software program similar to Pine, and Emacs is not your thing, you should definitely take a look at <a href="http://www.mutt.org/">mutt</a>. It is a full-screen, console based mail program that actually has a lot more flexibility than Pine, but has a keymap included in the distribution that allows you to use the same keystrokes as Pine would to send and receive mail. It's also under the GNU General Public License, version 2.0.</p>
|
||||
<p>Of course, due to the license change you can now use the <a href="http://www.washington.edu/alpine/">Alpine distribution</a> of PINE as it is now considered Free Software, but you would be sacrificing many of nano's features to do so.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
<h1><a name="7"></a>7. Miscellaneous</h1>
|
||||
<h2><a name="7.1"></a>7.1. Where can I ask questions or send suggestions?</h2>
|
||||
<h3><a name="7.1"></a>7.1. Where can I ask questions or send suggestions?</h3>
|
||||
<blockquote><p>There are three mailing lists for nano hosted at <a href="http://savannah.gnu.org/">Savannah</a>: info-nano, help-nano and nano-devel. info-nano is a very low traffic list where new versions of nano are announced (surprise!). help-nano is for getting help with the editor without needing to hear all of the development issues surrounding it. nano-devel is a normally low, sometimes high traffic list for discussing the present and future development of nano. Here are links to where you can sign up for a given list:</p>
|
||||
<p>info-nano - <a href="http://mail.gnu.org/mailman/listinfo/info-nano/">http://mail.gnu.org/mailman/listinfo/info-nano/</a><br>
|
||||
help-nano - <a href="http://mail.gnu.org/mailman/listinfo/help-nano/">http://mail.gnu.org/mailman/listinfo/help-nano/</a><br>
|
||||
nano-devel - <a href="http://mail.gnu.org/mailman/listinfo/nano-devel/">http://mail.gnu.org/mailman/listinfo/nano-devel/</a></p></blockquote>
|
||||
<h2><a name="7.2"></a>7.3. How do I submit a bug report or patch?</h2>
|
||||
<h3><a name="7.2"></a>7.3. How do I submit a bug report or patch?</h3>
|
||||
<blockquote>
|
||||
<p>The best way to submit bugs is through the <a href="https://savannah.gnu.org/bugs/?group=nano">Savannah bug tracker</a>, as you can check whether the bug you are reporting has already been submitted, and it makes it easier for the maintainers to keep track of them.
|
||||
<p>You can submit patches for nano via <a href="https://savannah.gnu.org/patch/?group=nano">Savannah's patch manager</a>.</p></blockquote>
|
||||
<h2><a name="7.3"></a>7.3. I want to send the development team a big load of cash (or just a thank you).</h2>
|
||||
<h3><a name="7.3"></a>7.3. I want to send the development team a big load of cash (or just a thank you).</h3>
|
||||
<blockquote><p>That's fine. Send it <a href="mailto:nano-devel@gnu.org">our way</a>! Better yet, fix a <a href="https://savannah.gnu.org/bugs/?group=nano">bug</a> in the program or implement a <a href="https://nano-editor.org/dist/latest/TODO">cool feature</a> and send us that instead (though cash is fine too).</p></blockquote>
|
||||
<h2><a name="7.4"></a>7.4. How do I join the development team?</h2>
|
||||
<h3><a name="7.4"></a>7.4. How do I join the development team?</h3>
|
||||
<blockquote><p>The easiest way is to consistently send in good patches that add some needed functionality, fix a bug or two, and/or make the program more optimized/efficient. Then ask nicely and you will probably be added to the Savannah development list and be given write access after a while. There is a lot of responsibility that goes along with being a team member, so don't think it's just something to add to your resume.</p></blockquote>
|
||||
<h2><a name="7.5"></a>7.5. Can I have write access to the git tree?</h2>
|
||||
<h3><a name="7.5"></a>7.5. Can I have write access to the git tree?</h3>
|
||||
<blockquote><p>Re-read section <a href="#7.4">7.4</a> and you should know the answer.</p></blockquote>
|
||||
<hr width="100%">
|
||||
|
||||
|
||||
17
doc/nano.1
17
doc/nano.1
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <http://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 2.9.2" "January 2018"
|
||||
.TH NANO 1 "version 2.9.6" "April 2018"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, an enhanced free Pico clone
|
||||
@@ -54,9 +54,9 @@ highlighted), and then use \fB^K\fR to cut it, or \fBM\-6\fR to copy it to the
|
||||
cutbuffer. One can also save the marked text to a file with \fB^O\fR, or
|
||||
spell check it with \fB^T\fR.
|
||||
.PP
|
||||
Since nano-2.7.0, text can also be selected by holding Shift and moving the
|
||||
cursor with the arrow keys. Holding down the Alt key too will increase the
|
||||
stride.
|
||||
On some terminals, text can be selected also by holding down Shift while
|
||||
using the arrow keys. Holding down the Alt key too will increase the stride.
|
||||
Any cursor movement without Shift being held will cancel such a selection.
|
||||
.PP
|
||||
The two lines at the bottom of the screen show some important commands;
|
||||
the built-in help (\fB^G\fR) lists all the available ones.
|
||||
@@ -108,6 +108,10 @@ won't work properly with this option enabled.
|
||||
.BR \-L ", " \-\-nonewlines
|
||||
Don't add newlines to the ends of files.
|
||||
.TP
|
||||
.BR \-M ", " \-\-trimblanks
|
||||
Snip trailing whitespace from the wrapped line when automatic
|
||||
hard-wrapping occurs or when text is justified.
|
||||
.TP
|
||||
.BR \-N ", " \-\-noconvert
|
||||
Disable automatic conversion of files from DOS/Mac format.
|
||||
.TP
|
||||
@@ -117,7 +121,6 @@ Use the blank line below the title bar as extra editing space.
|
||||
.BR \-P ", " \-\-positionlog
|
||||
For the 200 most recent files, log the last position of the cursor,
|
||||
and place it at that position again upon reopening such a file.
|
||||
(The old form of this option, \fB\-\-poslog\fR, is deprecated.)
|
||||
.TP
|
||||
.BR "\-Q ""\fIcharacters\fB""" ", " "\-\-quotestr=""" \fIcharacters """
|
||||
Set the quoting string for justifying. The default is
|
||||
@@ -300,8 +303,8 @@ cannot be undone any more. The workaround is, of course, to exit without
|
||||
saving.
|
||||
.sp
|
||||
The recording and playback of keyboard macros works correctly only on a
|
||||
terminal emulator, not on a Linux console (VT), because the latter is a
|
||||
deficient terminal. And it works only with recent versions of ncurses.
|
||||
terminal emulator, not on a Linux console (VT), because the latter does
|
||||
not by default distinguish modified from unmodified arrow keys.
|
||||
.sp
|
||||
Please report any other bugs that you encounter via:
|
||||
.br
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 2.9.2
|
||||
@set UPDATED January 2018
|
||||
@set VERSION 2.9.6
|
||||
@set UPDATED April 2018
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 2.9.2
|
||||
@subtitle version 2.9.6
|
||||
|
||||
@author Chris Allegretta
|
||||
@page
|
||||
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
|
||||
@node Top
|
||||
@top
|
||||
|
||||
This manual documents the GNU @command{nano} editor, version 2.9.2.
|
||||
This manual documents the GNU @command{nano} editor, version 2.9.6.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@@ -200,6 +200,11 @@ won't work properly with this option enabled.
|
||||
@itemx --nonewlines
|
||||
Don't add newlines to the ends of files.
|
||||
|
||||
@item -M
|
||||
@itemx --trimblanks
|
||||
Snip trailing whitespace from the wrapped line when automatic
|
||||
hard-wrapping occurs or when text is justified.
|
||||
|
||||
@item -N
|
||||
@itemx --noconvert
|
||||
Disable automatic conversion of files from DOS/Mac format.
|
||||
@@ -212,7 +217,6 @@ Use the blank line below the title bar as extra editing space.
|
||||
@itemx --positionlog
|
||||
For the 200 most recent files, log the last position of the cursor,
|
||||
and place it at that position again upon reopening such a file.
|
||||
(The old form of this option, @option{--poslog}, is deprecated.)
|
||||
|
||||
@item -Q "@var{characters}"
|
||||
@itemx --quotestr="@var{characters}"
|
||||
@@ -493,12 +497,15 @@ the 'Copy Text' command (default key binding: @kbd{M-6}).
|
||||
|
||||
Text can be selected by first 'setting the Mark' (default key bindings:
|
||||
@kbd{^6} and @kbd{M-A}) and then moving the cursor to the other end of the portion
|
||||
to be selected. The selected portion of text will be highlighted in
|
||||
reverse video (or in bold if you set the boldtext option).
|
||||
to be selected. The selected portion of text will be highlighted.
|
||||
This selection can now be cut or copied in its entirety with a single
|
||||
@kbd{^K} or @kbd{M-6}. Or the selection can be used to limit the scope of
|
||||
a search-and-replace (@kbd{^\}) or spell-checking session (@kbd{^T}).
|
||||
|
||||
On some terminals, it is also possible to select text by holding down
|
||||
@kbd{Shift} together with the cursor keys. Such a selection is cancelled
|
||||
upon any cursor movement where @kbd{Shift} isn't held.
|
||||
|
||||
Cutting or copying selected text will toggle the mark off automatically.
|
||||
If necessary, it can be toggled off manually with another @kbd{^6} or @kbd{M-A}.
|
||||
|
||||
@@ -562,8 +569,8 @@ cannot be undone any more. The workaround is, of course, to exit without
|
||||
saving.
|
||||
|
||||
The recording and playback of keyboard macros works correctly only on a
|
||||
terminal emulator, not on a Linux console (VT), because the latter is a
|
||||
deficient terminal. And it works only with recent versions of ncurses.
|
||||
terminal emulator, not on a Linux console (VT), because the latter does
|
||||
not by default distinguish modified from unmodified arrow keys.
|
||||
|
||||
@node Built-in Help
|
||||
@chapter Built-in Help
|
||||
@@ -726,13 +733,16 @@ Do case-sensitive searches by default.
|
||||
|
||||
@item set constantshow
|
||||
Constantly display the cursor position on the status bar.
|
||||
(The old form of this option, @code{set const}, is deprecated.)
|
||||
Note that this overrides @option{quickblank}.
|
||||
|
||||
@item set cutfromcursor
|
||||
Use cut-from-cursor-to-end-of-line by default, instead of cutting the whole line.
|
||||
(The old form of this option, @code{set cut}, is deprecated.)
|
||||
|
||||
@item set errorcolor @var{fgcolor},@var{bgcolor}
|
||||
Use this color combination for the status bar when an error message is displayed.
|
||||
@xref{@code{set functioncolor}} for valid color names.
|
||||
|
||||
@item set fill @var{number}
|
||||
Hard-wrap lines at column number @var{number}. If @var{number} is 0 or less,
|
||||
the maximum line length will be the screen width less @var{number} columns.
|
||||
@@ -745,7 +755,8 @@ Use this color combination for the concise function descriptions
|
||||
in the two help lines at the bottom of the screen.
|
||||
Valid names for foreground and background color are:
|
||||
@code{white}, @code{black}, @code{blue}, @code{green},
|
||||
@code{red}, @code{cyan}, @code{yellow}, and @code{magenta}.
|
||||
@code{red}, @code{cyan}, @code{yellow}, @code{magenta}, and @code{normal}
|
||||
--- where @code{normal} means the default foreground or background color.
|
||||
The name of the foreground color may be prefixed with @code{bright}.
|
||||
And either @var{fgcolor} or ,@var{bgcolor} may be left out.
|
||||
|
||||
@@ -810,7 +821,6 @@ directory feature is turned off.
|
||||
@item set positionlog
|
||||
Save the cursor position of files between editing sessions.
|
||||
The cursor position is remembered for the 200 most-recently edited files.
|
||||
(The old form of this option, @code{set poslog}, is deprecated.)
|
||||
|
||||
@item set preserve
|
||||
Preserve the XON and XOFF keys (@kbd{^Q} and @kbd{^S}).
|
||||
@@ -1032,7 +1042,7 @@ in one of the system-installed files (which normally are not writable).
|
||||
@node Rebinding Keys
|
||||
@section Rebinding Keys
|
||||
|
||||
Key bindings can be changed via the following two commands in a
|
||||
Key bindings can be changed via the following three commands in a
|
||||
nanorc file:
|
||||
|
||||
@table @code
|
||||
@@ -1041,6 +1051,13 @@ nanorc file:
|
||||
Rebinds @code{key} to @code{function} in the context of @code{menu}
|
||||
(or in all menus where the function exists by using @code{all}).
|
||||
|
||||
@item bind key "string" menu
|
||||
Makes @code{key} produce @code{string} in the context of @code{menu}
|
||||
(or in all menus where the key exists when @code{all} is used).
|
||||
The @code{string} can consist of text or commands or a mix of them.
|
||||
(To enter a command into the @code{string}, precede its keystroke
|
||||
with @kbd{M-V}.)
|
||||
|
||||
@item unbind key menu
|
||||
Unbinds @code{key} from @code{menu}
|
||||
(or from all menus where it exists by using @code{all}).
|
||||
@@ -1097,7 +1114,6 @@ Starts a backward search for text in the current buffer.
|
||||
|
||||
@item searchagain
|
||||
Repeats the last search command without prompting.
|
||||
(The form @code{research} is deprecated.)
|
||||
|
||||
@item findprevious
|
||||
As @code{searchagain}, but always in the backward direction.
|
||||
@@ -1132,7 +1148,6 @@ Cuts all text from the cursor position till the end of the buffer.
|
||||
|
||||
@item curpos
|
||||
Shows the current cursor position: the line, column, and character positions.
|
||||
(The form @code{cursorpos} is deprecated.)
|
||||
|
||||
@item wordcount
|
||||
Counts the number of words, lines and characters in the current buffer.
|
||||
@@ -1174,10 +1189,12 @@ Goes one line up (in the editor or browser).
|
||||
Goes one line down (in the editor or browser).
|
||||
|
||||
@item scrollup
|
||||
Scrolls up one line of text from the current position.
|
||||
Scrolls the viewport up one row (meaning that the text slides down)
|
||||
while keeping the cursor in the same text position, if possible.
|
||||
|
||||
@item scrolldown
|
||||
Scrolls down one line of text from the current position.
|
||||
Scrolls the viewport down one row (meaning that the text slides up)
|
||||
while keeping the cursor in the same text position, if possible.
|
||||
|
||||
@item prevword
|
||||
Moves the cursor to the beginning of the previous word.
|
||||
@@ -1220,9 +1237,6 @@ Goes to the last line of the file.
|
||||
Goes to a specific line (and column if specified). Negative numbers count
|
||||
from the end of the file (and end of the line).
|
||||
|
||||
@item gototext
|
||||
Switches from targeting a line number to searching for text.
|
||||
|
||||
@item findbracket
|
||||
Moves the cursor to the bracket (brace, parenthesis, etc.) that matches
|
||||
(pairs) with the one under the cursor.
|
||||
@@ -1273,7 +1287,6 @@ Toggles case sensitivity in searching (search/replace menus only).
|
||||
|
||||
@item regexp
|
||||
Toggles whether searching/replacing is based on literal strings or regular expressions.
|
||||
(The form @code{regex} is deprecated.)
|
||||
|
||||
@item backwards
|
||||
Toggles whether searching/replacing goes forward or backward.
|
||||
@@ -1286,7 +1299,10 @@ Shows the next history entry in the prompt menus (e.g.@: search).
|
||||
|
||||
@item flipreplace
|
||||
Toggles between searching for something and replacing something.
|
||||
(The form @code{dontreplace} is deprecated.)
|
||||
|
||||
@item flipgoto
|
||||
Toggles between searching for text and targeting a line number.
|
||||
(The form @code{gototext} is deprecated.)
|
||||
|
||||
@item flipexecute
|
||||
Toggles between inserting a file and executing a command.
|
||||
@@ -1294,7 +1310,6 @@ Toggles between inserting a file and executing a command.
|
||||
@item flipnewbuffer
|
||||
Toggles between inserting into the current buffer and into a new
|
||||
empty buffer.
|
||||
(The form @code{newbuffer} is deprecated.)
|
||||
|
||||
@item dosformat
|
||||
When writing a file, switches to writing a DOS format (CR/LF).
|
||||
@@ -1400,7 +1415,6 @@ The 'search to replace' menu.
|
||||
|
||||
@item replacewith
|
||||
The 'replace with' menu, which comes up after 'search to replace'.
|
||||
(The form @code{replace2} is deprecated.)
|
||||
|
||||
@item gotoline
|
||||
The 'goto line (and column)' menu.
|
||||
|
||||
43
doc/nanorc.5
43
doc/nanorc.5
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <http://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 2.9.2" "January 2018"
|
||||
.TH NANORC 5 "version 2.9.6" "April 2018"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
@@ -96,13 +96,16 @@ Do case-sensitive searches by default.
|
||||
.TP
|
||||
.B set constantshow
|
||||
Constantly display the cursor position in the status bar.
|
||||
(The old form of this option, '\fBset const\fR', is deprecated.)
|
||||
This overrides the option \fBquickblank\fR.
|
||||
.TP
|
||||
.B set cutfromcursor
|
||||
Use cut-from-cursor-to-end-of-line by default, instead of cutting the whole line.
|
||||
(The old form of this option, '\fBset cut\fR', is deprecated.)
|
||||
.TP
|
||||
.B set errorcolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Use this color combination for the status bar when an error message is displayed.
|
||||
See \fBset titlecolor\fR for valid color names.
|
||||
.TP
|
||||
.B set fill \fInumber\fR
|
||||
Hard-wrap lines at column number \fInumber\fR. If \fInumber\fR is 0 or less,
|
||||
the maximum line length will be the screen width less \fInumber\fP columns.
|
||||
@@ -178,7 +181,6 @@ directory feature is turned off.
|
||||
.B set positionlog
|
||||
Save the cursor position of files between editing sessions.
|
||||
The cursor position is remembered for the 200 most-recently edited files.
|
||||
(The old form of this option, '\fBset poslog\fR', is deprecated.)
|
||||
.TP
|
||||
.B set preserve
|
||||
Preserve the XON and XOFF keys (^Q and ^S).
|
||||
@@ -262,7 +264,9 @@ Save automatically on exit, don't prompt.
|
||||
.B set titlecolor \fIfgcolor\fR,\fIbgcolor\fR
|
||||
Specify the color combination to use for the title bar.
|
||||
Valid names for the foreground and background colors are:
|
||||
.BR white ", " black ", " blue ", " green ", " red ", " cyan ", " yellow ", and " magenta .
|
||||
.BR white ", " black ", " blue ", " green ", " red ", "
|
||||
.BR cyan ", " yellow ", " magenta ", and " normal
|
||||
-- where \fBnormal\fR means the default foreground or background color.
|
||||
The name of the foreground color may be prefixed with \fBbright\fR.
|
||||
And either "\fIfgcolor\fR" or ",\fIbgcolor\fR" may be left out.
|
||||
.TP
|
||||
@@ -393,16 +397,26 @@ slightly improve a syntax defined in one of the system-installed
|
||||
files (which normally are not writable).
|
||||
|
||||
.SH REBINDING KEYS
|
||||
Key bindings can be changed via the following two commands:
|
||||
Key bindings can be changed via the following three commands:
|
||||
.RS 3
|
||||
.TP
|
||||
.BI bind " key function menu"
|
||||
Rebinds the key \fIkey\fP to a new function named \fIfunction\fP in the
|
||||
context of menu \fImenu\fP (or in all menus where the function exists
|
||||
by using \fBall\fP).
|
||||
.TP
|
||||
.BI bind " key " """" string """" " menu"
|
||||
Makes the given \fIkey\fR produce the given \fIstring\fR in the given
|
||||
\fImenu\fR (or in all menus where the key exists when \fBall\fR is used).
|
||||
The \fIstring\fR can consist of text or commands or a mix of them.
|
||||
(To enter a command into the \fIstring\fR, precede its keystroke
|
||||
with \fBM-V\fR.)
|
||||
|
||||
.TP
|
||||
.BI unbind " key menu"
|
||||
Unbinds the key \fIkey\fP from the menu named \fImenu\fP (or from all
|
||||
menus where it exists by using \fBall\fP).
|
||||
.RE
|
||||
|
||||
.TP
|
||||
The format of \fIkey\fP should be one of:
|
||||
@@ -453,7 +467,6 @@ Starts a backward search for text in the current buffer.
|
||||
.TP
|
||||
.B searchagain
|
||||
Repeats the last search command without prompting.
|
||||
(The form 'research' is deprecated.)
|
||||
.TP
|
||||
.B findprevious
|
||||
As \fBsearchagain\fR, but always in the backward direction.
|
||||
@@ -488,7 +501,6 @@ Cuts all text from the cursor position till the end of the buffer.
|
||||
.TP
|
||||
.B curpos
|
||||
Shows the current cursor position: the line, column, and character positions.
|
||||
(The form 'cursorpos' is deprecated.)
|
||||
.TP
|
||||
.B wordcount
|
||||
Counts the number of words, lines and characters in the current buffer.
|
||||
@@ -533,10 +545,12 @@ Goes one line up (in the editor or browser).
|
||||
Goes one line down (in the editor or browser).
|
||||
.TP
|
||||
.B scrollup
|
||||
Scrolls up one line of text from the current position.
|
||||
Scrolls the viewport up one row (meaning that the text slides down)
|
||||
while keeping the cursor in the same text position, if possible.
|
||||
.TP
|
||||
.B scrolldown
|
||||
Scrolls down one line of text from the current position.
|
||||
Scrolls the viewport down one row (meaning that the text slides up)
|
||||
while keeping the cursor in the same text position, if possible.
|
||||
.TP
|
||||
.B prevword
|
||||
Moves the cursor to the beginning of the previous word.
|
||||
@@ -579,9 +593,6 @@ Goes to the last line of the file.
|
||||
Goes to a specific line (and column if specified). Negative numbers count
|
||||
from the end of the file (and end of the line).
|
||||
.TP
|
||||
.B gototext
|
||||
Switches from targeting a line number to searching for text.
|
||||
.TP
|
||||
.B findbracket
|
||||
Moves the cursor to the bracket (brace, parenthesis, etc.) that matches
|
||||
(pairs) with the one under the cursor.
|
||||
@@ -632,7 +643,6 @@ Toggles case sensitivity in searching (search/replace menus only).
|
||||
.TP
|
||||
.B regexp
|
||||
Toggles whether searching/replacing is based on literal strings or regular expressions.
|
||||
(The form 'regex' is deprecated.)
|
||||
.TP
|
||||
.B backwards
|
||||
Toggles whether searching/replacing goes forward or backward.
|
||||
@@ -645,7 +655,10 @@ Shows the next history entry in the prompt menus (e.g. search).
|
||||
.TP
|
||||
.B flipreplace
|
||||
Toggles between searching for something and replacing something.
|
||||
(The form 'dontreplace' is deprecated.)
|
||||
.TP
|
||||
.B flipgoto
|
||||
Toggles between searching for text and targeting a line number.
|
||||
(The form 'gototext' is deprecated.)
|
||||
.TP
|
||||
.B flipexecute
|
||||
Toggles between inserting a file and executing a command.
|
||||
@@ -653,7 +666,6 @@ Toggles between inserting a file and executing a command.
|
||||
.B flipnewbuffer
|
||||
Toggles between inserting into the current buffer and into a new
|
||||
empty buffer.
|
||||
(The form 'newbuffer' is deprecated.)
|
||||
.TP
|
||||
.B dosformat
|
||||
When writing a file, switches to writing a DOS format (CR/LF).
|
||||
@@ -757,7 +769,6 @@ The 'search to replace' menu.
|
||||
.TP
|
||||
.B replacewith
|
||||
The 'replace with' menu, which comes up after 'search to replace'.
|
||||
(The form 'replace2' is deprecated.)
|
||||
.TP
|
||||
.B gotoline
|
||||
The 'goto line (and column)' menu.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <http://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 2.9.2" "January 2018"
|
||||
.TH RNANO 1 "version 2.9.6" "April 2018"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
|
||||
@@ -196,17 +196,19 @@
|
||||
# set wordchars "<_>."
|
||||
|
||||
|
||||
## Paint the interface elements of nano.
|
||||
## These are examples; by default there are no colors.
|
||||
## Paint the interface elements of nano. These are examples;
|
||||
## by default there are no colors, except for errorcolor.
|
||||
# set titlecolor brightwhite,blue
|
||||
# set statuscolor brightwhite,green
|
||||
# set errorcolor brightwhite,red
|
||||
# set selectedcolor brightwhite,magenta
|
||||
# set numbercolor cyan
|
||||
# set keycolor cyan
|
||||
# set functioncolor green
|
||||
## In root's .nanorc you might want to use:
|
||||
# set titlecolor brightwhite,red
|
||||
# set statuscolor brightwhite,red
|
||||
# set titlecolor brightwhite,magenta
|
||||
# set statuscolor brightwhite,magenta
|
||||
# set errorcolor brightwhite,red
|
||||
# set selectedcolor brightwhite,cyan
|
||||
# set numbercolor magenta
|
||||
# set keycolor brightmagenta
|
||||
|
||||
@@ -10,7 +10,7 @@ Summary : a user-friendly editor, a Pico clone with enhancements
|
||||
License : GPLv3+
|
||||
Group : Applications/Editors
|
||||
URL : https://nano-editor.org/
|
||||
Source : https://nano-editor.org/dist/v2.6/%{name}-%{version}.tar.gz
|
||||
Source : https://nano-editor.org/dist/latest/%{name}-%{version}.tar.gz
|
||||
|
||||
BuildRoot : %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires : autoconf, automake, gettext-devel, ncurses-devel, texinfo
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# List of available languages.
|
||||
bg ca cs da de eo es eu fi fr ga gl hr hu id it ja ms nb nl nn pl pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
|
||||
bg ca cs da de eo es eu fi fr ga gl hr hu id it ja ms nb nl nn pl pt pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
|
||||
|
||||
1134
po/nano.pot
1134
po/nano.pot
File diff suppressed because it is too large
Load Diff
1210
po/pt_BR.po
1210
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1831
po/zh_CN.po
1831
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1185
po/zh_TW.po
1185
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* browser.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2016 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -32,9 +32,9 @@ static char **filelist = NULL;
|
||||
/* The list of files to display in the file browser. */
|
||||
static size_t filelist_len = 0;
|
||||
/* The number of files in the list. */
|
||||
static int width = 0;
|
||||
static size_t width = 0;
|
||||
/* The number of files that we can display per screen row. */
|
||||
static int longest = 0;
|
||||
static size_t longest = 0;
|
||||
/* The number of columns in the longest filename in the list. */
|
||||
static size_t selected = 0;
|
||||
/* The currently selected filename in the list; zero-based. */
|
||||
@@ -121,7 +121,7 @@ char *do_browser(char *path)
|
||||
int mouse_x, mouse_y;
|
||||
|
||||
/* We can click on the edit window to select a filename. */
|
||||
if (get_mouseinput(&mouse_x, &mouse_y, TRUE) == 0 &&
|
||||
if (get_mouseinput(&mouse_y, &mouse_x, TRUE) == 0 &&
|
||||
wmouse_trafo(edit, &mouse_y, &mouse_x, FALSE)) {
|
||||
/* longest is the width of each column. There
|
||||
* are two spaces between each column. */
|
||||
@@ -187,10 +187,10 @@ char *do_browser(char *path)
|
||||
selected += width - 1 - (selected % width);
|
||||
if (selected >= filelist_len)
|
||||
selected = filelist_len - 1;
|
||||
} else if (func == do_up_void) {
|
||||
} else if (func == do_up) {
|
||||
if (selected >= width)
|
||||
selected -= width;
|
||||
} else if (func == do_down_void) {
|
||||
} else if (func == do_down) {
|
||||
if (selected + width <= filelist_len - 1)
|
||||
selected += width;
|
||||
} else if (func == do_prev_block) {
|
||||
@@ -258,9 +258,9 @@ char *do_browser(char *path)
|
||||
|
||||
/* In case the specified directory cannot be entered, select it
|
||||
* (if it is in the current list) so it will be highlighted. */
|
||||
for (i = 0; i < filelist_len; i++)
|
||||
if (strcmp(filelist[i], path) == 0)
|
||||
selected = i;
|
||||
for (size_t j = 0; j < filelist_len; j++)
|
||||
if (strcmp(filelist[j], path) == 0)
|
||||
selected = j;
|
||||
|
||||
/* Try opening and reading the specified directory. */
|
||||
goto read_directory_contents;
|
||||
@@ -303,6 +303,10 @@ char *do_browser(char *path)
|
||||
/* Try opening and reading the selected directory. */
|
||||
path = mallocstrcpy(path, filelist[selected]);
|
||||
goto read_directory_contents;
|
||||
#ifdef ENABLE_NANORC
|
||||
} else if (func == (functionptrtype)implant) {
|
||||
implant(first_sc_for(MBROWSER, func)->expansion);
|
||||
#endif
|
||||
} else if (func == do_exit) {
|
||||
/* Exit from the file browser. */
|
||||
break;
|
||||
@@ -357,7 +361,7 @@ char *do_browse_from(const char *inpath)
|
||||
path = free_and_assign(path, strip_last_component(path));
|
||||
|
||||
if (stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
|
||||
char * currentdir = charalloc(PATH_MAX + 1);
|
||||
char *currentdir = charalloc(PATH_MAX + 1);
|
||||
|
||||
free(path);
|
||||
path = getcwd(currentdir, PATH_MAX + 1);
|
||||
@@ -521,7 +525,7 @@ void browser_refresh(void)
|
||||
/* The length of the filename in columns. */
|
||||
size_t infolen;
|
||||
/* The length of the file information in columns. */
|
||||
int infomaxlen = 7;
|
||||
size_t infomaxlen = 7;
|
||||
/* The maximum length of the file information in columns:
|
||||
* normally seven, but will be twelve for "(parent dir)". */
|
||||
bool dots = (COLS >= 15 && namelen >= longest - infomaxlen);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* chars.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
|
||||
44
src/color.c
44
src/color.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* color.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -45,7 +45,6 @@ void set_colorpairs(void)
|
||||
{
|
||||
const syntaxtype *sint;
|
||||
bool using_defaults = FALSE;
|
||||
short foreground, background;
|
||||
size_t i;
|
||||
|
||||
/* Tell ncurses to enable colors. */
|
||||
@@ -58,27 +57,27 @@ void set_colorpairs(void)
|
||||
|
||||
/* Initialize the color pairs for nano's interface elements. */
|
||||
for (i = 0; i < NUMBER_OF_ELEMENTS; i++) {
|
||||
bool bright = FALSE;
|
||||
colortype *combo = color_combo[i];
|
||||
|
||||
if (specified_color_combo[i] != NULL &&
|
||||
parse_color_names(specified_color_combo[i],
|
||||
&foreground, &background, &bright)) {
|
||||
if (foreground == -1 && !using_defaults)
|
||||
foreground = COLOR_WHITE;
|
||||
if (background == -1 && !using_defaults)
|
||||
background = COLOR_BLACK;
|
||||
init_pair(i + 1, foreground, background);
|
||||
if (combo != NULL) {
|
||||
if (combo->fg == USE_THE_DEFAULT && !using_defaults)
|
||||
combo->fg = COLOR_WHITE;
|
||||
if (combo->bg == USE_THE_DEFAULT && !using_defaults)
|
||||
combo->bg = COLOR_BLACK;
|
||||
init_pair(i + 1, combo->fg, combo->bg);
|
||||
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BANDAID |
|
||||
(bright ? A_BOLD : A_NORMAL);
|
||||
(combo->bright ? A_BOLD : A_NORMAL);
|
||||
} else {
|
||||
if (i != FUNCTION_TAG)
|
||||
interface_color_pair[i] = hilite_attribute;
|
||||
else
|
||||
if (i == FUNCTION_TAG)
|
||||
interface_color_pair[i] = A_NORMAL;
|
||||
else if (i == ERROR_MESSAGE) {
|
||||
init_pair(i + 1, COLOR_WHITE, COLOR_RED);
|
||||
interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BOLD | A_BANDAID;
|
||||
} else
|
||||
interface_color_pair[i] = hilite_attribute;
|
||||
}
|
||||
|
||||
free(specified_color_combo[i]);
|
||||
specified_color_combo[i] = NULL;
|
||||
free(color_combo[i]);
|
||||
}
|
||||
|
||||
/* For each syntax, go through its list of colors and assign each
|
||||
@@ -91,8 +90,7 @@ void set_colorpairs(void)
|
||||
const colortype *beforenow = sint->color;
|
||||
|
||||
while (beforenow != ink && (beforenow->fg != ink->fg ||
|
||||
beforenow->bg != ink->bg ||
|
||||
beforenow->bright != ink->bright))
|
||||
beforenow->bg != ink->bg))
|
||||
beforenow = beforenow->next;
|
||||
|
||||
if (beforenow != ink)
|
||||
@@ -127,10 +125,10 @@ void color_init(void)
|
||||
foreground = ink->fg;
|
||||
background = ink->bg;
|
||||
|
||||
if (foreground == -1 && !using_defaults)
|
||||
if (foreground == USE_THE_DEFAULT && !using_defaults)
|
||||
foreground = COLOR_WHITE;
|
||||
|
||||
if (background == -1 && !using_defaults)
|
||||
if (background == USE_THE_DEFAULT && !using_defaults)
|
||||
background = COLOR_BLACK;
|
||||
|
||||
init_pair(ink->pairnum, foreground, background);
|
||||
@@ -293,6 +291,7 @@ void check_the_multis(filestruct *line)
|
||||
const colortype *ink;
|
||||
bool astart, anend;
|
||||
regmatch_t startmatch, endmatch;
|
||||
char *afterstart;
|
||||
|
||||
/* If there is no syntax or no multiline regex, there is nothing to do. */
|
||||
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0)
|
||||
@@ -306,7 +305,8 @@ void check_the_multis(filestruct *line)
|
||||
alloc_multidata_if_needed(line);
|
||||
|
||||
astart = (regexec(ink->start, line->data, 1, &startmatch, 0) == 0);
|
||||
anend = (regexec(ink->end, line->data, 1, &endmatch, 0) == 0);
|
||||
afterstart = line->data + (astart ? startmatch.rm_eo : 0);
|
||||
anend = (regexec(ink->end, afterstart, 1, &endmatch, 0) == 0);
|
||||
|
||||
/* Check whether the multidata still matches the current situation. */
|
||||
if (line->multidata[ink->id] == CNONE ||
|
||||
|
||||
10
src/cut.c
10
src/cut.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* cut.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014 Mark Majeres *
|
||||
* Copyright (C) 2016 Benno Schulenberg *
|
||||
* *
|
||||
@@ -188,10 +188,6 @@ void do_cut_text(bool copy_text, bool cut_till_eof)
|
||||
|
||||
refresh_needed = TRUE;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
check_the_multis(openfile->current);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_filestruct(cutbuffer);
|
||||
#endif
|
||||
@@ -286,8 +282,4 @@ void do_uncut_text(void)
|
||||
|
||||
set_modified();
|
||||
refresh_needed = TRUE;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
check_the_multis(openfile->current);
|
||||
#endif
|
||||
}
|
||||
|
||||
78
src/files.c
78
src/files.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* files.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -66,16 +66,19 @@ void make_new_buffer(void)
|
||||
|
||||
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;
|
||||
} 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;
|
||||
@@ -345,6 +348,9 @@ int do_lockfile(const char *filename)
|
||||
pidstring = charalloc(11);
|
||||
sprintf (pidstring, "%u", (unsigned int)lockpid);
|
||||
|
||||
/* Display newlines in filenames as ^J. */
|
||||
as_an_at = FALSE;
|
||||
|
||||
/* TRANSLATORS: The second %s is the name of the user, the third that of the editor. */
|
||||
question = _("File %s is being edited (by %s with %s, PID %s); continue?");
|
||||
room = COLS - strlenpt(question) + 7 - strlenpt(lockuser) -
|
||||
@@ -359,7 +365,7 @@ int do_lockfile(const char *filename)
|
||||
strcat(postedname, fragment);
|
||||
free(fragment);
|
||||
} else
|
||||
postedname = mallocstrcpy(NULL, filename);
|
||||
postedname = display_string(filename, 0, room, FALSE);
|
||||
|
||||
/* Allow extra space for username (14), program name (8), PID (8),
|
||||
* and terminating \0 (1), minus the %s (2) for the file name. */
|
||||
@@ -403,13 +409,11 @@ void stat_with_alloc(const char *filename, struct stat **pstat)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* This does one of three things. If the filename is "", just create a new
|
||||
* empty buffer. Otherwise, read the given file into the existing buffer,
|
||||
* or into a new buffer when MULTIBUFFER is set or there is no buffer yet. */
|
||||
bool open_buffer(const char *filename, bool undoable)
|
||||
/* This does one of three things. If the filename is "", it just creates
|
||||
* a new empty buffer. When the filename is not empty, it reads that file
|
||||
* into a new buffer when requested, otherwise into the existing buffer. */
|
||||
bool open_buffer(const char *filename, bool new_buffer)
|
||||
{
|
||||
bool new_buffer = (openfile == NULL || ISSET(MULTIBUFFER));
|
||||
/* Whether we load into the current buffer or a new one. */
|
||||
char *realname;
|
||||
/* The filename after tilde expansion. */
|
||||
FILE *f;
|
||||
@@ -432,10 +436,11 @@ bool open_buffer(const char *filename, bool undoable)
|
||||
|
||||
/* When the specified filename is not empty, and the corresponding
|
||||
* file exists, verify that it is a normal file. */
|
||||
if (strcmp(filename, "") != 0) {
|
||||
if (*filename != '\0') {
|
||||
struct stat fileinfo;
|
||||
|
||||
if (stat(realname, &fileinfo) == 0 && !S_ISREG(fileinfo.st_mode)) {
|
||||
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
|
||||
@@ -471,24 +476,20 @@ bool open_buffer(const char *filename, bool undoable)
|
||||
rc = (filename[0] != '\0' && !ISSET(NOREAD_MODE)) ?
|
||||
open_file(realname, new_buffer, inhelp, &f) : -2;
|
||||
|
||||
/* If we have a file, and we're loading into a new buffer, update
|
||||
* the filename. */
|
||||
if (rc != -1 && new_buffer)
|
||||
openfile->filename = mallocstrcpy(openfile->filename, realname);
|
||||
|
||||
/* 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) {
|
||||
read_file(f, rc, realname, undoable, new_buffer);
|
||||
read_file(f, rc, realname, !new_buffer);
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->current_stat == NULL)
|
||||
stat_with_alloc(realname, &openfile->current_stat);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If we have a file, and we're loading into a new buffer, move back
|
||||
* to the beginning of the first line of the buffer. */
|
||||
/* If we have a file, and we've loaded it into a new buffer, set
|
||||
* the filename and put the cursor at the start of the buffer. */
|
||||
if (rc != -1 && new_buffer) {
|
||||
openfile->filename = mallocstrcpy(openfile->filename, realname);
|
||||
openfile->current = openfile->fileage;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
@@ -524,7 +525,7 @@ void replace_buffer(const char *filename)
|
||||
initialize_buffer_text();
|
||||
|
||||
/* Insert the processed file into its place. */
|
||||
read_file(f, descriptor, filename, FALSE, TRUE);
|
||||
read_file(f, descriptor, filename, FALSE);
|
||||
|
||||
/* Put current at a place that is certain to exist. */
|
||||
openfile->current = openfile->fileage;
|
||||
@@ -555,7 +556,7 @@ void replace_marked_buffer(const char *filename, filestruct *top, size_t top_x,
|
||||
* where the marked text was. */
|
||||
extract_buffer(&trash_top, &trash_bot, top, top_x, bot, bot_x);
|
||||
free_filestruct(trash_top);
|
||||
read_file(f, descriptor, filename, FALSE, TRUE);
|
||||
read_file(f, descriptor, filename, FALSE);
|
||||
|
||||
/* Restore the magicline behavior now that we're done fiddling. */
|
||||
if (!old_no_newlines)
|
||||
@@ -712,13 +713,10 @@ char *encode_data(char *buf, size_t buf_len)
|
||||
return mallocstrcpy(NULL, buf);
|
||||
}
|
||||
|
||||
/* Read an open file into the current buffer. f should be set to the
|
||||
* open file, and filename should be set to the name of the file.
|
||||
* undoable means do we want to create undo records to try and undo
|
||||
* this. Will also attempt to check file writability if fd > 0 and
|
||||
* checkwritable == TRUE. */
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable,
|
||||
bool checkwritable)
|
||||
/* Read the given open file f into the current buffer. filename should be
|
||||
* set to the name of the file. undoable means that undo records should be
|
||||
* created and that the file does not need to be checked for writability. */
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||
{
|
||||
ssize_t was_lineno = openfile->current->lineno;
|
||||
/* The line number where we start the insertion. */
|
||||
@@ -834,7 +832,7 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable,
|
||||
if (ferror(f))
|
||||
nperror(filename);
|
||||
fclose(f);
|
||||
if (fd > 0 && checkwritable) {
|
||||
if (fd > 0 && !undoable) {
|
||||
close(fd);
|
||||
writable = is_file_writable(filename);
|
||||
}
|
||||
@@ -1121,7 +1119,7 @@ void do_insertfile(void)
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* When in multibuffer mode, first open a blank buffer. */
|
||||
if (ISSET(MULTIBUFFER))
|
||||
open_buffer("", FALSE);
|
||||
open_buffer("", TRUE);
|
||||
#endif
|
||||
/* If the command is not empty, execute it and read its output
|
||||
* into the buffer, and add the command to the history list. */
|
||||
@@ -1148,8 +1146,8 @@ void do_insertfile(void)
|
||||
/* Make sure the specified path is tilde-expanded. */
|
||||
answer = free_and_assign(answer, real_dir_from_tilde(answer));
|
||||
|
||||
/* Read the specified file into the current buffer. */
|
||||
open_buffer(answer, TRUE);
|
||||
/* Read the file into a new buffer or into current buffer. */
|
||||
open_buffer(answer, ISSET(MULTIBUFFER));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
@@ -2192,12 +2190,17 @@ 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);
|
||||
char *message = charalloc(strlen(question) +
|
||||
strlen(answer) + 1);
|
||||
sprintf(message, question, answer);
|
||||
strlen(name) + 1);
|
||||
|
||||
sprintf(message, question, name);
|
||||
|
||||
i = do_yesno_prompt(FALSE, message);
|
||||
|
||||
free(message);
|
||||
free(name);
|
||||
|
||||
if (i < 1)
|
||||
continue;
|
||||
@@ -2420,8 +2423,8 @@ char **username_tab_completion(const char *buf, size_t *num_matches,
|
||||
|
||||
/* We consider the first buf_len characters of buf for filename tab
|
||||
* completion. */
|
||||
char **cwd_tab_completion(const char *buf, bool allow_files, size_t
|
||||
*num_matches, size_t buf_len)
|
||||
char **cwd_tab_completion(const char *buf, bool allow_files,
|
||||
size_t *num_matches, size_t buf_len)
|
||||
{
|
||||
char *dirname = mallocstrcpy(NULL, buf);
|
||||
char *slash, *filename;
|
||||
@@ -2600,7 +2603,8 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
if (!*lastwastab)
|
||||
*lastwastab = TRUE;
|
||||
else if (num_matches > 1) {
|
||||
int longest_name = 0, ncols, editline = 0;
|
||||
size_t longest_name = 0, ncols;
|
||||
int editline = 0;
|
||||
|
||||
/* Sort the list of available choices. */
|
||||
qsort(matches, num_matches, sizeof(char *), diralphasort);
|
||||
|
||||
345
src/global.c
345
src/global.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* global.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -32,8 +32,8 @@ volatile sig_atomic_t the_window_resized = FALSE;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
bool console;
|
||||
/* Whether we're running on a Linux VC (TRUE) or under X (FALSE). */
|
||||
bool on_a_vt;
|
||||
/* Whether we're running on a Linux VT or on something else. */
|
||||
#endif
|
||||
|
||||
bool meta_key;
|
||||
@@ -46,11 +46,6 @@ bool focusing = TRUE;
|
||||
bool as_an_at = TRUE;
|
||||
/* Whether a 0x0A byte should be shown as a ^@ instead of a ^J. */
|
||||
|
||||
int margin = 0;
|
||||
/* The amount of space reserved at the left for line numbers. */
|
||||
int editwincols = -1;
|
||||
/* The number of usable columns in the edit window: COLS - margin. */
|
||||
|
||||
bool suppress_cursorpos = FALSE;
|
||||
/* Should we skip constant position display for current keystroke? */
|
||||
|
||||
@@ -98,18 +93,22 @@ char *present_path = NULL;
|
||||
|
||||
unsigned flags[4] = {0, 0, 0, 0};
|
||||
/* Our flag containing the states of all global options. */
|
||||
|
||||
WINDOW *topwin = NULL;
|
||||
/* The top portion of the window, where we display the version
|
||||
* number of nano, the name of the current file, and whether the
|
||||
* current file has been modified. */
|
||||
/* The top portion of the screen, showing the version number of nano,
|
||||
* the name of the file, and whether the buffer was modified. */
|
||||
WINDOW *edit = NULL;
|
||||
/* The middle portion of the window, i.e. the edit window, where
|
||||
* we display the current file we're editing. */
|
||||
/* The middle portion of the screen: the edit window, showing the
|
||||
* contents of the current buffer, the file we are editing. */
|
||||
WINDOW *bottomwin = NULL;
|
||||
/* The bottom portion of the window, where we display statusbar
|
||||
/* The bottom portion of the screen, where we display statusbar
|
||||
* messages, the statusbar prompt, and a list of shortcuts. */
|
||||
int editwinrows = 0;
|
||||
/* How many rows does the edit window take up? */
|
||||
int editwincols = -1;
|
||||
/* The number of usable columns in the edit window: COLS - margin. */
|
||||
int margin = 0;
|
||||
/* The amount of space reserved at the left for line numbers. */
|
||||
|
||||
filestruct *cutbuffer = NULL;
|
||||
/* The buffer where we store cut text. */
|
||||
@@ -233,8 +232,8 @@ regmatch_t regmatches[10];
|
||||
int hilite_attribute = A_REVERSE;
|
||||
/* The curses attribute we use to highlight something. */
|
||||
#ifdef ENABLE_COLOR
|
||||
char* specified_color_combo[] = {NULL};
|
||||
/* The color combinations as specified in the rcfile. */
|
||||
colortype* color_combo[] = {NULL};
|
||||
/* The color combinations for interface elements given in the rcfile. */
|
||||
#endif
|
||||
int interface_color_pair[] = {0};
|
||||
/* The processed color pairs for the interface elements. */
|
||||
@@ -254,7 +253,7 @@ size_t length_of_list(int menu)
|
||||
size_t i = 0;
|
||||
|
||||
for (f = allfuncs; f != NULL; f = f->next)
|
||||
if ((f->menus & menu) && first_sc_for(menu, f->scfunc) != NULL)
|
||||
if ((f->menus & menu) && first_sc_for(menu, f->func) != NULL)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
@@ -266,7 +265,7 @@ size_t length_of_list(int menu)
|
||||
#define BLANKAFTER TRUE /* A blank line after this one. */
|
||||
#define TOGETHER FALSE
|
||||
|
||||
/* Just throw this here. */
|
||||
/* Empty functions, for the most part corresponding to toggles. */
|
||||
void case_sens_void(void)
|
||||
{
|
||||
}
|
||||
@@ -279,7 +278,7 @@ void backwards_void(void)
|
||||
void flip_replace(void)
|
||||
{
|
||||
}
|
||||
void gototext_void(void)
|
||||
void flip_goto(void)
|
||||
{
|
||||
}
|
||||
#ifdef ENABLE_BROWSER
|
||||
@@ -291,6 +290,9 @@ void goto_dir_void(void)
|
||||
}
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_toggle_void(void)
|
||||
{
|
||||
}
|
||||
void dos_format_void(void)
|
||||
{
|
||||
}
|
||||
@@ -318,6 +320,9 @@ void flip_newbuffer(void)
|
||||
void discard_buffer(void)
|
||||
{
|
||||
}
|
||||
void do_cancel(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* Add a function to the function list. */
|
||||
void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *help,
|
||||
@@ -332,7 +337,7 @@ void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *h
|
||||
tailfunc = f;
|
||||
|
||||
f->next = NULL;
|
||||
f->scfunc = func;
|
||||
f->func = func;
|
||||
f->menus = menus;
|
||||
f->desc = desc;
|
||||
f->viewok = viewok;
|
||||
@@ -366,7 +371,7 @@ void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
|
||||
/* Fill in the data. */
|
||||
s->menus = menus;
|
||||
s->scfunc = func;
|
||||
s->func = func;
|
||||
#ifndef NANO_TINY
|
||||
s->toggle = toggle;
|
||||
if (toggle)
|
||||
@@ -379,16 +384,6 @@ void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Assign one function's shortcuts to another function. */
|
||||
void replace_scs_for(void (*oldfunc)(void), void (*newfunc)(void))
|
||||
{
|
||||
sc *s;
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if (s->scfunc == oldfunc)
|
||||
s->scfunc = newfunc;
|
||||
}
|
||||
|
||||
/* 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))
|
||||
@@ -396,13 +391,12 @@ const sc *first_sc_for(int menu, void (*func)(void))
|
||||
const sc *s;
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if ((s->menus & menu) && s->scfunc == func)
|
||||
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
|
||||
/* Otherwise... */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -425,7 +419,7 @@ functionptrtype func_from_key(int *kbinput)
|
||||
const sc *s = get_shortcut(kbinput);
|
||||
|
||||
if (s)
|
||||
return s->scfunc;
|
||||
return s->func;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -525,16 +519,11 @@ void shortcut_init(void)
|
||||
const char *cancel_gist = N_("Cancel the current function");
|
||||
const char *help_gist = N_("Display this help text");
|
||||
const char *exit_gist =
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
N_("Close the current file buffer / Exit from nano")
|
||||
#else
|
||||
N_("Exit from nano")
|
||||
#endif
|
||||
;
|
||||
N_("Close the current buffer / Exit from nano");
|
||||
const char *writeout_gist =
|
||||
N_("Write the current file to disk");
|
||||
N_("Write the current buffer (or the marked region) to disk");
|
||||
const char *readfile_gist =
|
||||
N_("Insert another file into the current one");
|
||||
N_("Insert another file into current buffer (or into new buffer)");
|
||||
const char *whereis_gist =
|
||||
N_("Search forward for a string or a regular expression");
|
||||
const char *wherewas_gist =
|
||||
@@ -552,7 +541,7 @@ void shortcut_init(void)
|
||||
const char *prevpage_gist = N_("Go one screenful up");
|
||||
const char *nextpage_gist = N_("Go one screenful down");
|
||||
const char *cut_gist =
|
||||
N_("Cut the current line and store it in the cutbuffer");
|
||||
N_("Cut current line (or marked region) and store it in cutbuffer");
|
||||
const char *uncut_gist =
|
||||
N_("Uncut from the cutbuffer into the current line");
|
||||
const char *cursorpos_gist = N_("Display the position of the cursor");
|
||||
@@ -565,7 +554,7 @@ void shortcut_init(void)
|
||||
#ifndef NANO_TINY
|
||||
const char *mark_gist = N_("Mark text starting from the cursor position");
|
||||
const char *copy_gist =
|
||||
N_("Copy the current line and store it in the cutbuffer");
|
||||
N_("Copy current line (or marked region) and store it in cutbuffer");
|
||||
const char *indent_gist = N_("Indent the current line (or marked lines)");
|
||||
const char *unindent_gist = N_("Unindent the current line (or marked lines)");
|
||||
const char *undo_gist = N_("Undo the last operation");
|
||||
@@ -591,10 +580,12 @@ void shortcut_init(void)
|
||||
const char *lastline_gist = N_("Go to the last line of the file");
|
||||
#ifndef NANO_TINY
|
||||
const char *bracket_gist = N_("Go to the matching bracket");
|
||||
#endif
|
||||
#ifdef ENABLE_HELP
|
||||
const char *scrollup_gist =
|
||||
N_("Scroll up one line without scrolling the cursor");
|
||||
N_("Scroll up one line without moving the cursor textually");
|
||||
const char *scrolldown_gist =
|
||||
N_("Scroll down one line without scrolling the cursor");
|
||||
N_("Scroll down one line without moving the cursor textually");
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
const char *prevfile_gist = N_("Switch to the previous file buffer");
|
||||
@@ -633,8 +624,8 @@ void shortcut_init(void)
|
||||
const char *comment_gist =
|
||||
N_("Comment/uncomment the current line (or marked lines)");
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
const char *savefile_gist = N_("Save file without prompting");
|
||||
#ifndef NANO_TINY
|
||||
const char *findprev_gist = N_("Search next occurrence backward");
|
||||
const char *findnext_gist = N_("Search next occurrence forward");
|
||||
const char *recordmacro_gist = N_("Start/stop recording a macro");
|
||||
@@ -832,7 +823,7 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_full_justify, MWHEREIS,
|
||||
fulljustify_tag, WITHORSANS(fulljustify_gist), TOGETHER, NOVIEW);
|
||||
|
||||
add_to_funcs(do_gotolinecolumn_void, MWHEREIS,
|
||||
add_to_funcs(flip_goto, MWHEREIS,
|
||||
gotoline_tag, WITHORSANS(gotoline_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
@@ -870,11 +861,11 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_end, MMAIN,
|
||||
N_("End"), WITHORSANS(end_gist), BLANKAFTER, VIEW);
|
||||
|
||||
add_to_funcs(do_up_void, MMAIN|MHELP|MBROWSER,
|
||||
add_to_funcs(do_up, MMAIN|MHELP|MBROWSER,
|
||||
prevline_tag, WITHORSANS(prevline_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_down_void, MMAIN|MHELP|MBROWSER,
|
||||
add_to_funcs(do_down, MMAIN|MHELP|MBROWSER,
|
||||
nextline_tag, WITHORSANS(nextline_gist), TOGETHER, VIEW);
|
||||
#ifndef NANO_TINY
|
||||
#ifdef ENABLE_HELP
|
||||
add_to_funcs(do_scroll_up, MMAIN,
|
||||
N_("Scroll Up"), WITHORSANS(scrollup_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_scroll_down, MMAIN,
|
||||
@@ -985,14 +976,13 @@ void shortcut_init(void)
|
||||
N_("Record"), WITHORSANS(recordmacro_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(run_macro, MMAIN,
|
||||
N_("Run Macro"), WITHORSANS(runmacro_gist), BLANKAFTER, VIEW);
|
||||
|
||||
#endif
|
||||
add_to_funcs(do_search_backward, MMAIN,
|
||||
/* TRANSLATORS: This starts a backward search. */
|
||||
N_("Where Was"), WITHORSANS(wherewas_gist), BLANKAFTER, VIEW);
|
||||
|
||||
add_to_funcs(do_savefile, MMAIN,
|
||||
N_("Save"), WITHORSANS(savefile_gist), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
add_to_funcs(get_history_older_void, MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE,
|
||||
@@ -1002,11 +992,11 @@ void shortcut_init(void)
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_JUSTIFY
|
||||
add_to_funcs(do_gotolinecolumn_void, MWHEREIS,
|
||||
add_to_funcs(flip_goto, MWHEREIS,
|
||||
gotoline_tag, WITHORSANS(gotoline_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(gototext_void, MGOTOLINE,
|
||||
add_to_funcs(flip_goto, MGOTOLINE,
|
||||
N_("Go To Text"), WITHORSANS(whereis_gist), BLANKAFTER, VIEW);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -1029,8 +1019,7 @@ void shortcut_init(void)
|
||||
N_("Backup File"), WITHORSANS(backup_gist), BLANKAFTER, NOVIEW);
|
||||
}
|
||||
|
||||
/* If we're using restricted mode, file insertion is disabled, and
|
||||
* thus command execution and the multibuffer toggle have no place. */
|
||||
/* Command execution is only available when not in restricted mode. */
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
add_to_funcs(flip_execute, MINSERTFILE,
|
||||
N_("Execute Command"), WITHORSANS(execute_gist), TOGETHER, NOVIEW);
|
||||
@@ -1040,12 +1029,14 @@ void shortcut_init(void)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* Multiple buffers are only available when not in restricted mode. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs(flip_newbuffer, MINSERTFILE|MEXTCMD,
|
||||
N_("New Buffer"), WITHORSANS(newbuffer_gist), TOGETHER, NOVIEW);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
/* The file browser is only available when not in restricted mode. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs(to_files_void, MWRITEFILE|MINSERTFILE,
|
||||
N_("To Files"), WITHORSANS(tofiles_gist), TOGETHER, VIEW);
|
||||
@@ -1197,19 +1188,19 @@ void shortcut_init(void)
|
||||
add_to_sclist((MMOST & ~MBROWSER), "Home", KEY_HOME, do_home, 0);
|
||||
add_to_sclist((MMOST & ~MBROWSER), "^E", 0, do_end, 0);
|
||||
add_to_sclist((MMOST & ~MBROWSER), "End", KEY_END, do_end, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", 0, do_up_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", 0, do_down_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", 0, do_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", 0, do_down, 0);
|
||||
#ifdef ENABLE_UTF8
|
||||
if (using_utf8()) {
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xb2", KEY_UP, do_up_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xbc", KEY_DOWN, do_down_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xb2", KEY_UP, do_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x96\xbc", KEY_DOWN, do_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER, "^\xE2\x96\xb2", CONTROL_UP, do_prev_block, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER, "^\xE2\x96\xbc", CONTROL_DOWN, do_next_block, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", KEY_UP, do_up_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", KEY_DOWN, do_down_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", KEY_UP, do_up, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", KEY_DOWN, do_down, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER, "^Up", CONTROL_UP, do_prev_block, 0);
|
||||
add_to_sclist(MMAIN|MBROWSER, "^Down", CONTROL_DOWN, do_next_block, 0);
|
||||
}
|
||||
@@ -1221,7 +1212,7 @@ 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
|
||||
#ifndef NANO_TINY
|
||||
#ifdef ENABLE_HELP
|
||||
add_to_sclist(MMAIN, "M--", 0, do_scroll_up, 0);
|
||||
add_to_sclist(MMAIN, "M-_", 0, do_scroll_up, 0);
|
||||
add_to_sclist(MMAIN, "M-+", 0, do_scroll_down, 0);
|
||||
@@ -1292,8 +1283,7 @@ void shortcut_init(void)
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^W", 0, do_para_begin_void, 0);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^O", 0, do_para_end_void, 0);
|
||||
#endif
|
||||
add_to_sclist(MWHEREIS, "^T", 0, do_gotolinecolumn_void, 0);
|
||||
add_to_sclist(MGOTOLINE, "^T", 0, gototext_void, 0);
|
||||
add_to_sclist(MWHEREIS|MGOTOLINE, "^T", 0, flip_goto, 0);
|
||||
#ifdef ENABLE_HISTORIES
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXTCMD, "^P", 0, get_history_older_void, 0);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXTCMD, "^N", 0, get_history_newer_void, 0);
|
||||
@@ -1328,8 +1318,8 @@ void shortcut_init(void)
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MWRITEFILE, "M-D", 0, dos_format_void, 0);
|
||||
add_to_sclist(MWRITEFILE, "M-M", 0, mac_format_void, 0);
|
||||
/* In restricted mode, don't allow Appending, Prepending, nor making
|
||||
* backups, nor executing a command, nor opening a new buffer. */
|
||||
/* Only when not in restricted mode, allow Appending, Prepending,
|
||||
* making backups, and executing a command. */
|
||||
if (!ISSET(RESTRICTED)) {
|
||||
add_to_sclist(MWRITEFILE, "M-A", 0, append_void, 0);
|
||||
add_to_sclist(MWRITEFILE, "M-P", 0, prepend_void, 0);
|
||||
@@ -1338,11 +1328,12 @@ void shortcut_init(void)
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* Only when not in restricted mode, allow multiple buffers. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", 0, flip_newbuffer, 0);
|
||||
#endif
|
||||
#ifdef ENABLE_BROWSER
|
||||
/* In restricted mode, don't allow entering the file browser. */
|
||||
/* Only when not in restricted mode, allow entering the file browser. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files_void, 0);
|
||||
#endif
|
||||
@@ -1364,10 +1355,17 @@ void shortcut_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
#if defined(ENABLE_COLOR) && defined(ENABLE_SPELLER)
|
||||
/* Assign one function's shortcuts to another function. */
|
||||
void replace_scs_for(void (*oldfunc)(void), void (*newfunc)(void))
|
||||
{
|
||||
for (sc *s = sclist; s != NULL; s = s->next)
|
||||
if (s->func == oldfunc)
|
||||
s->func = newfunc;
|
||||
}
|
||||
|
||||
void set_lint_or_format_shortcuts(void)
|
||||
{
|
||||
#ifdef ENABLE_SPELLER
|
||||
if (openfile->syntax->formatter) {
|
||||
replace_scs_for(do_spell, do_formatter);
|
||||
replace_scs_for(do_linter, do_formatter);
|
||||
@@ -1375,31 +1373,27 @@ void set_lint_or_format_shortcuts(void)
|
||||
replace_scs_for(do_spell, do_linter);
|
||||
replace_scs_for(do_formatter, do_linter);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_spell_shortcuts(void)
|
||||
{
|
||||
#ifdef ENABLE_SPELLER
|
||||
replace_scs_for(do_formatter, do_spell);
|
||||
replace_scs_for(do_linter, do_spell);
|
||||
#endif
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
#endif /* ENABLE_COLOR && ENABLE_SPELLER */
|
||||
|
||||
const subnfunc *sctofunc(const sc *s)
|
||||
{
|
||||
subnfunc *f = allfuncs;
|
||||
|
||||
while (f != NULL && f->scfunc != s->scfunc)
|
||||
while (f != NULL && f->func != s->func)
|
||||
f = f->next;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Now let's come up with a single (hopefully) function to get a string
|
||||
* for each flag. */
|
||||
/* Return the textual description that corresponds to the given flag. */
|
||||
const char *flagtostr(int flag)
|
||||
{
|
||||
switch (flag) {
|
||||
@@ -1460,213 +1454,209 @@ sc *strtosc(const char *input)
|
||||
|
||||
#ifdef ENABLE_HELP
|
||||
if (!strcasecmp(input, "help"))
|
||||
s->scfunc = do_help_void;
|
||||
s->func = do_help_void;
|
||||
else
|
||||
#endif
|
||||
if (!strcasecmp(input, "cancel"))
|
||||
s->scfunc = do_cancel;
|
||||
s->func = do_cancel;
|
||||
else if (!strcasecmp(input, "exit"))
|
||||
s->scfunc = do_exit;
|
||||
s->func = do_exit;
|
||||
else if (!strcasecmp(input, "discardbuffer"))
|
||||
s->scfunc = discard_buffer;
|
||||
s->func = discard_buffer;
|
||||
else if (!strcasecmp(input, "writeout"))
|
||||
s->scfunc = do_writeout_void;
|
||||
#ifndef NANO_TINY
|
||||
s->func = do_writeout_void;
|
||||
else if (!strcasecmp(input, "savefile"))
|
||||
s->scfunc = do_savefile;
|
||||
#endif
|
||||
s->func = do_savefile;
|
||||
else if (!strcasecmp(input, "insert"))
|
||||
s->scfunc = do_insertfile_void;
|
||||
s->func = do_insertfile_void;
|
||||
else if (!strcasecmp(input, "whereis"))
|
||||
s->scfunc = do_search_forward;
|
||||
s->func = do_search_forward;
|
||||
else if (!strcasecmp(input, "wherewas"))
|
||||
s->scfunc = do_search_backward;
|
||||
else if (!strcasecmp(input, "searchagain") ||
|
||||
!strcasecmp(input, "research")) /* Deprecated. Remove in 2018. */
|
||||
s->scfunc = do_research;
|
||||
s->func = do_search_backward;
|
||||
else if (!strcasecmp(input, "searchagain"))
|
||||
s->func = do_research;
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "findprevious"))
|
||||
s->scfunc = do_findprevious;
|
||||
s->func = do_findprevious;
|
||||
else if (!strcasecmp(input, "findnext"))
|
||||
s->scfunc = do_findnext;
|
||||
s->func = do_findnext;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "replace"))
|
||||
s->scfunc = do_replace;
|
||||
s->func = do_replace;
|
||||
else if (!strcasecmp(input, "cut"))
|
||||
s->scfunc = do_cut_text_void;
|
||||
s->func = do_cut_text_void;
|
||||
else if (!strcasecmp(input, "uncut"))
|
||||
s->scfunc = do_uncut_text;
|
||||
s->func = do_uncut_text;
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "cutrestoffile"))
|
||||
s->scfunc = do_cut_till_eof;
|
||||
s->func = do_cut_till_eof;
|
||||
else if (!strcasecmp(input, "copytext"))
|
||||
s->scfunc = do_copy_text;
|
||||
s->func = do_copy_text;
|
||||
else if (!strcasecmp(input, "mark"))
|
||||
s->scfunc = do_mark;
|
||||
s->func = do_mark;
|
||||
#endif
|
||||
#ifdef ENABLE_SPELLER
|
||||
else if (!strcasecmp(input, "tospell") ||
|
||||
!strcasecmp(input, "speller"))
|
||||
s->scfunc = do_spell;
|
||||
s->func = do_spell;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (!strcasecmp(input, "linter"))
|
||||
s->scfunc = do_linter;
|
||||
s->func = do_linter;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "curpos") ||
|
||||
!strcasecmp(input, "cursorpos")) /* Deprecated. Remove in 2018. */
|
||||
s->scfunc = do_cursorpos_void;
|
||||
else if (!strcasecmp(input, "curpos"))
|
||||
s->func = do_cursorpos_void;
|
||||
else if (!strcasecmp(input, "gotoline"))
|
||||
s->scfunc = do_gotolinecolumn_void;
|
||||
s->func = do_gotolinecolumn_void;
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
else if (!strcasecmp(input, "justify"))
|
||||
s->scfunc = do_justify_void;
|
||||
s->func = do_justify_void;
|
||||
else if (!strcasecmp(input, "fulljustify"))
|
||||
s->scfunc = do_full_justify;
|
||||
s->func = do_full_justify;
|
||||
else if (!strcasecmp(input, "beginpara"))
|
||||
s->scfunc = do_para_begin_void;
|
||||
s->func = do_para_begin_void;
|
||||
else if (!strcasecmp(input, "endpara"))
|
||||
s->scfunc = do_para_end_void;
|
||||
s->func = do_para_end_void;
|
||||
#endif
|
||||
#ifdef ENABLE_COMMENT
|
||||
else if (!strcasecmp(input, "comment"))
|
||||
s->scfunc = do_comment;
|
||||
s->func = do_comment;
|
||||
#endif
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
else if (!strcasecmp(input, "complete"))
|
||||
s->scfunc = complete_a_word;
|
||||
s->func = complete_a_word;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "indent"))
|
||||
s->scfunc = do_indent;
|
||||
s->func = do_indent;
|
||||
else if (!strcasecmp(input, "unindent"))
|
||||
s->scfunc = do_unindent;
|
||||
else if (!strcasecmp(input, "scrollup"))
|
||||
s->scfunc = do_scroll_up;
|
||||
else if (!strcasecmp(input, "scrolldown"))
|
||||
s->scfunc = do_scroll_down;
|
||||
s->func = do_unindent;
|
||||
else if (!strcasecmp(input, "cutwordleft"))
|
||||
s->scfunc = do_cut_prev_word;
|
||||
s->func = do_cut_prev_word;
|
||||
else if (!strcasecmp(input, "cutwordright"))
|
||||
s->scfunc = do_cut_next_word;
|
||||
s->func = do_cut_next_word;
|
||||
else if (!strcasecmp(input, "findbracket"))
|
||||
s->scfunc = do_find_bracket;
|
||||
s->func = do_find_bracket;
|
||||
else if (!strcasecmp(input, "wordcount"))
|
||||
s->scfunc = do_wordlinechar_count;
|
||||
s->func = do_wordlinechar_count;
|
||||
else if (!strcasecmp(input, "recordmacro"))
|
||||
s->scfunc = record_macro;
|
||||
s->func = record_macro;
|
||||
else if (!strcasecmp(input, "runmacro"))
|
||||
s->scfunc = run_macro;
|
||||
s->func = run_macro;
|
||||
else if (!strcasecmp(input, "undo"))
|
||||
s->scfunc = do_undo;
|
||||
s->func = do_undo;
|
||||
else if (!strcasecmp(input, "redo"))
|
||||
s->scfunc = do_redo;
|
||||
s->func = do_redo;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "left") ||
|
||||
!strcasecmp(input, "back"))
|
||||
s->scfunc = do_left;
|
||||
s->func = do_left;
|
||||
else if (!strcasecmp(input, "right") ||
|
||||
!strcasecmp(input, "forward"))
|
||||
s->scfunc = do_right;
|
||||
s->func = do_right;
|
||||
else if (!strcasecmp(input, "up") ||
|
||||
!strcasecmp(input, "prevline"))
|
||||
s->scfunc = do_up_void;
|
||||
s->func = do_up;
|
||||
else if (!strcasecmp(input, "down") ||
|
||||
!strcasecmp(input, "nextline"))
|
||||
s->scfunc = do_down_void;
|
||||
s->func = do_down;
|
||||
#ifdef ENABLE_HELP
|
||||
else if (!strcasecmp(input, "scrollup"))
|
||||
s->func = do_scroll_up;
|
||||
else if (!strcasecmp(input, "scrolldown"))
|
||||
s->func = do_scroll_down;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "prevword"))
|
||||
s->scfunc = do_prev_word_void;
|
||||
s->func = do_prev_word_void;
|
||||
else if (!strcasecmp(input, "nextword"))
|
||||
s->scfunc = do_next_word_void;
|
||||
s->func = do_next_word_void;
|
||||
else if (!strcasecmp(input, "home"))
|
||||
s->scfunc = do_home;
|
||||
s->func = do_home;
|
||||
else if (!strcasecmp(input, "end"))
|
||||
s->scfunc = do_end;
|
||||
s->func = do_end;
|
||||
else if (!strcasecmp(input, "prevblock"))
|
||||
s->scfunc = do_prev_block;
|
||||
s->func = do_prev_block;
|
||||
else if (!strcasecmp(input, "nextblock"))
|
||||
s->scfunc = do_next_block;
|
||||
s->func = do_next_block;
|
||||
else if (!strcasecmp(input, "pageup") ||
|
||||
!strcasecmp(input, "prevpage"))
|
||||
s->scfunc = do_page_up;
|
||||
s->func = do_page_up;
|
||||
else if (!strcasecmp(input, "pagedown") ||
|
||||
!strcasecmp(input, "nextpage"))
|
||||
s->scfunc = do_page_down;
|
||||
s->func = do_page_down;
|
||||
else if (!strcasecmp(input, "firstline"))
|
||||
s->scfunc = to_first_line;
|
||||
s->func = to_first_line;
|
||||
else if (!strcasecmp(input, "lastline"))
|
||||
s->scfunc = to_last_line;
|
||||
s->func = to_last_line;
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
else if (!strcasecmp(input, "prevbuf"))
|
||||
s->scfunc = switch_to_prev_buffer;
|
||||
s->func = switch_to_prev_buffer;
|
||||
else if (!strcasecmp(input, "nextbuf"))
|
||||
s->scfunc = switch_to_next_buffer;
|
||||
s->func = switch_to_next_buffer;
|
||||
#endif
|
||||
else if (!strcasecmp(input, "verbatim"))
|
||||
s->scfunc = do_verbatim_input;
|
||||
s->func = do_verbatim_input;
|
||||
else if (!strcasecmp(input, "tab"))
|
||||
s->scfunc = do_tab;
|
||||
s->func = do_tab;
|
||||
else if (!strcasecmp(input, "enter"))
|
||||
s->scfunc = do_enter;
|
||||
s->func = do_enter;
|
||||
else if (!strcasecmp(input, "delete"))
|
||||
s->scfunc = do_delete;
|
||||
s->func = do_delete;
|
||||
else if (!strcasecmp(input, "backspace"))
|
||||
s->scfunc = do_backspace;
|
||||
s->func = do_backspace;
|
||||
else if (!strcasecmp(input, "refresh"))
|
||||
s->scfunc = total_refresh;
|
||||
s->func = total_refresh;
|
||||
else if (!strcasecmp(input, "suspend"))
|
||||
s->scfunc = do_suspend_void;
|
||||
s->func = do_suspend_void;
|
||||
else if (!strcasecmp(input, "casesens"))
|
||||
s->scfunc = case_sens_void;
|
||||
else if (!strcasecmp(input, "regexp") ||
|
||||
!strcasecmp(input, "regex")) /* Deprecated. Remove in 2018. */
|
||||
s->scfunc = regexp_void;
|
||||
s->func = case_sens_void;
|
||||
else if (!strcasecmp(input, "regexp"))
|
||||
s->func = regexp_void;
|
||||
else if (!strcasecmp(input, "backwards"))
|
||||
s->scfunc = backwards_void;
|
||||
else if (!strcasecmp(input, "flipreplace") ||
|
||||
!strcasecmp(input, "dontreplace")) /* Deprecated. Remove in 2018. */
|
||||
s->scfunc = flip_replace;
|
||||
else if (!strcasecmp(input, "gototext"))
|
||||
s->scfunc = gototext_void;
|
||||
s->func = backwards_void;
|
||||
else if (!strcasecmp(input, "flipreplace"))
|
||||
s->func = flip_replace;
|
||||
else if (!strcasecmp(input, "flipgoto") ||
|
||||
!strcasecmp(input, "gototext")) /* Deprecated. Remove end of 2018. */
|
||||
s->func = flip_goto;
|
||||
#ifdef ENABLE_HISTORIES
|
||||
else if (!strcasecmp(input, "prevhistory"))
|
||||
s->scfunc = get_history_older_void;
|
||||
s->func = get_history_older_void;
|
||||
else if (!strcasecmp(input, "nexthistory"))
|
||||
s->scfunc = get_history_newer_void;
|
||||
s->func = get_history_newer_void;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
else if (!strcasecmp(input, "dosformat"))
|
||||
s->scfunc = dos_format_void;
|
||||
s->func = dos_format_void;
|
||||
else if (!strcasecmp(input, "macformat"))
|
||||
s->scfunc = mac_format_void;
|
||||
s->func = mac_format_void;
|
||||
else if (!strcasecmp(input, "append"))
|
||||
s->scfunc = append_void;
|
||||
s->func = append_void;
|
||||
else if (!strcasecmp(input, "prepend"))
|
||||
s->scfunc = prepend_void;
|
||||
s->func = prepend_void;
|
||||
else if (!strcasecmp(input, "backup"))
|
||||
s->scfunc = backup_file_void;
|
||||
s->func = backup_file_void;
|
||||
else if (!strcasecmp(input, "flipexecute"))
|
||||
s->scfunc = flip_execute;
|
||||
s->func = flip_execute;
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
else if (!strcasecmp(input, "flipnewbuffer") ||
|
||||
!strcasecmp(input, "newbuffer")) /* Deprecated. Remove in 2018. */
|
||||
s->scfunc = flip_newbuffer;
|
||||
else if (!strcasecmp(input, "flipnewbuffer"))
|
||||
s->func = flip_newbuffer;
|
||||
#endif
|
||||
#ifdef ENABLE_BROWSER
|
||||
else if (!strcasecmp(input, "tofiles") ||
|
||||
!strcasecmp(input, "browser"))
|
||||
s->scfunc = to_files_void;
|
||||
s->func = to_files_void;
|
||||
else if (!strcasecmp(input, "gotodir"))
|
||||
s->scfunc = goto_dir_void;
|
||||
s->func = goto_dir_void;
|
||||
else if (!strcasecmp(input, "firstfile"))
|
||||
s->scfunc = to_first_file;
|
||||
s->func = to_first_file;
|
||||
else if (!strcasecmp(input, "lastfile"))
|
||||
s->scfunc = to_last_file;
|
||||
s->func = to_last_file;
|
||||
#endif
|
||||
else {
|
||||
#ifndef NANO_TINY
|
||||
s->scfunc = do_toggle_void;
|
||||
s->func = do_toggle_void;
|
||||
if (!strcasecmp(input, "nohelp"))
|
||||
s->toggle = NO_HELP;
|
||||
else if (!strcasecmp(input, "constupdate"))
|
||||
@@ -1730,8 +1720,7 @@ int strtomenu(const char *input)
|
||||
return MWHEREIS;
|
||||
else if (!strcasecmp(input, "replace"))
|
||||
return MREPLACE;
|
||||
else if (!strcasecmp(input, "replace2") || /* Deprecated. Remove in 2018. */
|
||||
!strcasecmp(input, "replacewith"))
|
||||
else if (!strcasecmp(input, "replacewith"))
|
||||
return MREPLACEWITH;
|
||||
else if (!strcasecmp(input, "gotoline"))
|
||||
return MGOTOLINE;
|
||||
@@ -1797,12 +1786,14 @@ void thanks_for_all_the_fish(void)
|
||||
free(alt_speller);
|
||||
#endif
|
||||
free_filestruct(cutbuffer);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* Free the memory associated with each open file buffer. */
|
||||
while (openfile != openfile->next) {
|
||||
openfile = openfile->next;
|
||||
delete_opennode(openfile->prev);
|
||||
}
|
||||
delete_opennode(openfile);
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
free(syntaxstr);
|
||||
while (syntaxes != NULL) {
|
||||
|
||||
31
src/help.c
31
src/help.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* help.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2000-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2000-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2017 Rishabh Dave *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
@@ -46,7 +46,7 @@ char *tempfilename = NULL;
|
||||
* read that file into a new buffer. */
|
||||
void wrap_the_help_text(bool redisplaying)
|
||||
{
|
||||
int sum = 0;
|
||||
size_t sum = 0;
|
||||
const char *ptr = start_of_body;
|
||||
FILE *tempfile = fopen(tempfilename, "w+b");
|
||||
|
||||
@@ -75,7 +75,7 @@ void wrap_the_help_text(bool redisplaying)
|
||||
if (redisplaying)
|
||||
close_buffer();
|
||||
|
||||
open_buffer(tempfilename, FALSE);
|
||||
open_buffer(tempfilename, TRUE);
|
||||
remove_magicline();
|
||||
|
||||
prepare_for_display();
|
||||
@@ -142,10 +142,10 @@ void do_help(void)
|
||||
|
||||
UNSET(WHITESPACE_DISPLAY);
|
||||
UNSET(NOREAD_MODE);
|
||||
SET(MULTIBUFFER);
|
||||
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
UNSET(LINE_NUMBERS);
|
||||
editwincols = COLS;
|
||||
margin = 0;
|
||||
#endif
|
||||
tabsize = 8;
|
||||
@@ -191,12 +191,12 @@ void do_help(void)
|
||||
|
||||
if (func == total_refresh) {
|
||||
total_redraw();
|
||||
} else if (func == do_up_void) {
|
||||
do_up(TRUE);
|
||||
} else if (func == do_down_void) {
|
||||
} else if (func == do_up) {
|
||||
do_scroll_up();
|
||||
} else if (func == do_down) {
|
||||
if (openfile->edittop->lineno + editwinrows - 1 <
|
||||
openfile->filebot->lineno)
|
||||
do_down(TRUE);
|
||||
do_scroll_down();
|
||||
} else if (func == do_page_up) {
|
||||
do_page_up();
|
||||
} else if (func == do_page_down) {
|
||||
@@ -215,13 +215,17 @@ void do_help(void)
|
||||
do_findprevious();
|
||||
} else if (func == do_findnext) {
|
||||
do_findnext();
|
||||
#ifdef ENABLE_NANORC
|
||||
} else if (func == (functionptrtype)implant) {
|
||||
implant(first_sc_for(MHELP, func)->expansion);
|
||||
#endif
|
||||
} else if (kbinput == KEY_WINCH) {
|
||||
; /* Nothing to do. */
|
||||
#endif
|
||||
#ifdef ENABLE_MOUSE
|
||||
} else if (kbinput == KEY_MOUSE) {
|
||||
int dummy_x, dummy_y;
|
||||
get_mouseinput(&dummy_x, &dummy_y, TRUE);
|
||||
int dummy_row, dummy_col;
|
||||
get_mouseinput(&dummy_row, &dummy_col, TRUE);
|
||||
#endif
|
||||
} else if (func == do_exit) {
|
||||
/* Exit from the help viewer. */
|
||||
@@ -249,6 +253,7 @@ void do_help(void)
|
||||
|
||||
#ifdef ENABLE_LINENUMBERS
|
||||
margin = was_margin;
|
||||
editwincols = COLS - margin;
|
||||
#endif
|
||||
tabsize = was_tabsize;
|
||||
#ifdef ENABLE_COLOR
|
||||
@@ -471,7 +476,7 @@ void help_init(void)
|
||||
size_t endis_len = strlen(_("enable/disable"));
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if (s->scfunc == do_toggle_void)
|
||||
if (s->func == do_toggle_void)
|
||||
allocsize += strlen(_(flagtostr(s->toggle))) + endis_len + 8;
|
||||
}
|
||||
#endif
|
||||
@@ -504,7 +509,7 @@ void help_init(void)
|
||||
if ((s->menus & currmenu) == 0)
|
||||
continue;
|
||||
|
||||
if (s->scfunc == f->scfunc) {
|
||||
if (s->func == f->func) {
|
||||
scsfound++;
|
||||
/* Make the first column narrower (6) than the second (10),
|
||||
* but allow it to spill into the second, for "M-Space". */
|
||||
@@ -620,7 +625,7 @@ size_t help_line_len(const char *ptr)
|
||||
else if (wrap_location > 0)
|
||||
return wrap_location;
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_HELP */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* history.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2003-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2003-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -227,7 +227,7 @@ char *get_history_completion(filestruct **h, char *s, size_t len)
|
||||
* match, or len is 0. Return s. */
|
||||
return (char *)s;
|
||||
}
|
||||
#endif /* ENSABLE_TABCOMP */
|
||||
#endif /* ENABLE_TABCOMP */
|
||||
|
||||
void history_error(const char *msg, ...)
|
||||
{
|
||||
|
||||
67
src/move.c
67
src/move.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* move.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -481,18 +481,12 @@ void do_end(void)
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Move the cursor to the preceding line or chunk. If scroll_only is TRUE,
|
||||
* also scroll the screen one row, so the cursor stays in the same spot. */
|
||||
void do_up(bool scroll_only)
|
||||
/* Move the cursor to the preceding line or chunk. */
|
||||
void do_up(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t leftedge, target_column;
|
||||
|
||||
/* When just scrolling and the top of the file is onscreen, get out. */
|
||||
if (scroll_only && openfile->edittop == openfile->fileage &&
|
||||
openfile->firstcolumn == 0)
|
||||
return;
|
||||
|
||||
get_edge_and_target(&leftedge, &target_column);
|
||||
|
||||
/* If we can't move up one line or chunk, we're at top of file. */
|
||||
@@ -501,18 +495,17 @@ void do_up(bool scroll_only)
|
||||
|
||||
set_proper_index_and_pww(&leftedge, target_column, FALSE);
|
||||
|
||||
if (scroll_only)
|
||||
edit_scroll(BACKWARD, 1);
|
||||
|
||||
edit_redraw(was_current, FLOWING);
|
||||
if (openfile->current_y == 0 && ISSET(SMOOTH_SCROLL))
|
||||
edit_scroll(BACKWARD);
|
||||
else
|
||||
edit_redraw(was_current, FLOWING);
|
||||
|
||||
/* <Up> should not change placewewant, so restore it. */
|
||||
openfile->placewewant = leftedge + target_column;
|
||||
}
|
||||
|
||||
/* Move the cursor to next line or chunk. If scroll_only is TRUE, also
|
||||
* scroll the screen one row, so the cursor stays in the same spot. */
|
||||
void do_down(bool scroll_only)
|
||||
/* Move the cursor to next line or chunk. */
|
||||
void do_down(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
size_t leftedge, target_column;
|
||||
@@ -525,38 +518,42 @@ void do_down(bool scroll_only)
|
||||
|
||||
set_proper_index_and_pww(&leftedge, target_column, TRUE);
|
||||
|
||||
if (scroll_only)
|
||||
edit_scroll(FORWARD, 1);
|
||||
|
||||
edit_redraw(was_current, FLOWING);
|
||||
if (openfile->current_y == editwinrows - 1 && ISSET(SMOOTH_SCROLL))
|
||||
edit_scroll(FORWARD);
|
||||
else
|
||||
edit_redraw(was_current, FLOWING);
|
||||
|
||||
/* <Down> should not change placewewant, so restore it. */
|
||||
openfile->placewewant = leftedge + target_column;
|
||||
}
|
||||
|
||||
/* Move up one line or chunk. */
|
||||
void do_up_void(void)
|
||||
{
|
||||
do_up(FALSE);
|
||||
}
|
||||
|
||||
/* Move down one line or chunk. */
|
||||
void do_down_void(void)
|
||||
{
|
||||
do_down(FALSE);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
#ifdef ENABLE_HELP
|
||||
/* Scroll up one line or chunk without scrolling the cursor. */
|
||||
void do_scroll_up(void)
|
||||
{
|
||||
do_up(TRUE);
|
||||
/* When the top of the file is onscreen, we can't scroll. */
|
||||
if (openfile->edittop->prev == NULL && openfile->firstcolumn == 0)
|
||||
return;
|
||||
|
||||
if (openfile->current_y == editwinrows - 1)
|
||||
do_up();
|
||||
|
||||
edit_scroll(BACKWARD);
|
||||
}
|
||||
|
||||
/* Scroll down one line or chunk without scrolling the cursor. */
|
||||
void do_scroll_down(void)
|
||||
{
|
||||
do_down(TRUE);
|
||||
if (openfile->current_y == 0)
|
||||
do_down();
|
||||
|
||||
if (openfile->edittop->next != NULL
|
||||
#ifndef NANO_TINY
|
||||
|| chunk_for(openfile->firstcolumn, openfile->edittop) <
|
||||
number_of_chunks_in(openfile->edittop)
|
||||
#endif
|
||||
)
|
||||
edit_scroll(FORWARD);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
437
src/nano.c
437
src/nano.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* nano.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#ifndef NANO_TINY
|
||||
#if defined(__linux__) || !defined(NANO_TINY)
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -38,6 +38,15 @@
|
||||
#include <termios.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/vt.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
#define read_them_all TRUE
|
||||
#else
|
||||
#define read_them_all FALSE
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
static int oldinterval = -1;
|
||||
@@ -60,8 +69,7 @@ static struct sigaction act;
|
||||
static bool input_was_aborted = FALSE;
|
||||
/* Whether reading from standard input was aborted via ^C. */
|
||||
|
||||
/* Create a new linestruct node. Note that we do not set prevnode->next
|
||||
* to the new line. */
|
||||
/* Create a new linestruct node. Note that we do not set prevnode->next. */
|
||||
filestruct *make_new_node(filestruct *prevnode)
|
||||
{
|
||||
filestruct *newnode = nmalloc(sizeof(filestruct));
|
||||
@@ -171,20 +179,24 @@ void free_filestruct(filestruct *src)
|
||||
delete_node(src);
|
||||
}
|
||||
|
||||
/* Renumber the lines in a buffer, starting with fileptr. */
|
||||
void renumber(filestruct *fileptr)
|
||||
/* Renumber the lines in a buffer, starting with the given line. */
|
||||
void renumber(filestruct *line)
|
||||
{
|
||||
ssize_t line;
|
||||
ssize_t number;
|
||||
|
||||
if (fileptr == NULL)
|
||||
if (line == NULL) {
|
||||
#ifndef NANO_TINY
|
||||
statusline(ALERT, "Trying to renumber nothing -- please report a bug");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
line = (fileptr->prev == NULL) ? 0 : fileptr->prev->lineno;
|
||||
number = (line->prev == NULL) ? 0 : line->prev->lineno;
|
||||
|
||||
assert(fileptr != fileptr->next);
|
||||
|
||||
for (; fileptr != NULL; fileptr = fileptr->next)
|
||||
fileptr->lineno = ++line;
|
||||
while (line != NULL) {
|
||||
line->lineno = ++number;
|
||||
line = line->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Partition the current buffer so that it appears to begin at (top, top_x)
|
||||
@@ -192,12 +204,7 @@ void renumber(filestruct *fileptr)
|
||||
partition *partition_filestruct(filestruct *top, size_t top_x,
|
||||
filestruct *bot, size_t bot_x)
|
||||
{
|
||||
partition *p;
|
||||
|
||||
assert(top != NULL && bot != NULL && openfile->fileage != NULL && openfile->filebot != NULL);
|
||||
|
||||
/* Initialize the partition. */
|
||||
p = (partition *)nmalloc(sizeof(partition));
|
||||
partition *p = nmalloc(sizeof(partition));
|
||||
|
||||
/* If the top and bottom of the partition are different from the top
|
||||
* and bottom of the buffer, save the latter and then set them
|
||||
@@ -240,8 +247,6 @@ partition *partition_filestruct(filestruct *top, size_t top_x,
|
||||
* to (filebot, $) again. */
|
||||
void unpartition_filestruct(partition **p)
|
||||
{
|
||||
assert(p != NULL && openfile->fileage != NULL && openfile->filebot != NULL);
|
||||
|
||||
/* Reattach the line above the top of the partition, and restore the
|
||||
* text before top_x from top_data. Free top_data when we're done
|
||||
* with it. */
|
||||
@@ -292,8 +297,6 @@ void extract_buffer(filestruct **file_top, filestruct **file_bot,
|
||||
bool same_line = FALSE;
|
||||
#endif
|
||||
|
||||
assert(file_top != NULL && file_bot != NULL && top != NULL && bot != NULL);
|
||||
|
||||
/* If (top, top_x)-(bot, bot_x) doesn't cover any text, get out. */
|
||||
if (top == bot && top_x == bot_x)
|
||||
return;
|
||||
@@ -350,8 +353,8 @@ void extract_buffer(filestruct **file_top, filestruct **file_bot,
|
||||
|
||||
delete_node(openfile->fileage);
|
||||
|
||||
/* Renumber, starting with the line after the original file_bot. */
|
||||
renumber(file_bot_save->next);
|
||||
/* Renumber, starting at the last line of the original buffer. */
|
||||
renumber(file_bot_save);
|
||||
}
|
||||
|
||||
/* Since the text has now been saved, remove it from the buffer. */
|
||||
@@ -405,8 +408,6 @@ void ingraft_buffer(filestruct *somebuffer)
|
||||
bool right_side_up = FALSE, single_line = FALSE;
|
||||
#endif
|
||||
|
||||
assert(somebuffer != NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Keep track of whether the mark begins inside the partition and
|
||||
* will need adjustment. */
|
||||
@@ -500,17 +501,17 @@ openfilestruct *make_new_opennode(void)
|
||||
return (openfilestruct *)nmalloc(sizeof(openfilestruct));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* Unlink a node from the rest of the circular list, and delete it. */
|
||||
void unlink_opennode(openfilestruct *fileptr)
|
||||
{
|
||||
assert(fileptr != fileptr->prev && fileptr != fileptr->next);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (fileptr == firstfile)
|
||||
firstfile = firstfile->next;
|
||||
|
||||
fileptr->prev->next = fileptr->next;
|
||||
fileptr->next->prev = fileptr->prev;
|
||||
|
||||
#endif
|
||||
delete_opennode(fileptr);
|
||||
}
|
||||
|
||||
@@ -527,6 +528,7 @@ void delete_opennode(openfilestruct *fileptr)
|
||||
#endif
|
||||
free(fileptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Display a warning about a key disabled in view mode. */
|
||||
void print_view_warning(void)
|
||||
@@ -584,69 +586,56 @@ void finish(void)
|
||||
void die(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
openfilestruct *firstone = openfile;
|
||||
|
||||
/* Switch on the cursor and leave curses mode. */
|
||||
curs_set(1);
|
||||
endwin();
|
||||
|
||||
/* Restore the old terminal settings. */
|
||||
tcsetattr(0, TCSANOW, &oldterm);
|
||||
|
||||
/* Display the dying message. */
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
|
||||
while (openfile) {
|
||||
#ifndef NANO_TINY
|
||||
/* If the current buffer has a lockfile, remove it. */
|
||||
if (openfile && ISSET(LOCKING) && openfile->lock_filename)
|
||||
delete_lockfile(openfile->lock_filename);
|
||||
/* If the current buffer has a lockfile, remove it. */
|
||||
if (ISSET(LOCKING) && openfile->lock_filename)
|
||||
delete_lockfile(openfile->lock_filename);
|
||||
#endif
|
||||
/* If the current buffer was modified, ensure it is unpartitioned,
|
||||
* then save it. When in restricted mode, we don't save anything,
|
||||
* because it would write files not mentioned on the command line. */
|
||||
if (openfile->modified && !ISSET(RESTRICTED)) {
|
||||
if (filepart != NULL)
|
||||
unpartition_filestruct(&filepart);
|
||||
|
||||
/* If the current file buffer was modified, save it. */
|
||||
if (openfile && openfile->modified) {
|
||||
/* If the buffer is partitioned, unpartition it first. */
|
||||
if (filepart != NULL)
|
||||
unpartition_filestruct(&filepart);
|
||||
|
||||
die_save_file(openfile->filename, openfile->current_stat);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* Save all of the other modified file buffers, if any. */
|
||||
if (openfile != NULL) {
|
||||
openfilestruct *firstone = openfile;
|
||||
|
||||
while (openfile->next != firstone) {
|
||||
openfile = openfile->next;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(LOCKING) && openfile->lock_filename)
|
||||
delete_lockfile(openfile->lock_filename);
|
||||
#endif
|
||||
if (openfile->modified)
|
||||
die_save_file(openfile->filename, openfile->current_stat);
|
||||
emergency_save(openfile->filename, openfile->current_stat);
|
||||
}
|
||||
}
|
||||
|
||||
filepart = NULL;
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
openfile = openfile->next;
|
||||
#endif
|
||||
if (openfile == firstone)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Abandon the building. */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Save the current file under the name specified in die_filename, which
|
||||
* is modified to be unique if necessary. */
|
||||
void die_save_file(const char *die_filename, struct stat *die_stat)
|
||||
/* Save the current buffer under the given name.
|
||||
* If necessary, the name is modified to be unique. */
|
||||
void emergency_save(const char *die_filename, struct stat *die_stat)
|
||||
{
|
||||
char *targetname;
|
||||
bool failed = TRUE;
|
||||
|
||||
/* If we're using restricted mode, don't write any emergency backup
|
||||
* files, since that would allow reading from or writing to files
|
||||
* not specified on the command line. */
|
||||
if (ISSET(RESTRICTED))
|
||||
return;
|
||||
|
||||
/* If we can't save, we have really bad problems, but we might as
|
||||
* well try. */
|
||||
/* If the buffer has no name, simply call it "nano". */
|
||||
if (*die_filename == '\0')
|
||||
die_filename = "nano";
|
||||
|
||||
@@ -665,9 +654,8 @@ void die_save_file(const char *die_filename, struct stat *die_stat)
|
||||
_("Too many backup files?"));
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Try and chmod/chown the save file to the values of the original file,
|
||||
* but don't worry if it fails because we're supposed to be bailing as
|
||||
* fast as possible. */
|
||||
/* Try to chmod/chown the saved file to the values of the original file,
|
||||
* but ignore any failure as we are in a hurry to get out. */
|
||||
if (die_stat) {
|
||||
IGNORE_CALL_RESULT(chmod(targetname, die_stat->st_mode));
|
||||
IGNORE_CALL_RESULT(chown(targetname, die_stat->st_uid,
|
||||
@@ -818,6 +806,10 @@ void usage(void)
|
||||
N_("Fix numeric keypad key confusion problem"));
|
||||
print_opt("-L", "--nonewlines",
|
||||
N_("Don't add newlines to the ends of files"));
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
print_opt("-M", "--trimblanks",
|
||||
N_("Trim tail spaces when hard-wrapping"));
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-N", "--noconvert",
|
||||
N_("Don't convert files from DOS/Mac format"));
|
||||
@@ -913,8 +905,8 @@ void version(void)
|
||||
#else
|
||||
printf(_(" GNU nano, version %s\n"), VERSION);
|
||||
#endif
|
||||
printf(" (C) 1999-2011, 2013-2017 Free Software Foundation, Inc.\n");
|
||||
printf(_(" (C) 2014-%s the contributors to nano\n"), "2017");
|
||||
printf(" (C) 1999-2011, 2013-2018 Free Software Foundation, Inc.\n");
|
||||
printf(_(" (C) 2014-%s the contributors to nano\n"), "2018");
|
||||
printf(_(" Email: nano@nano-editor.org Web: https://nano-editor.org/"));
|
||||
printf(_("\n Compiled options:"));
|
||||
|
||||
@@ -1095,12 +1087,6 @@ void close_and_go(void)
|
||||
finish();
|
||||
}
|
||||
|
||||
/* Another placeholder for function mapping. */
|
||||
void do_cancel(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/* Make a note that reading from stdin was concluded with ^C. */
|
||||
RETSIGTYPE make_a_note(int signal)
|
||||
{
|
||||
@@ -1113,7 +1099,7 @@ bool scoop_stdin(void)
|
||||
struct sigaction oldaction, newaction;
|
||||
/* Original and temporary handlers for SIGINT. */
|
||||
bool setup_failed = FALSE;
|
||||
/* Whether setting up the SIGINT handler failed. */
|
||||
/* Whether setting up the temporary SIGINT handler failed. */
|
||||
FILE *stream;
|
||||
int thetty;
|
||||
|
||||
@@ -1132,12 +1118,12 @@ bool scoop_stdin(void)
|
||||
/* Set things up so that SIGINT will cancel the reading. */
|
||||
if (sigaction(SIGINT, NULL, &newaction) == -1) {
|
||||
setup_failed = TRUE;
|
||||
nperror("sigaction");
|
||||
perror("sigaction");
|
||||
} else {
|
||||
newaction.sa_handler = make_a_note;
|
||||
if (sigaction(SIGINT, &newaction, &oldaction) == -1) {
|
||||
setup_failed = TRUE;
|
||||
nperror("sigaction");
|
||||
perror("sigaction");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,8 +1139,8 @@ bool scoop_stdin(void)
|
||||
}
|
||||
|
||||
/* Read the input into a new buffer. */
|
||||
open_buffer("", FALSE);
|
||||
read_file(stream, 0, "stdin", TRUE, FALSE);
|
||||
open_buffer("", TRUE);
|
||||
read_file(stream, 0, "stdin", TRUE);
|
||||
openfile->edittop = openfile->fileage;
|
||||
|
||||
/* Reconnect the tty as the input source. */
|
||||
@@ -1170,7 +1156,7 @@ bool scoop_stdin(void)
|
||||
|
||||
/* If it was changed, restore the handler for SIGINT. */
|
||||
if (!setup_failed && sigaction(SIGINT, &oldaction, NULL) == -1)
|
||||
nperror("sigaction");
|
||||
perror("sigaction");
|
||||
|
||||
terminal_init();
|
||||
doupdate();
|
||||
@@ -1409,12 +1395,6 @@ void do_toggle(int flag)
|
||||
statusline(HUSH, "%s %s", _(flagtostr(flag)),
|
||||
enabled ? _("enabled") : _("disabled"));
|
||||
}
|
||||
|
||||
/* Bleh. */
|
||||
void do_toggle_void(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Disable extended input and output processing in our terminal
|
||||
@@ -1422,7 +1402,7 @@ void do_toggle_void(void)
|
||||
void disable_extended_io(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios term;
|
||||
struct termios term = {0};
|
||||
|
||||
tcgetattr(0, &term);
|
||||
term.c_lflag &= ~IEXTEN;
|
||||
@@ -1436,7 +1416,7 @@ void disable_extended_io(void)
|
||||
void disable_signals(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios term;
|
||||
struct termios term = {0};
|
||||
|
||||
tcgetattr(0, &term);
|
||||
term.c_lflag &= ~ISIG;
|
||||
@@ -1450,7 +1430,7 @@ void disable_signals(void)
|
||||
void enable_signals(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios term;
|
||||
struct termios term = {0};
|
||||
|
||||
tcgetattr(0, &term);
|
||||
term.c_lflag |= ISIG;
|
||||
@@ -1507,7 +1487,6 @@ void terminal_init(void)
|
||||
|
||||
if (!newterm_set) {
|
||||
#endif
|
||||
|
||||
raw();
|
||||
nonl();
|
||||
noecho();
|
||||
@@ -1556,6 +1535,83 @@ void unbound_key(int code)
|
||||
statusline(ALERT, _("Unbound key: %c"), code);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
/* Handle a mouse click on the edit window or the shortcut list. */
|
||||
int do_mouse(void)
|
||||
{
|
||||
int click_row, click_col;
|
||||
int retval = get_mouseinput(&click_row, &click_col, TRUE);
|
||||
|
||||
/* If the click is wrong or already handled, we're done. */
|
||||
if (retval != 0)
|
||||
return retval;
|
||||
|
||||
/* If the click was in the edit window, put the cursor in that spot. */
|
||||
if (wmouse_trafo(edit, &click_row, &click_col, FALSE)) {
|
||||
filestruct *current_save = openfile->current;
|
||||
ssize_t row_count = click_row - openfile->current_y;
|
||||
size_t leftedge;
|
||||
#ifndef NANO_TINY
|
||||
size_t current_x_save = openfile->current_x;
|
||||
bool sameline = (click_row == openfile->current_y);
|
||||
/* Whether the click was on the row where the cursor is. */
|
||||
|
||||
if (ISSET(SOFTWRAP))
|
||||
leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
else
|
||||
#endif
|
||||
leftedge = get_page_start(xplustabs());
|
||||
|
||||
/* Move current up or down to the row that was clicked on. */
|
||||
if (row_count < 0)
|
||||
go_back_chunks(-row_count, &openfile->current, &leftedge);
|
||||
else
|
||||
go_forward_chunks(row_count, &openfile->current, &leftedge);
|
||||
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
actual_last_column(leftedge, click_col));
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Clicking where the cursor is toggles the mark, as does clicking
|
||||
* beyond the line length with the cursor at the end of the line. */
|
||||
if (sameline && openfile->current_x == current_x_save)
|
||||
do_mark();
|
||||
else
|
||||
#endif
|
||||
/* The cursor moved; clean the cutbuffer on the next cut. */
|
||||
cutbuffer_reset();
|
||||
|
||||
edit_redraw(current_save, CENTERING);
|
||||
}
|
||||
|
||||
/* No more handling is needed. */
|
||||
return 2;
|
||||
}
|
||||
#endif /* ENABLE_MOUSE */
|
||||
|
||||
/* Return TRUE when the given function is a cursor-moving command. */
|
||||
bool wanted_to_move(void (*func)(void))
|
||||
{
|
||||
return func == do_left || func == do_right ||
|
||||
func == do_up || func == do_down ||
|
||||
func == do_home || func == do_end ||
|
||||
func == do_prev_word_void || func == do_next_word_void ||
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
func == do_para_begin_void || func == do_para_end_void ||
|
||||
#endif
|
||||
func == do_prev_block || func == do_next_block ||
|
||||
func == do_page_up || func == do_page_down ||
|
||||
func == to_first_line || func == to_last_line;
|
||||
}
|
||||
|
||||
/* Return TRUE when the given shortcut is valid in view mode. */
|
||||
bool okay_for_view(const sc *shortcut)
|
||||
{
|
||||
const subnfunc *func = sctofunc(shortcut);
|
||||
|
||||
return (func != NULL && func->viewok);
|
||||
}
|
||||
|
||||
/* Read in a keystroke. Act on the keystroke if it is a shortcut or a toggle;
|
||||
* otherwise, insert it into the edit buffer. If allow_funcs is FALSE, don't
|
||||
* do anything with the keystroke -- just return it. */
|
||||
@@ -1569,8 +1625,7 @@ int do_input(bool allow_funcs)
|
||||
/* The length of the input buffer. */
|
||||
bool retain_cuts = FALSE;
|
||||
/* Whether to conserve the current contents of the cutbuffer. */
|
||||
const sc *s;
|
||||
bool have_shortcut;
|
||||
const sc *shortcut;
|
||||
|
||||
/* Read in a keystroke, and show the cursor while waiting. */
|
||||
input = get_kbinput(edit, VISIBLE);
|
||||
@@ -1594,15 +1649,11 @@ int do_input(bool allow_funcs)
|
||||
#endif
|
||||
|
||||
/* Check for a shortcut in the main list. */
|
||||
s = get_shortcut(&input);
|
||||
|
||||
/* If we got a shortcut from the main list, or a "universal"
|
||||
* edit window shortcut, set have_shortcut to TRUE. */
|
||||
have_shortcut = (s != NULL);
|
||||
shortcut = get_shortcut(&input);
|
||||
|
||||
/* If we got a non-high-bit control key, a meta key sequence, or a
|
||||
* function key, and it's not a shortcut or toggle, throw it out. */
|
||||
if (!have_shortcut) {
|
||||
if (shortcut == NULL) {
|
||||
if (is_ascii_cntrl_char(input) || meta_key || !is_byte(input)) {
|
||||
unbound_key(input);
|
||||
input = ERR;
|
||||
@@ -1615,7 +1666,7 @@ int do_input(bool allow_funcs)
|
||||
/* If the keystroke isn't a shortcut nor a toggle, it's a normal text
|
||||
* character: add the character to the input buffer -- or display a
|
||||
* warning when we're in view mode. */
|
||||
if (input != ERR && !have_shortcut) {
|
||||
if (input != ERR && shortcut == NULL) {
|
||||
if (ISSET(VIEW_MODE))
|
||||
print_view_warning();
|
||||
else {
|
||||
@@ -1635,7 +1686,7 @@ int do_input(bool allow_funcs)
|
||||
* characters waiting after the one we read in, we need to output
|
||||
* all available characters in the input puddle. Note that this
|
||||
* puddle will be empty if we're in view mode. */
|
||||
if (have_shortcut || get_key_buffer_len() == 0) {
|
||||
if (shortcut || get_key_buffer_len() == 0) {
|
||||
if (puddle != NULL) {
|
||||
/* Insert all bytes in the input buffer into the edit buffer
|
||||
* at once, filtering out any low control codes. */
|
||||
@@ -1649,33 +1700,38 @@ int do_input(bool allow_funcs)
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_shortcut)
|
||||
if (shortcut == NULL)
|
||||
pletion_line = NULL;
|
||||
else {
|
||||
const subnfunc *f = sctofunc(s);
|
||||
|
||||
if (ISSET(VIEW_MODE) && f && !f->viewok) {
|
||||
if (ISSET(VIEW_MODE) && !okay_for_view(shortcut)) {
|
||||
print_view_warning();
|
||||
return ERR;
|
||||
}
|
||||
|
||||
/* If the function associated with this shortcut is
|
||||
* cutting or copying text, remember this. */
|
||||
if (s->scfunc == do_cut_text_void
|
||||
if (shortcut->func == do_cut_text_void
|
||||
#ifndef NANO_TINY
|
||||
|| s->scfunc == do_copy_text || s->scfunc == do_cut_till_eof
|
||||
|| shortcut->func == do_copy_text
|
||||
|| shortcut->func == do_cut_till_eof
|
||||
#endif
|
||||
)
|
||||
retain_cuts = TRUE;
|
||||
|
||||
#ifdef ENABLE_WORDCOMPLETION
|
||||
if (s->scfunc != complete_a_word)
|
||||
if (shortcut->func != complete_a_word)
|
||||
pletion_line = NULL;
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
if (shortcut->func == (functionptrtype)implant) {
|
||||
implant(shortcut->expansion);
|
||||
return 42;
|
||||
}
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (s->scfunc == do_toggle_void) {
|
||||
do_toggle(s->toggle);
|
||||
if (s->toggle != CUT_FROM_CURSOR)
|
||||
if (shortcut->func == do_toggle_void) {
|
||||
do_toggle(shortcut->toggle);
|
||||
if (shortcut->toggle != CUT_FROM_CURSOR)
|
||||
retain_cuts = TRUE;
|
||||
} else
|
||||
#endif
|
||||
@@ -1695,14 +1751,17 @@ int do_input(bool allow_funcs)
|
||||
}
|
||||
#endif
|
||||
/* Execute the function of the shortcut. */
|
||||
s->scfunc();
|
||||
shortcut->func();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When the marked region changes without Shift being held,
|
||||
* discard a soft mark. And when the marked region covers a
|
||||
* different set of lines, reset the "last line too" flag. */
|
||||
if (openfile->mark && (openfile->current != was_current ||
|
||||
openfile->current_x != was_x)) {
|
||||
if (!shift_held && openfile->kind_of_mark == SOFTMARK) {
|
||||
if (openfile->mark) {
|
||||
if (!shift_held && openfile->kind_of_mark == SOFTMARK &&
|
||||
(openfile->current != was_current ||
|
||||
openfile->current_x != was_x ||
|
||||
wanted_to_move(shortcut->func))) {
|
||||
openfile->mark = NULL;
|
||||
refresh_needed = TRUE;
|
||||
} else if (openfile->current != was_current)
|
||||
@@ -1710,15 +1769,19 @@ int do_input(bool allow_funcs)
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_WRAPPING
|
||||
/* If the cursor moved to another line, clear the prepend flag. */
|
||||
if (openfile->current->next != was_next)
|
||||
/* If the cursor moved to another line and this was not caused
|
||||
* by adding characters to the buffer, clear the prepend flag. */
|
||||
if (openfile->current->next != was_next &&
|
||||
shortcut->func != do_tab &&
|
||||
shortcut->func != do_verbatim_input)
|
||||
wrap_reset();
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
if (f && !f->viewok)
|
||||
if (!refresh_needed && !okay_for_view(shortcut))
|
||||
check_the_multis(openfile->current);
|
||||
#endif
|
||||
if (!refresh_needed && (s->scfunc == do_delete || s->scfunc == do_backspace))
|
||||
if (!refresh_needed && (shortcut->func == do_delete ||
|
||||
shortcut->func == do_backspace))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
}
|
||||
@@ -1731,60 +1794,6 @@ int do_input(bool allow_funcs)
|
||||
return input;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
/* Handle a mouse click on the edit window or the shortcut list. */
|
||||
int do_mouse(void)
|
||||
{
|
||||
int mouse_col, mouse_row;
|
||||
int retval = get_mouseinput(&mouse_col, &mouse_row, TRUE);
|
||||
|
||||
/* If the click is wrong or already handled, we're done. */
|
||||
if (retval != 0)
|
||||
return retval;
|
||||
|
||||
/* If the click was in the edit window, put the cursor in that spot. */
|
||||
if (wmouse_trafo(edit, &mouse_row, &mouse_col, FALSE)) {
|
||||
filestruct *current_save = openfile->current;
|
||||
ssize_t row_count = mouse_row - openfile->current_y;
|
||||
size_t leftedge;
|
||||
#ifndef NANO_TINY
|
||||
size_t current_x_save = openfile->current_x;
|
||||
bool sameline = (mouse_row == openfile->current_y);
|
||||
/* Whether the click was on the row where the cursor is. */
|
||||
|
||||
if (ISSET(SOFTWRAP))
|
||||
leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
else
|
||||
#endif
|
||||
leftedge = get_page_start(xplustabs());
|
||||
|
||||
/* Move current up or down to the row corresponding to mouse_row. */
|
||||
if (row_count < 0)
|
||||
go_back_chunks(-row_count, &openfile->current, &leftedge);
|
||||
else
|
||||
go_forward_chunks(row_count, &openfile->current, &leftedge);
|
||||
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
actual_last_column(leftedge, mouse_col));
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Clicking where the cursor is toggles the mark, as does clicking
|
||||
* beyond the line length with the cursor at the end of the line. */
|
||||
if (sameline && openfile->current_x == current_x_save)
|
||||
do_mark();
|
||||
else
|
||||
#endif
|
||||
/* The cursor moved; clean the cutbuffer on the next cut. */
|
||||
cutbuffer_reset();
|
||||
|
||||
edit_redraw(current_save, CENTERING);
|
||||
}
|
||||
|
||||
/* No more handling is needed. */
|
||||
return 2;
|
||||
}
|
||||
#endif /* ENABLE_MOUSE */
|
||||
|
||||
/* The user typed output_len multibyte characters. Add them to the edit
|
||||
* buffer, filtering out all ASCII control characters if allow_cntrls is
|
||||
* TRUE. */
|
||||
@@ -1883,7 +1892,8 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
check_the_multis(openfile->current);
|
||||
if (!refresh_needed)
|
||||
check_the_multis(openfile->current);
|
||||
#endif
|
||||
|
||||
if (!refresh_needed)
|
||||
@@ -1900,11 +1910,6 @@ int main(int argc, char **argv)
|
||||
#ifdef ENABLE_WRAPPING
|
||||
bool forced_wrapping = FALSE;
|
||||
/* Should long lines be automatically hard wrapped? */
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
bool is_multibuffer;
|
||||
/* The actual value of the multibuffer option, restored after
|
||||
* we've loaded all files given on the command line. */
|
||||
#endif
|
||||
const struct option long_options[] = {
|
||||
{"boldtext", 0, NULL, 'D'},
|
||||
@@ -1916,6 +1921,9 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
{"rebindkeypad", 0, NULL, 'K'},
|
||||
{"nonewlines", 0, NULL, 'L'},
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
{"trimblanks", 0, NULL, 'M'},
|
||||
#endif
|
||||
{"morespace", 0, NULL, 'O'},
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
{"quotestr", 1, NULL, 'Q'},
|
||||
@@ -1966,7 +1974,6 @@ int main(int argc, char **argv)
|
||||
{"locking", 0, NULL, 'G'},
|
||||
{"historylog", 0, NULL, 'H'},
|
||||
{"noconvert", 0, NULL, 'N'},
|
||||
{"poslog", 0, NULL, 'P'}, /* deprecated form, remove in 2018 */
|
||||
{"positionlog", 0, NULL, 'P'},
|
||||
{"smooth", 0, NULL, 'S'},
|
||||
{"wordbounds", 0, NULL, 'W'},
|
||||
@@ -1980,6 +1987,13 @@ int main(int argc, char **argv)
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
struct vt_stat dummy;
|
||||
|
||||
/* Check whether we're running on a Linux console. */
|
||||
on_a_vt = (ioctl(0, VT_GETSTATE, &dummy) == 0);
|
||||
#endif
|
||||
|
||||
/* Back up the terminal settings so that they can be restored. */
|
||||
tcgetattr(0, &oldterm);
|
||||
|
||||
@@ -2026,7 +2040,7 @@ int main(int argc, char **argv)
|
||||
|
||||
while ((optchr =
|
||||
getopt_long(argc, argv,
|
||||
"ABC:DEFGHIKLNOPQ:RST:UVWX:Y:abcdefghijklmno:pqr:s:tuvwxz$",
|
||||
"ABC:DEFGHIKLMNOPQ:RST:UVWX:Y:abcdefghijklmno:pqr:s:tuvwxz$",
|
||||
long_options, NULL)) != -1) {
|
||||
switch (optchr) {
|
||||
case 'b':
|
||||
@@ -2080,6 +2094,11 @@ int main(int argc, char **argv)
|
||||
case 'L':
|
||||
SET(NO_NEWLINES);
|
||||
break;
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
case 'M':
|
||||
SET(TRIM_BLANKS);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
case 'N':
|
||||
SET(NO_CONVERT);
|
||||
@@ -2468,14 +2487,21 @@ int main(int argc, char **argv)
|
||||
if (initscr() == NULL)
|
||||
exit(1);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
set_colorpairs();
|
||||
#else
|
||||
interface_color_pair[TITLE_BAR] = hilite_attribute;
|
||||
interface_color_pair[LINE_NUMBER] = hilite_attribute;
|
||||
interface_color_pair[SELECTED_TEXT] = hilite_attribute;
|
||||
interface_color_pair[STATUS_BAR] = hilite_attribute;
|
||||
interface_color_pair[ERROR_MESSAGE] = hilite_attribute;
|
||||
interface_color_pair[KEY_COMBO] = hilite_attribute;
|
||||
interface_color_pair[FUNCTION_TAG] = A_NORMAL;
|
||||
#endif
|
||||
|
||||
/* Set up the terminal state. */
|
||||
terminal_init();
|
||||
|
||||
#ifdef __linux__
|
||||
/* Check whether we're running on a Linux console. */
|
||||
console = (getenv("DISPLAY") == NULL);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Main: set up windows\n");
|
||||
#endif
|
||||
@@ -2494,17 +2520,6 @@ int main(int argc, char **argv)
|
||||
mouse_init();
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
set_colorpairs();
|
||||
#else
|
||||
interface_color_pair[TITLE_BAR] = hilite_attribute;
|
||||
interface_color_pair[LINE_NUMBER] = hilite_attribute;
|
||||
interface_color_pair[SELECTED_TEXT] = hilite_attribute;
|
||||
interface_color_pair[STATUS_BAR] = hilite_attribute;
|
||||
interface_color_pair[KEY_COMBO] = hilite_attribute;
|
||||
interface_color_pair[FUNCTION_TAG] = A_NORMAL;
|
||||
#endif
|
||||
|
||||
/* Ask ncurses for the key codes for Control+Left/Right/Up/Down. */
|
||||
controlleft = get_keycode("kLFT5", CONTROL_LEFT);
|
||||
controlright = get_keycode("kRIT5", CONTROL_RIGHT);
|
||||
@@ -2543,13 +2558,8 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "Main: open file\n");
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
is_multibuffer = ISSET(MULTIBUFFER);
|
||||
SET(MULTIBUFFER);
|
||||
#endif
|
||||
|
||||
/* Read the files mentioned on the command line into new buffers. */
|
||||
while (optind < argc && (!openfile || ISSET(MULTIBUFFER))) {
|
||||
while (optind < argc && (!openfile || read_them_all)) {
|
||||
ssize_t givenline = 0, givencol = 0;
|
||||
|
||||
/* If there's a +LINE[,COLUMN] argument here, eat it up. */
|
||||
@@ -2561,10 +2571,10 @@ int main(int argc, char **argv)
|
||||
/* If the filename is a dash, read from standard input; otherwise,
|
||||
* open the file; skip positioning the cursor if either failed. */
|
||||
if (strcmp(argv[optind], "-") == 0) {
|
||||
optind++;
|
||||
if (!scoop_stdin())
|
||||
continue;
|
||||
optind++;
|
||||
} else if (!open_buffer(argv[optind++], FALSE))
|
||||
} else if (!open_buffer(argv[optind++], TRUE))
|
||||
continue;
|
||||
|
||||
/* If a position was given on the command line, go there. */
|
||||
@@ -2584,15 +2594,12 @@ int main(int argc, char **argv)
|
||||
* directories, then open a blank buffer and allow editing. Otherwise,
|
||||
* switch from the last opened file to the next, that is: the first. */
|
||||
if (openfile == NULL) {
|
||||
open_buffer("", FALSE);
|
||||
open_buffer("", TRUE);
|
||||
UNSET(VIEW_MODE);
|
||||
}
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
else
|
||||
openfile = openfile->next;
|
||||
|
||||
if (!is_multibuffer)
|
||||
UNSET(MULTIBUFFER);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -2624,7 +2631,6 @@ int main(int argc, char **argv)
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (currmenu != MMAIN)
|
||||
display_main_list();
|
||||
|
||||
@@ -2651,7 +2657,4 @@ int main(int argc, char **argv)
|
||||
/* Read in and interpret keystrokes. */
|
||||
do_input(TRUE);
|
||||
}
|
||||
|
||||
/* We should never get here. */
|
||||
assert(FALSE);
|
||||
}
|
||||
|
||||
23
src/nano.h
23
src/nano.h
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* nano.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -142,6 +142,11 @@
|
||||
#define REPLACING 1
|
||||
#define INREGION 2
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
#define USE_THE_DEFAULT -1
|
||||
#define BAD_COLOR -2
|
||||
#endif
|
||||
|
||||
/* Enumeration types. */
|
||||
typedef enum {
|
||||
NIX_FILE, DOS_FILE, MAC_FILE
|
||||
@@ -163,8 +168,9 @@ typedef enum {
|
||||
CENTERING, FLOWING, STATIONARY
|
||||
} update_type;
|
||||
|
||||
/* The kinds of undo actions. ADD...REPLACE must come first. */
|
||||
typedef enum {
|
||||
ADD, DEL, BACK, CUT, CUT_TO_EOF, REPLACE,
|
||||
ADD, ENTER, BACK, DEL, JOIN, REPLACE,
|
||||
#ifdef ENABLE_WRAPPING
|
||||
SPLIT_BEGIN, SPLIT_END,
|
||||
#endif
|
||||
@@ -172,7 +178,7 @@ typedef enum {
|
||||
#ifdef ENABLE_COMMENT
|
||||
COMMENT, UNCOMMENT, PREFLIGHT,
|
||||
#endif
|
||||
JOIN, PASTE, INSERT, ENTER, OTHER
|
||||
CUT, CUT_TO_EOF, PASTE, INSERT, OTHER
|
||||
} undo_type;
|
||||
|
||||
/* Structure types. */
|
||||
@@ -407,10 +413,12 @@ typedef struct openfilestruct {
|
||||
colortype *colorstrings;
|
||||
/* The file's associated colors. */
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
struct openfilestruct *next;
|
||||
/* The next open file, if any. */
|
||||
struct openfilestruct *prev;
|
||||
/* The preceding open file, if any. */
|
||||
#endif
|
||||
} openfilestruct;
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
@@ -431,7 +439,7 @@ typedef struct sc {
|
||||
/* The integer that, together with meta, identifies the keystroke. */
|
||||
int menus;
|
||||
/* Which menus this applies to. */
|
||||
void (*scfunc)(void);
|
||||
void (*func)(void);
|
||||
/* The function we're going to run. */
|
||||
#ifndef NANO_TINY
|
||||
int toggle;
|
||||
@@ -439,13 +447,17 @@ typedef struct sc {
|
||||
int ordinal;
|
||||
/* The how-manieth toggle this is, in order to be able to
|
||||
* keep them in sequence. */
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
char *expansion;
|
||||
/* The string of keycodes to which this shortcut is expanded. */
|
||||
#endif
|
||||
struct sc *next;
|
||||
/* Next in the list. */
|
||||
} sc;
|
||||
|
||||
typedef struct subnfunc {
|
||||
void (*scfunc)(void);
|
||||
void (*func)(void);
|
||||
/* The actual function to call. */
|
||||
int menus;
|
||||
/* In what menus this function applies. */
|
||||
@@ -480,6 +492,7 @@ enum
|
||||
LINE_NUMBER,
|
||||
SELECTED_TEXT,
|
||||
STATUS_BAR,
|
||||
ERROR_MESSAGE,
|
||||
KEY_COMBO,
|
||||
FUNCTION_TAG,
|
||||
NUMBER_OF_ELEMENTS
|
||||
|
||||
179
src/prompt.c
179
src/prompt.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* prompt.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -28,11 +28,34 @@ static char *prompt = NULL;
|
||||
static size_t statusbar_x = HIGHEST_POSITIVE;
|
||||
/* The cursor position in answer. */
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
/* Handle a mouse click on the statusbar prompt or the shortcut list. */
|
||||
int do_statusbar_mouse(void)
|
||||
{
|
||||
int click_row, click_col;
|
||||
int retval = get_mouseinput(&click_row, &click_col, TRUE);
|
||||
|
||||
/* We can click on the statusbar window text to move the cursor. */
|
||||
if (retval == 0 && wmouse_trafo(bottomwin, &click_row, &click_col, FALSE)) {
|
||||
size_t start_col = strlenpt(prompt) + 2;
|
||||
|
||||
/* Move to where the click occurred. */
|
||||
if (click_row == 0 && click_col >= start_col) {
|
||||
statusbar_x = actual_x(answer,
|
||||
get_statusbar_page_start(start_col, start_col +
|
||||
statusbar_xplustabs()) + click_col - start_col);
|
||||
update_the_statusbar();
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read in a keystroke, interpret it if it is a shortcut or toggle, and
|
||||
* return it. Set ran_func to TRUE if we ran a function associated with
|
||||
* a shortcut key, and set finished to TRUE if we're done after running
|
||||
* return it. Set finished to TRUE if we're done after running
|
||||
* or trying to run a function associated with a shortcut key. */
|
||||
int do_statusbar_input(bool *ran_func, bool *finished)
|
||||
int do_statusbar_input(bool *finished)
|
||||
{
|
||||
int input;
|
||||
/* The character we read in. */
|
||||
@@ -40,11 +63,8 @@ int do_statusbar_input(bool *ran_func, bool *finished)
|
||||
/* The input buffer. */
|
||||
static size_t kbinput_len = 0;
|
||||
/* The length of the input buffer. */
|
||||
const sc *s;
|
||||
bool have_shortcut = FALSE;
|
||||
const subnfunc *f;
|
||||
const sc *shortcut;
|
||||
|
||||
*ran_func = FALSE;
|
||||
*finished = FALSE;
|
||||
|
||||
/* Read in a character. */
|
||||
@@ -67,15 +87,11 @@ int do_statusbar_input(bool *ran_func, bool *finished)
|
||||
#endif
|
||||
|
||||
/* Check for a shortcut in the current list. */
|
||||
s = get_shortcut(&input);
|
||||
|
||||
/* If we got a shortcut from the current list, or a "universal"
|
||||
* statusbar prompt shortcut, set have_shortcut to TRUE. */
|
||||
have_shortcut = (s != NULL);
|
||||
shortcut = get_shortcut(&input);
|
||||
|
||||
/* If we got a non-high-bit control key, a meta key sequence, or a
|
||||
* function key, and it's not a shortcut or toggle, throw it out. */
|
||||
if (!have_shortcut) {
|
||||
if (shortcut == NULL) {
|
||||
if (is_ascii_cntrl_char(input) || meta_key || !is_byte(input)) {
|
||||
beep();
|
||||
input = ERR;
|
||||
@@ -84,7 +100,7 @@ int do_statusbar_input(bool *ran_func, bool *finished)
|
||||
|
||||
/* If the keystroke isn't a shortcut nor a toggle, it's a normal text
|
||||
* character: add the it to the input buffer, when allowed. */
|
||||
if (input != ERR && !have_shortcut) {
|
||||
if (input != ERR && shortcut == NULL) {
|
||||
/* Only accept input when not in restricted mode, or when not at
|
||||
* the "Write File" prompt, or when there is no filename yet. */
|
||||
if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
|
||||
@@ -98,7 +114,7 @@ int do_statusbar_input(bool *ran_func, bool *finished)
|
||||
/* If we got a shortcut, or if there aren't any other keystrokes waiting
|
||||
* after the one we read in, we need to insert all the characters in the
|
||||
* input buffer (if not empty) into the answer. */
|
||||
if ((have_shortcut || get_key_buffer_len() == 0) && kbinput != NULL) {
|
||||
if ((shortcut || get_key_buffer_len() == 0) && kbinput != NULL) {
|
||||
/* Inject all characters in the input buffer at once, filtering out
|
||||
* control characters. */
|
||||
do_statusbar_output(kbinput, kbinput_len, TRUE);
|
||||
@@ -109,55 +125,54 @@ int do_statusbar_input(bool *ran_func, bool *finished)
|
||||
kbinput = NULL;
|
||||
}
|
||||
|
||||
if (have_shortcut) {
|
||||
if (s->scfunc == do_tab || s->scfunc == do_enter)
|
||||
if (shortcut) {
|
||||
if (shortcut->func == do_tab || shortcut->func == do_enter)
|
||||
;
|
||||
else if (s->scfunc == do_left)
|
||||
else if (shortcut->func == do_left)
|
||||
do_statusbar_left();
|
||||
else if (s->scfunc == do_right)
|
||||
else if (shortcut->func == do_right)
|
||||
do_statusbar_right();
|
||||
#ifndef NANO_TINY
|
||||
else if (s->scfunc == do_prev_word_void)
|
||||
else if (shortcut->func == do_prev_word_void)
|
||||
do_statusbar_prev_word();
|
||||
else if (s->scfunc == do_next_word_void)
|
||||
else if (shortcut->func == do_next_word_void)
|
||||
do_statusbar_next_word();
|
||||
#endif
|
||||
else if (s->scfunc == do_home)
|
||||
else if (shortcut->func == do_home)
|
||||
do_statusbar_home();
|
||||
else if (s->scfunc == do_end)
|
||||
else if (shortcut->func == do_end)
|
||||
do_statusbar_end();
|
||||
/* When in restricted mode at the "Write File" prompt and the
|
||||
* filename isn't blank, disallow any input and deletion. */
|
||||
else if (ISSET(RESTRICTED) && currmenu == MWRITEFILE &&
|
||||
openfile->filename[0] != '\0' &&
|
||||
(s->scfunc == do_verbatim_input ||
|
||||
s->scfunc == do_cut_text_void ||
|
||||
s->scfunc == do_delete ||
|
||||
s->scfunc == do_backspace))
|
||||
(shortcut->func == do_verbatim_input ||
|
||||
shortcut->func == do_cut_text_void ||
|
||||
shortcut->func == do_uncut_text ||
|
||||
shortcut->func == do_delete ||
|
||||
shortcut->func == do_backspace))
|
||||
;
|
||||
else if (s->scfunc == do_verbatim_input)
|
||||
#ifdef ENABLE_NANORC
|
||||
else if (shortcut->func == (functionptrtype)implant)
|
||||
implant(shortcut->expansion);
|
||||
#endif
|
||||
else if (shortcut->func == do_verbatim_input)
|
||||
do_statusbar_verbatim_input();
|
||||
else if (s->scfunc == do_cut_text_void)
|
||||
else if (shortcut->func == do_cut_text_void)
|
||||
do_statusbar_cut_text();
|
||||
else if (s->scfunc == do_delete)
|
||||
else if (shortcut->func == do_delete)
|
||||
do_statusbar_delete();
|
||||
else if (s->scfunc == do_backspace)
|
||||
else if (shortcut->func == do_backspace)
|
||||
do_statusbar_backspace();
|
||||
else if (s->scfunc == do_uncut_text) {
|
||||
else if (shortcut->func == do_uncut_text) {
|
||||
if (cutbuffer != NULL)
|
||||
do_statusbar_uncut_text();
|
||||
} else {
|
||||
/* Handle any other shortcut in the current menu, setting
|
||||
* ran_func to TRUE if we try to run their associated functions,
|
||||
* and setting finished to TRUE to indicatethat we're done after
|
||||
* running or trying to run their associated functions. */
|
||||
f = sctofunc(s);
|
||||
if (s->scfunc != NULL) {
|
||||
*ran_func = TRUE;
|
||||
if (f && (!ISSET(VIEW_MODE) || f->viewok) &&
|
||||
f->scfunc != do_gotolinecolumn_void)
|
||||
f->scfunc();
|
||||
}
|
||||
/* Handle any other shortcut in the current menu, setting finished
|
||||
* to TRUE to indicate that we're done after running or trying to
|
||||
* run its associated function. */
|
||||
if (!ISSET(VIEW_MODE) || okay_for_view(shortcut))
|
||||
shortcut->func();
|
||||
*finished = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -165,32 +180,6 @@ int do_statusbar_input(bool *ran_func, bool *finished)
|
||||
return input;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MOUSE
|
||||
/* Handle a mouse click on the statusbar prompt or the shortcut list. */
|
||||
int do_statusbar_mouse(void)
|
||||
{
|
||||
int mouse_x, mouse_y;
|
||||
int retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
|
||||
|
||||
/* We can click on the statusbar window text to move the cursor. */
|
||||
if (retval == 0 && wmouse_trafo(bottomwin, &mouse_y, &mouse_x, FALSE)) {
|
||||
size_t start_col;
|
||||
|
||||
start_col = strlenpt(prompt) + 2;
|
||||
|
||||
/* Move to where the click occurred. */
|
||||
if (mouse_x >= start_col && mouse_y == 0) {
|
||||
statusbar_x = actual_x(answer,
|
||||
get_statusbar_page_start(start_col, start_col +
|
||||
statusbar_xplustabs()) + mouse_x - start_col);
|
||||
update_the_statusbar();
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The user typed input_len multibyte characters. Add them to the answer,
|
||||
* filtering out ASCII control characters if filtering is TRUE. */
|
||||
void do_statusbar_output(int *the_input, size_t input_len,
|
||||
@@ -198,27 +187,25 @@ void do_statusbar_output(int *the_input, size_t input_len,
|
||||
{
|
||||
char *output = charalloc(input_len + 1);
|
||||
char onechar[MAXCHARLEN];
|
||||
int i, char_len;
|
||||
size_t char_len, i, j = 0;
|
||||
|
||||
/* Copy the typed stuff so it can be treated. */
|
||||
for (i = 0; i < input_len; i++)
|
||||
output[i] = (char)the_input[i];
|
||||
output[i] = '\0';
|
||||
|
||||
i = 0;
|
||||
|
||||
while (i < input_len) {
|
||||
while (j < input_len) {
|
||||
/* Encode any NUL byte as 0x0A. */
|
||||
if (output[i] == '\0')
|
||||
output[i] = '\n';
|
||||
if (output[j] == '\0')
|
||||
output[j] = '\n';
|
||||
|
||||
/* Interpret the next multibyte character. */
|
||||
char_len = parse_mbchar(output + i, onechar, NULL);
|
||||
char_len = parse_mbchar(output + j, onechar, NULL);
|
||||
|
||||
i += char_len;
|
||||
j += char_len;
|
||||
|
||||
/* When filtering, skip any ASCII control character. */
|
||||
if (filtering && is_ascii_cntrl_char(*(output + i - char_len)))
|
||||
if (filtering && is_ascii_cntrl_char(*(output + j - char_len)))
|
||||
continue;
|
||||
|
||||
/* Insert the typed character into the existing answer string. */
|
||||
@@ -356,6 +343,8 @@ void do_statusbar_verbatim_input(void)
|
||||
kbinput = get_verbatim_kbinput(bottomwin, &kbinput_len);
|
||||
|
||||
do_statusbar_output(kbinput, kbinput_len, FALSE);
|
||||
|
||||
free(kbinput);
|
||||
}
|
||||
|
||||
/* Return the zero-based column position of the cursor in the answer. */
|
||||
@@ -443,7 +432,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
void (*refresh_func)(void))
|
||||
{
|
||||
int kbinput = ERR;
|
||||
bool ran_func, finished;
|
||||
bool finished;
|
||||
functionptrtype func;
|
||||
#ifdef ENABLE_TABCOMP
|
||||
bool tabbed = FALSE;
|
||||
@@ -470,7 +459,7 @@ functionptrtype acquire_an_answer(int *actual, bool allow_tabs,
|
||||
update_the_statusbar();
|
||||
|
||||
while (TRUE) {
|
||||
kbinput = do_statusbar_input(&ran_func, &finished);
|
||||
kbinput = do_statusbar_input(&finished);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If the window size changed, go reformat the prompt string. */
|
||||
@@ -617,7 +606,8 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
||||
|
||||
bottombars(menu);
|
||||
|
||||
answer = mallocstrcpy(answer, curranswer);
|
||||
if (answer != curranswer || answer == NULL)
|
||||
answer = mallocstrcpy(answer, curranswer);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
redo_theprompt:
|
||||
@@ -669,19 +659,13 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
||||
int do_yesno_prompt(bool all, const char *msg)
|
||||
{
|
||||
int response = -2, width = 16;
|
||||
char *message = display_string(msg, 0, COLS, FALSE);
|
||||
|
||||
/* TRANSLATORS: For the next three strings, if possible, specify
|
||||
* the single-byte letters for both your language and English.
|
||||
* For example, in French: "OoYy", for both "Oui" and "Yes". */
|
||||
/* TRANSLATORS: For the next three strings, specify the single-byte
|
||||
* starting letters of the translations for "Yes", "No", and "All".
|
||||
* Of each string, the first letter is shown in the help lines. */
|
||||
const char *yesstr = _("Yy");
|
||||
const char *nostr = _("Nn");
|
||||
const char *allstr = _("Aa");
|
||||
|
||||
/* The above three variables consist of all the single-byte characters
|
||||
* that are accepted for the corresponding answer. Of each variable,
|
||||
* the first character is displayed in the help lines. */
|
||||
|
||||
while (response == -2) {
|
||||
int kbinput;
|
||||
|
||||
@@ -717,7 +701,7 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
/* Color the statusbar over its full width and display the question. */
|
||||
wattron(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
blank_statusbar();
|
||||
mvwaddnstr(bottomwin, 0, 0, message, actual_x(message, COLS - 1));
|
||||
mvwaddnstr(bottomwin, 0, 0, msg, actual_x(msg, COLS - 1));
|
||||
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
wnoutrefresh(bottomwin);
|
||||
|
||||
@@ -727,12 +711,21 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
kbinput = get_kbinput(bottomwin, !all);
|
||||
|
||||
/* See if the pressed key is in the Yes, No, or All strings. */
|
||||
#ifdef ENABLE_NLS
|
||||
if (strchr(yesstr, kbinput) != NULL)
|
||||
response = 1;
|
||||
else if (strchr(nostr, kbinput) != NULL)
|
||||
response = 0;
|
||||
else if (all && strchr(allstr, kbinput) != NULL)
|
||||
response = 2;
|
||||
else
|
||||
#endif
|
||||
if (strchr("Yy", kbinput) != NULL)
|
||||
response = 1;
|
||||
else if (strchr("Nn", kbinput) != NULL)
|
||||
response = 0;
|
||||
else if (all && strchr("Aa", kbinput) != NULL)
|
||||
response = 2;
|
||||
else if (func_from_key(&kbinput) == do_cancel)
|
||||
response = -1;
|
||||
#ifdef ENABLE_MOUSE
|
||||
@@ -755,7 +748,5 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
#endif /* ENABLE_MOUSE */
|
||||
}
|
||||
|
||||
free(message);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
62
src/proto.h
62
src/proto.h
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* proto.h -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -30,7 +30,7 @@ extern volatile sig_atomic_t the_window_resized;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
extern bool console;
|
||||
extern bool on_a_vt;
|
||||
#endif
|
||||
|
||||
extern bool meta_key;
|
||||
@@ -40,9 +40,6 @@ extern bool focusing;
|
||||
|
||||
extern bool as_an_at;
|
||||
|
||||
extern int margin;
|
||||
extern int editwincols;
|
||||
|
||||
extern bool suppress_cursorpos;
|
||||
|
||||
extern message_type lastmessage;
|
||||
@@ -91,10 +88,13 @@ extern char *last_search;
|
||||
extern char *present_path;
|
||||
|
||||
extern unsigned flags[4];
|
||||
|
||||
extern WINDOW *topwin;
|
||||
extern WINDOW *edit;
|
||||
extern WINDOW *bottomwin;
|
||||
extern int editwinrows;
|
||||
extern int editwincols;
|
||||
extern int margin;
|
||||
|
||||
extern filestruct *cutbuffer;
|
||||
extern filestruct *cutbottom;
|
||||
@@ -172,7 +172,7 @@ extern regmatch_t regmatches[10];
|
||||
|
||||
extern int hilite_attribute;
|
||||
#ifdef ENABLE_COLOR
|
||||
extern char* specified_color_combo[NUMBER_OF_ELEMENTS];
|
||||
extern colortype *color_combo[NUMBER_OF_ELEMENTS];
|
||||
#endif
|
||||
extern int interface_color_pair[NUMBER_OF_ELEMENTS];
|
||||
|
||||
@@ -267,7 +267,7 @@ void do_uncut_text(void);
|
||||
/* Most functions in files.c. */
|
||||
void initialize_buffer_text(void);
|
||||
void set_modified(void);
|
||||
bool open_buffer(const char *filename, bool undoable);
|
||||
bool open_buffer(const char *filename, bool new_buffer);
|
||||
#ifdef ENABLE_SPELLER
|
||||
void replace_buffer(const char *filename);
|
||||
#ifndef NANO_TINY
|
||||
@@ -281,8 +281,7 @@ void switch_to_prev_buffer(void);
|
||||
void switch_to_next_buffer(void);
|
||||
bool close_buffer(void);
|
||||
#endif
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable,
|
||||
bool checkwritable);
|
||||
void read_file(FILE *f, int fd, const char *filename, bool undoable);
|
||||
int open_file(const char *filename, bool newfie, bool quiet, FILE **f);
|
||||
char *get_next_filename(const char *name, const char *suffix);
|
||||
void do_insertfile_void(void);
|
||||
@@ -386,11 +385,9 @@ void do_prev_word_void(void);
|
||||
void do_next_word_void(void);
|
||||
void do_home(void);
|
||||
void do_end(void);
|
||||
void do_up(bool scroll_only);
|
||||
void do_down(bool scroll_only);
|
||||
void do_up_void(void);
|
||||
void do_down_void(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_up(void);
|
||||
void do_down(void);
|
||||
#ifdef ENABLE_HELP
|
||||
void do_scroll_up(void);
|
||||
void do_scroll_down(void);
|
||||
#endif
|
||||
@@ -404,7 +401,7 @@ void unlink_node(filestruct *fileptr);
|
||||
void delete_node(filestruct *fileptr);
|
||||
filestruct *copy_filestruct(const filestruct *src);
|
||||
void free_filestruct(filestruct *src);
|
||||
void renumber(filestruct *fileptr);
|
||||
void renumber(filestruct *line);
|
||||
partition *partition_filestruct(filestruct *top, size_t top_x,
|
||||
filestruct *bot, size_t bot_x);
|
||||
void unpartition_filestruct(partition **p);
|
||||
@@ -413,8 +410,10 @@ void extract_buffer(filestruct **file_top, filestruct **file_bot,
|
||||
void ingraft_buffer(filestruct *somebuffer);
|
||||
void copy_from_buffer(filestruct *somebuffer);
|
||||
openfilestruct *make_new_opennode(void);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void unlink_opennode(openfilestruct *fileptr);
|
||||
void delete_opennode(openfilestruct *fileptr);
|
||||
#endif
|
||||
void print_view_warning(void);
|
||||
void show_restricted_warning(void);
|
||||
#ifndef ENABLE_HELP
|
||||
@@ -422,7 +421,7 @@ void say_there_is_no_help(void);
|
||||
#endif
|
||||
void finish(void);
|
||||
void die(const char *msg, ...);
|
||||
void die_save_file(const char *die_filename, struct stat *die_stat);
|
||||
void emergency_save(const char *die_filename, struct stat *die_stat);
|
||||
void window_init(void);
|
||||
void do_exit(void);
|
||||
void close_and_go(void);
|
||||
@@ -434,23 +433,17 @@ RETSIGTYPE handle_sigwinch(int signal);
|
||||
void regenerate_screen(void);
|
||||
void allow_sigwinch(bool allow);
|
||||
void do_toggle(int flag);
|
||||
void do_toggle_void(void);
|
||||
void enable_signals(void);
|
||||
#endif
|
||||
void disable_flow_control(void);
|
||||
void enable_flow_control(void);
|
||||
void terminal_init(void);
|
||||
void unbound_key(int code);
|
||||
bool okay_for_view(const sc *shortcut);
|
||||
int do_input(bool allow_funcs);
|
||||
#ifdef ENABLE_MOUSE
|
||||
int do_mouse(void);
|
||||
#endif
|
||||
void do_output(char *output, size_t output_len, bool allow_cntrls);
|
||||
|
||||
/* Most functions in prompt.c. */
|
||||
#ifdef ENABLE_MOUSE
|
||||
int do_statusbar_mouse(void);
|
||||
#endif
|
||||
void do_statusbar_output(int *the_input, size_t input_len, bool filtering);
|
||||
void do_statusbar_home(void);
|
||||
void do_statusbar_end(void);
|
||||
@@ -477,7 +470,6 @@ int do_yesno_prompt(bool all, const char *msg);
|
||||
/* Most functions in rcfile.c. */
|
||||
#ifdef ENABLE_NANORC
|
||||
#ifdef ENABLE_COLOR
|
||||
bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright);
|
||||
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage);
|
||||
#endif
|
||||
void parse_rcfile(FILE *rcstream, bool syntax_only);
|
||||
@@ -485,22 +477,23 @@ void do_rcfiles(void);
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
/* Most functions in search.c. */
|
||||
void not_found_msg(const char *str);
|
||||
void search_replace_abort(void);
|
||||
void tidy_up_after_search(void);
|
||||
int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
size_t *match_len, bool skipone, const filestruct *begin, size_t begin_x);
|
||||
void do_search(void);
|
||||
void do_search_forward(void);
|
||||
void do_search_backward(void);
|
||||
void do_research(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_findprevious(void);
|
||||
void do_findnext(void);
|
||||
#endif
|
||||
void do_research(void);
|
||||
void not_found_msg(const char *str);
|
||||
void go_looking(void);
|
||||
ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
const filestruct *real_current, size_t *real_current_x);
|
||||
void do_replace(void);
|
||||
void ask_for_replacement(void);
|
||||
void goto_line_posx(ssize_t line, size_t pos_x);
|
||||
void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
bool interactive);
|
||||
@@ -527,7 +520,6 @@ void do_unindent(void);
|
||||
bool white_string(const char *s);
|
||||
#ifdef ENABLE_COMMENT
|
||||
void do_comment(void);
|
||||
bool comment_line(undo_type action, filestruct *f, const char *comment_seq);
|
||||
#endif
|
||||
void do_undo(void);
|
||||
void do_redo(void);
|
||||
@@ -624,9 +616,12 @@ void dump_filestruct(const filestruct *inptr);
|
||||
/* Most functions in winio.c. */
|
||||
void record_macro(void);
|
||||
void run_macro(void);
|
||||
void get_key_buffer(WINDOW *win);
|
||||
size_t get_key_buffer_len(void);
|
||||
void put_back(int keycode);
|
||||
void unget_kbinput(int kbinput, bool metakey);
|
||||
#ifdef ENABLE_NANORC
|
||||
void implant(const char *string);
|
||||
#endif
|
||||
int get_kbinput(WINDOW *win, bool showcursor);
|
||||
int parse_kbinput(WINDOW *win);
|
||||
int arrow_from_abcd(int kbinput);
|
||||
@@ -636,7 +631,7 @@ int get_control_kbinput(int kbinput);
|
||||
int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
|
||||
int *parse_verbatim_kbinput(WINDOW *win, size_t *count);
|
||||
#ifdef ENABLE_MOUSE
|
||||
int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
|
||||
int get_mouseinput(int *mouse_row, int *mouse_col, bool allow_shortcuts);
|
||||
#endif
|
||||
const sc *get_shortcut(int *kbinput);
|
||||
void blank_row(WINDOW *win, int y, int x, int n);
|
||||
@@ -663,7 +658,7 @@ bool line_needs_update(const size_t old_column, const size_t new_column);
|
||||
int go_back_chunks(int nrows, filestruct **line, size_t *leftedge);
|
||||
int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge);
|
||||
bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge);
|
||||
void edit_scroll(bool direction, int nrows);
|
||||
void edit_scroll(bool direction);
|
||||
#ifndef NANO_TINY
|
||||
size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
|
||||
bool *end_of_line);
|
||||
@@ -694,17 +689,17 @@ void do_credits(void);
|
||||
#endif
|
||||
|
||||
/* These are just name definitions. */
|
||||
void do_cancel(void);
|
||||
void case_sens_void(void);
|
||||
void regexp_void(void);
|
||||
void backwards_void(void);
|
||||
void flip_replace(void);
|
||||
void gototext_void(void);
|
||||
void flip_goto(void);
|
||||
#ifdef ENABLE_BROWSER
|
||||
void to_files_void(void);
|
||||
void goto_dir_void(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_toggle_void(void);
|
||||
void dos_format_void(void);
|
||||
void mac_format_void(void);
|
||||
void append_void(void);
|
||||
@@ -716,5 +711,6 @@ void flip_execute(void);
|
||||
void flip_newbuffer(void);
|
||||
#endif
|
||||
void discard_buffer(void);
|
||||
void do_cancel(void);
|
||||
|
||||
#endif /* !PROTO_H */
|
||||
|
||||
232
src/rcfile.c
232
src/rcfile.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* rcfile.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 2001-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2001-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014 Mike Frysinger *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* *
|
||||
@@ -31,7 +31,10 @@
|
||||
#ifdef ENABLE_NANORC
|
||||
|
||||
#ifndef RCFILE_NAME
|
||||
#define HOME_RC_NAME ".nanorc"
|
||||
#define RCFILE_NAME "nanorc"
|
||||
#else
|
||||
#define HOME_RC_NAME RCFILE_NAME
|
||||
#endif
|
||||
|
||||
static const rcoption rcopts[] = {
|
||||
@@ -42,7 +45,6 @@ static const rcoption rcopts[] = {
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
{"brackets", 0},
|
||||
#endif
|
||||
{"const", CONSTANT_SHOW}, /* deprecated form, remove in 2018 */
|
||||
{"constantshow", CONSTANT_SHOW},
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
{"fill", 0},
|
||||
@@ -67,7 +69,6 @@ static const rcoption rcopts[] = {
|
||||
{"operatingdir", 0},
|
||||
#endif
|
||||
#ifdef ENABLE_HISTORIES
|
||||
{"poslog", POS_HISTORY}, /* deprecated form, remove in 2018 */
|
||||
{"positionlog", POS_HISTORY},
|
||||
#endif
|
||||
{"preserve", PRESERVE},
|
||||
@@ -117,6 +118,7 @@ static const rcoption rcopts[] = {
|
||||
{"numbercolor", 0},
|
||||
{"selectedcolor", 0},
|
||||
{"statuscolor", 0},
|
||||
{"errorcolor", 0},
|
||||
{"keycolor", 0},
|
||||
{"functioncolor", 0},
|
||||
#endif
|
||||
@@ -188,30 +190,25 @@ char *parse_argument(char *ptr)
|
||||
const char *ptr_save = ptr;
|
||||
char *last_quote = NULL;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
if (*ptr != '"')
|
||||
return parse_next_word(ptr);
|
||||
|
||||
do {
|
||||
ptr++;
|
||||
if (*ptr == '"')
|
||||
while (*ptr != '\0') {
|
||||
if (*++ptr == '"')
|
||||
last_quote = ptr;
|
||||
} while (*ptr != '\0');
|
||||
}
|
||||
|
||||
if (last_quote == NULL) {
|
||||
if (*ptr == '\0')
|
||||
ptr = NULL;
|
||||
else
|
||||
*ptr++ = '\0';
|
||||
rcfile_error(N_("Argument '%s' has an unterminated \""), ptr_save);
|
||||
} else {
|
||||
*last_quote = '\0';
|
||||
ptr = last_quote + 1;
|
||||
return NULL;
|
||||
}
|
||||
if (ptr != NULL)
|
||||
while (isblank((unsigned char)*ptr))
|
||||
ptr++;
|
||||
|
||||
*last_quote = '\0';
|
||||
ptr = last_quote + 1;
|
||||
|
||||
while (isblank((unsigned char)*ptr))
|
||||
ptr++;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -220,19 +217,14 @@ char *parse_argument(char *ptr)
|
||||
* null-terminate it, and return a pointer to the /next/ word. */
|
||||
char *parse_next_regex(char *ptr)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
|
||||
/* Continue until the end of line, or until a " followed by a
|
||||
* blank character or the end of line. */
|
||||
while (*ptr != '\0' && (*ptr != '"' ||
|
||||
(*(ptr + 1) != '\0' && !isblank((unsigned char)ptr[1]))))
|
||||
ptr++;
|
||||
|
||||
assert(*ptr == '"' || *ptr == '\0');
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(
|
||||
N_("Regex strings must begin and end with a \" character"));
|
||||
rcfile_error(N_("Regex strings must begin and end with a \" character"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -270,13 +262,10 @@ bool nregcomp(const char *regex, int compile_flags)
|
||||
* line at ptr, and add it to the global linked list of color syntaxes. */
|
||||
void parse_syntax(char *ptr)
|
||||
{
|
||||
char *nameptr;
|
||||
/* A pointer to what should be the name of the syntax. */
|
||||
char *nameptr = ptr;
|
||||
|
||||
opensyntax = FALSE;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
/* Check that the syntax name is not empty. */
|
||||
if (*ptr == '\0' || (*ptr == '"' &&
|
||||
(*(ptr + 1) == '\0' || *(ptr + 1) == '"'))) {
|
||||
@@ -284,17 +273,19 @@ void parse_syntax(char *ptr)
|
||||
return;
|
||||
}
|
||||
|
||||
nameptr = ++ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
/* Check that the name starts and ends with a double quote. */
|
||||
if (*(nameptr - 1) != '\x22' || nameptr[strlen(nameptr) - 1] != '\x22') {
|
||||
rcfile_error(N_("A syntax name must be quoted"));
|
||||
/* Check that quotes around the name are either paired or absent. */
|
||||
if ((*nameptr == '\x22') ^ (nameptr[strlen(nameptr) - 1] == '\x22')) {
|
||||
rcfile_error(N_("Unpaired quote in syntax name"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Strip the end quote. */
|
||||
nameptr[strlen(nameptr) - 1] = '\0';
|
||||
/* If the name is quoted, strip the quotes. */
|
||||
if (*nameptr == '\x22') {
|
||||
nameptr++;
|
||||
nameptr[strlen(nameptr) - 1] = '\0';
|
||||
}
|
||||
|
||||
/* Redefining the "none" syntax is not allowed. */
|
||||
if (strcmp(nameptr, "none") == 0) {
|
||||
@@ -329,8 +320,7 @@ void parse_syntax(char *ptr)
|
||||
|
||||
/* The default syntax should have no associated extensions. */
|
||||
if (strcmp(live_syntax->name, "default") == 0 && *ptr != '\0') {
|
||||
rcfile_error(
|
||||
N_("The \"default\" syntax does not accept extensions"));
|
||||
rcfile_error(N_("The \"default\" syntax does not accept extensions"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -340,22 +330,17 @@ void parse_syntax(char *ptr)
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* Check whether the given executable function is "universal" (meaning
|
||||
* any horizontal movement or deletion) and thus is present in almost
|
||||
* all menus. */
|
||||
/* Return TRUE when the given function is present in almost all menus. */
|
||||
bool is_universal(void (*func)(void))
|
||||
{
|
||||
if (func == do_left || func == do_right ||
|
||||
return (func == do_left || func == do_right ||
|
||||
func == do_home || func == do_end ||
|
||||
#ifndef NANO_TINY
|
||||
func == do_prev_word_void || func == do_next_word_void ||
|
||||
#endif
|
||||
func == do_delete || func == do_backspace ||
|
||||
func == do_cut_text_void || func == do_uncut_text ||
|
||||
func == do_tab || func == do_enter || func == do_verbatim_input)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
func == do_tab || func == do_enter || func == do_verbatim_input);
|
||||
}
|
||||
|
||||
/* Bind or unbind a key combo, to or from a function. */
|
||||
@@ -365,8 +350,6 @@ void parse_binding(char *ptr, bool dobind)
|
||||
sc *s, *newsc = NULL;
|
||||
int menu;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting the rebinding code...\n");
|
||||
#endif
|
||||
@@ -411,7 +394,7 @@ void parse_binding(char *ptr, bool dobind)
|
||||
|
||||
if (dobind) {
|
||||
funcptr = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
ptr = parse_argument(ptr);
|
||||
|
||||
if (funcptr[0] == '\0') {
|
||||
rcfile_error(N_("Must specify a function to bind the key to"));
|
||||
@@ -429,7 +412,18 @@ void parse_binding(char *ptr, bool dobind)
|
||||
}
|
||||
|
||||
if (dobind) {
|
||||
newsc = strtosc(funcptr);
|
||||
/* If the thing to bind starts with a double quote, it is a string,
|
||||
* otherwise it is the name of a function. */
|
||||
if (*funcptr == '"') {
|
||||
newsc = nmalloc(sizeof(sc));
|
||||
newsc->func = (functionptrtype)implant;
|
||||
newsc->expansion = mallocstrcpy(NULL, funcptr + 1);
|
||||
#ifndef NANO_TINY
|
||||
newsc->toggle = 0;
|
||||
#endif
|
||||
} else
|
||||
newsc = strtosc(funcptr);
|
||||
|
||||
if (newsc == NULL) {
|
||||
rcfile_error(N_("Cannot map name \"%s\" to a function"), funcptr);
|
||||
goto free_things;
|
||||
@@ -448,20 +442,21 @@ void parse_binding(char *ptr, bool dobind)
|
||||
|
||||
/* Tally up the menus where the function exists. */
|
||||
for (f = allfuncs; f != NULL; f = f->next)
|
||||
if (f->scfunc == newsc->scfunc)
|
||||
if (f->func == newsc->func)
|
||||
mask = mask | f->menus;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Handle the special case of the toggles. */
|
||||
if (newsc->scfunc == do_toggle_void)
|
||||
if (newsc->func == do_toggle_void)
|
||||
mask = MMAIN;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
/* Handle the special case of a key defined as a string. */
|
||||
if (newsc->func == (functionptrtype)implant)
|
||||
mask = MMOST | MHELP;
|
||||
#endif
|
||||
/* Now limit the given menu to those where the function exists. */
|
||||
if (is_universal(newsc->scfunc))
|
||||
menu = menu & MMOST;
|
||||
else
|
||||
menu = menu & mask;
|
||||
menu = menu & (is_universal(newsc->func) ? MMOST : mask);
|
||||
|
||||
if (!menu) {
|
||||
rcfile_error(N_("Function '%s' does not exist in menu '%s'"), funcptr, menuptr);
|
||||
@@ -487,9 +482,9 @@ void parse_binding(char *ptr, bool dobind)
|
||||
if (dobind) {
|
||||
#ifndef NANO_TINY
|
||||
/* If this is a toggle, copy its sequence number. */
|
||||
if (newsc->scfunc == do_toggle_void) {
|
||||
if (newsc->func == do_toggle_void) {
|
||||
for (s = sclist; s != NULL; s = s->next)
|
||||
if (s->scfunc == do_toggle_void && s->toggle == newsc->toggle)
|
||||
if (s->func == do_toggle_void && s->toggle == newsc->toggle)
|
||||
newsc->ordinal = s->ordinal;
|
||||
} else
|
||||
newsc->ordinal = 0;
|
||||
@@ -591,7 +586,8 @@ short color_to_short(const char *colorname, bool *bright)
|
||||
if (strncasecmp(colorname, "bright", 6) == 0) {
|
||||
*bright = TRUE;
|
||||
colorname += 6;
|
||||
}
|
||||
} else
|
||||
*bright = FALSE;
|
||||
|
||||
if (strcasecmp(colorname, "green") == 0)
|
||||
return COLOR_GREEN;
|
||||
@@ -609,13 +605,39 @@ short color_to_short(const char *colorname, bool *bright)
|
||||
return COLOR_MAGENTA;
|
||||
else if (strcasecmp(colorname, "black") == 0)
|
||||
return COLOR_BLACK;
|
||||
else if (strcasecmp(colorname, "normal") == 0)
|
||||
return USE_THE_DEFAULT;
|
||||
|
||||
rcfile_error(N_("Color \"%s\" not understood.\n"
|
||||
"Valid colors are \"green\", \"red\", \"blue\",\n"
|
||||
"\"white\", \"yellow\", \"cyan\", \"magenta\" and\n"
|
||||
"\"black\", with the optional prefix \"bright\"\n"
|
||||
"for foreground colors."), colorname);
|
||||
return -1;
|
||||
rcfile_error(N_("Color \"%s\" not understood"), colorname);
|
||||
return BAD_COLOR;
|
||||
}
|
||||
|
||||
/* Parse the color name (or pair of color names) in the given string.
|
||||
* Return FALSE when any color name is invalid; otherwise return TRUE. */
|
||||
bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright)
|
||||
{
|
||||
char *comma = strchr(combostr, ',');
|
||||
|
||||
if (comma != NULL) {
|
||||
*bg = color_to_short(comma + 1, bright);
|
||||
if (*bright) {
|
||||
rcfile_error(N_("A background color cannot be bright"));
|
||||
return FALSE;
|
||||
}
|
||||
if (*bg == BAD_COLOR)
|
||||
return FALSE;
|
||||
*comma = '\0';
|
||||
} else
|
||||
*bg = USE_THE_DEFAULT;
|
||||
|
||||
if (comma != combostr) {
|
||||
*fg = color_to_short(combostr, bright);
|
||||
if (*fg == BAD_COLOR)
|
||||
return FALSE;
|
||||
} else
|
||||
*fg = USE_THE_DEFAULT;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Parse the color string in the line at ptr, and add it to the current
|
||||
@@ -624,13 +646,12 @@ short color_to_short(const char *colorname, bool *bright)
|
||||
void parse_colors(char *ptr, int rex_flags)
|
||||
{
|
||||
short fg, bg;
|
||||
bool bright = FALSE;
|
||||
bool bright;
|
||||
char *item;
|
||||
|
||||
if (!opensyntax) {
|
||||
rcfile_error(
|
||||
N_("A '%s' command requires a preceding 'syntax' command"),
|
||||
"color");
|
||||
rcfile_error(N_("A '%s' command requires a preceding 'syntax' command"),
|
||||
"color");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -665,8 +686,7 @@ void parse_colors(char *ptr, int rex_flags)
|
||||
}
|
||||
|
||||
if (*ptr != '"') {
|
||||
rcfile_error(
|
||||
N_("Regex strings must begin and end with a \" character"));
|
||||
rcfile_error(N_("Regex strings must begin and end with a \" character"));
|
||||
ptr = parse_next_regex(ptr);
|
||||
continue;
|
||||
}
|
||||
@@ -747,31 +767,19 @@ void parse_colors(char *ptr, int rex_flags)
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the color name, or pair of color names, in combostr. */
|
||||
bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright)
|
||||
/* Parse the argument of an interface color option. */
|
||||
colortype *parse_interface_color(char *combostr)
|
||||
{
|
||||
char *comma = strchr(combostr, ',');
|
||||
colortype *trio = nmalloc(sizeof(colortype));
|
||||
|
||||
if (comma != NULL) {
|
||||
*bg = color_to_short(comma + 1, bright);
|
||||
if (*bright) {
|
||||
rcfile_error(N_("A background color cannot be bright"));
|
||||
return FALSE;
|
||||
}
|
||||
*comma = '\0';
|
||||
} else
|
||||
*bg = -1;
|
||||
|
||||
if (comma != combostr) {
|
||||
*fg = color_to_short(combostr, bright);
|
||||
|
||||
/* If the specified foreground color is bad, ignore the regexes. */
|
||||
if (*fg == -1)
|
||||
return FALSE;
|
||||
} else
|
||||
*fg = -1;
|
||||
|
||||
return TRUE;
|
||||
if (parse_color_names(combostr, &trio->fg, &trio->bg, &trio->bright)) {
|
||||
free(combostr);
|
||||
return trio;
|
||||
} else {
|
||||
free(combostr);
|
||||
free(trio);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read regex strings enclosed in double quotes from the line pointed at
|
||||
@@ -810,8 +818,7 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
|
||||
regexlisttype *newthing;
|
||||
|
||||
if (*ptr != '"') {
|
||||
rcfile_error(
|
||||
N_("Regex strings must begin and end with a \" character"));
|
||||
rcfile_error(N_("Regex strings must begin and end with a \" character"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -841,8 +848,6 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
|
||||
/* Gather and store the string after a comment/linter/formatter command. */
|
||||
void pick_up_name(const char *kind, char *ptr, char **storage)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
|
||||
if (!opensyntax) {
|
||||
rcfile_error(
|
||||
N_("A '%s' command requires a preceding 'syntax' command"), kind);
|
||||
@@ -856,17 +861,17 @@ void pick_up_name(const char *kind, char *ptr, char **storage)
|
||||
|
||||
/* If the argument starts with a quote, find the terminating quote. */
|
||||
if (*ptr == '"') {
|
||||
char *look = ++ptr;
|
||||
|
||||
look += strlen(ptr);
|
||||
char *look = ptr + strlen(ptr);
|
||||
|
||||
while (*look != '"') {
|
||||
if (--look < ptr) {
|
||||
if (--look == ptr) {
|
||||
rcfile_error(N_("Argument of '%s' lacks closing \""), kind);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*look = '\0';
|
||||
ptr++;
|
||||
}
|
||||
|
||||
*storage = mallocstrcpy(*storage, ptr);
|
||||
@@ -885,8 +890,8 @@ static void check_vitals_mapped(void)
|
||||
|
||||
for (v = 0; v < VITALS; v++) {
|
||||
for (f = allfuncs; f != NULL; f = f->next) {
|
||||
if (f->scfunc == vitals[v] && f->menus & inmenus[v]) {
|
||||
const sc *s = first_sc_for(inmenus[v], f->scfunc);
|
||||
if (f->func == vitals[v] && f->menus & inmenus[v]) {
|
||||
const sc *s = first_sc_for(inmenus[v], f->func);
|
||||
if (!s) {
|
||||
fprintf(stderr, _("Fatal error: no keys mapped for function "
|
||||
"\"%s\". Exiting.\n"), f->desc);
|
||||
@@ -1086,17 +1091,19 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (strcasecmp(rcopts[i].name, "titlecolor") == 0)
|
||||
specified_color_combo[TITLE_BAR] = option;
|
||||
color_combo[TITLE_BAR] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "numbercolor") == 0)
|
||||
specified_color_combo[LINE_NUMBER] = option;
|
||||
color_combo[LINE_NUMBER] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "selectedcolor") == 0)
|
||||
specified_color_combo[SELECTED_TEXT] = option;
|
||||
color_combo[SELECTED_TEXT] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "statuscolor") == 0)
|
||||
specified_color_combo[STATUS_BAR] = option;
|
||||
color_combo[STATUS_BAR] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "errorcolor") == 0)
|
||||
color_combo[ERROR_MESSAGE] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "keycolor") == 0)
|
||||
specified_color_combo[KEY_COMBO] = option;
|
||||
color_combo[KEY_COMBO] = parse_interface_color(option);
|
||||
else if (strcasecmp(rcopts[i].name, "functioncolor") == 0)
|
||||
specified_color_combo[FUNCTION_TAG] = option;
|
||||
color_combo[FUNCTION_TAG] = parse_interface_color(option);
|
||||
else
|
||||
#endif
|
||||
#ifdef ENABLE_OPERATINGDIR
|
||||
@@ -1175,8 +1182,7 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
|
||||
tabsize = -1;
|
||||
}
|
||||
free(option);
|
||||
} else
|
||||
assert(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
@@ -1249,7 +1255,7 @@ void do_rcfiles(void)
|
||||
|
||||
/* Now try the to find a nanorc file in the user's home directory
|
||||
* or in the XDG configuration directories. */
|
||||
if (have_nanorc(homedir, "/." RCFILE_NAME))
|
||||
if (have_nanorc(homedir, "/" HOME_RC_NAME))
|
||||
parse_one_nanorc();
|
||||
else if (have_nanorc(xdgconfdir, "/nano/" RCFILE_NAME))
|
||||
parse_one_nanorc();
|
||||
|
||||
348
src/search.c
348
src/search.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* search.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2015-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -28,8 +28,8 @@
|
||||
|
||||
static bool came_full_circle = FALSE;
|
||||
/* Have we reached the starting line again while searching? */
|
||||
static bool regexp_compiled = FALSE;
|
||||
/* Have we compiled any regular expressions? */
|
||||
static bool have_compiled_regexp = FALSE;
|
||||
/* Whether we have compiled a regular expression for the search. */
|
||||
|
||||
/* Compile the given regular expression and store it in search_regexp.
|
||||
* Return TRUE if the expression is valid, and FALSE otherwise. */
|
||||
@@ -50,152 +50,122 @@ bool regexp_init(const char *regexp)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
regexp_compiled = TRUE;
|
||||
have_compiled_regexp = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Decompile the compiled regular expression we used in the last
|
||||
* search, if any. */
|
||||
void regexp_cleanup(void)
|
||||
/* Free a compiled regular expression, if one was compiled; and schedule a
|
||||
* full screen refresh when the mark is on, in case the cursor has moved. */
|
||||
void tidy_up_after_search(void)
|
||||
{
|
||||
if (regexp_compiled) {
|
||||
regexp_compiled = FALSE;
|
||||
if (have_compiled_regexp) {
|
||||
regfree(&search_regexp);
|
||||
have_compiled_regexp = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Report on the status bar that the given string was not found. */
|
||||
void not_found_msg(const char *str)
|
||||
{
|
||||
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE);
|
||||
size_t numchars = actual_x(disp, strnlenpt(disp, COLS / 2));
|
||||
|
||||
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
|
||||
(disp[numchars] == '\0') ? "" : "...");
|
||||
free(disp);
|
||||
}
|
||||
|
||||
/* Abort the current search or replace. Clean up by displaying the main
|
||||
* shortcut list, updating the screen if the mark was on before, and
|
||||
* decompiling the compiled regular expression we used in the last
|
||||
* search, if any. */
|
||||
void search_replace_abort(void)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->mark)
|
||||
refresh_needed = TRUE;
|
||||
#endif
|
||||
regexp_cleanup();
|
||||
}
|
||||
|
||||
/* Set up the system variables for a search or replace. If use_answer
|
||||
* is TRUE, only set backupstring to answer. Return -2 to run the
|
||||
* opposite program (search -> replace, replace -> search), return -1 if
|
||||
* the search should be canceled (due to Cancel, a blank search string,
|
||||
* Go to Line, or a failed regcomp()), return 0 on success, and return 1
|
||||
* on rerun calling program.
|
||||
*
|
||||
* replacing is TRUE if we call from do_replace(), and FALSE if called
|
||||
* from do_search(). */
|
||||
int search_init(bool replacing, bool use_answer)
|
||||
/* Prepare the prompt and ask the user what to search for. Keep looping
|
||||
* as long as the user presses a toggle, and only take action and exit
|
||||
* when <Enter> is pressed or a non-toggle shortcut was executed. */
|
||||
void search_init(bool replacing, bool keep_the_answer)
|
||||
{
|
||||
int i = 0;
|
||||
char *buf;
|
||||
static char *backupstring = NULL;
|
||||
/* The search string we'll be using. */
|
||||
functionptrtype func;
|
||||
char *thedefault;
|
||||
/* What will be searched for when the user typed nothing. */
|
||||
|
||||
/* If use_answer is TRUE, set backupstring to answer and get out. */
|
||||
if (use_answer) {
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We display the search prompt below. If the user types a partial
|
||||
* search string and then Replace or a toggle, we will return to
|
||||
* do_search() or do_replace() and be called again. In that case,
|
||||
* we should put the same search string back up. */
|
||||
/* When starting a new search, clear the current answer. */
|
||||
if (!keep_the_answer)
|
||||
answer = mallocstrcpy(answer, NULL);
|
||||
|
||||
/* If something was searched for earlier, include it in the prompt. */
|
||||
if (*last_search != '\0') {
|
||||
char *disp = display_string(last_search, 0, COLS / 3, FALSE);
|
||||
|
||||
buf = charalloc(strlen(disp) + 7);
|
||||
thedefault = charalloc(strlen(disp) + 7);
|
||||
/* We use (COLS / 3) here because we need to see more on the line. */
|
||||
sprintf(buf, " [%s%s]", disp,
|
||||
sprintf(thedefault, " [%s%s]", disp,
|
||||
(strlenpt(last_search) > COLS / 3) ? "..." : "");
|
||||
free(disp);
|
||||
} else
|
||||
buf = mallocstrcpy(NULL, "");
|
||||
thedefault = mallocstrcpy(NULL, "");
|
||||
|
||||
/* This is now one simple call. It just does a lot. */
|
||||
i = do_prompt(FALSE, FALSE,
|
||||
inhelp ? MFINDINHELP : (replacing ? MREPLACE : MWHEREIS),
|
||||
backupstring, &search_history,
|
||||
/* TRANSLATORS: This is the main search prompt. */
|
||||
edit_refresh, "%s%s%s%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: The next three modify the search prompt. */
|
||||
ISSET(CASE_SENSITIVE) ? _(" [Case Sensitive]") : "",
|
||||
ISSET(USE_REGEXP) ? _(" [Regexp]") : "",
|
||||
ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") : "", replacing ?
|
||||
while (TRUE) {
|
||||
functionptrtype func;
|
||||
/* Ask the user what to search for (or replace). */
|
||||
int i = do_prompt(FALSE, FALSE,
|
||||
inhelp ? MFINDINHELP : (replacing ? MREPLACE : MWHEREIS),
|
||||
answer, &search_history,
|
||||
/* TRANSLATORS: This is the main search prompt. */
|
||||
edit_refresh, "%s%s%s%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: The next three modify the search prompt. */
|
||||
ISSET(CASE_SENSITIVE) ? _(" [Case Sensitive]") : "",
|
||||
ISSET(USE_REGEXP) ? _(" [Regexp]") : "",
|
||||
ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") : "", replacing ?
|
||||
#ifndef NANO_TINY
|
||||
/* TRANSLATORS: The next two modify the search prompt. */
|
||||
openfile->mark ? _(" (to replace) in selection") :
|
||||
/* TRANSLATORS: The next two modify the search prompt. */
|
||||
openfile->mark ? _(" (to replace) in selection") :
|
||||
#endif
|
||||
_(" (to replace)") : "", buf);
|
||||
_(" (to replace)") : "", thedefault);
|
||||
|
||||
/* Release buf now that we don't need it anymore. */
|
||||
free(buf);
|
||||
|
||||
free(backupstring);
|
||||
backupstring = NULL;
|
||||
|
||||
/* 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')) {
|
||||
statusbar(_("Cancelled"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If Enter was pressed, see what we got. */
|
||||
if (i == 0 || i == -2) {
|
||||
/* If an answer was given, remember it. */
|
||||
if (*answer != '\0') {
|
||||
last_search = mallocstrcpy(last_search, answer);
|
||||
#ifdef ENABLE_HISTORIES
|
||||
update_history(&search_history, answer);
|
||||
#endif
|
||||
/* 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')) {
|
||||
statusbar(_("Cancelled"));
|
||||
tidy_up_after_search();
|
||||
free(thedefault);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If Enter was pressed, prepare to do a replace or a search. */
|
||||
if (i == 0 || i == -2) {
|
||||
/* If an actual answer was typed, remember it. */
|
||||
if (*answer != '\0') {
|
||||
last_search = mallocstrcpy(last_search, answer);
|
||||
#ifdef ENABLE_HISTORIES
|
||||
update_history(&search_history, answer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* When not doing a regular-expression search, just search;
|
||||
* otherwise compile the search string, and only search when
|
||||
* the expression is valid. */
|
||||
if (!ISSET(USE_REGEXP) || regexp_init(last_search)) {
|
||||
if (replacing)
|
||||
ask_for_replacement();
|
||||
else
|
||||
go_looking();
|
||||
}
|
||||
|
||||
tidy_up_after_search();
|
||||
free(thedefault);
|
||||
return;
|
||||
}
|
||||
|
||||
func = func_from_key(&i);
|
||||
|
||||
/* If we're here, one of the five toggles was pressed, or
|
||||
* a shortcut was executed. */
|
||||
if (func == case_sens_void) {
|
||||
TOGGLE(CASE_SENSITIVE);
|
||||
} else if (func == backwards_void) {
|
||||
TOGGLE(BACKWARDS_SEARCH);
|
||||
} else if (func == regexp_void) {
|
||||
TOGGLE(USE_REGEXP);
|
||||
} else if (func == flip_replace) {
|
||||
replacing = !replacing;
|
||||
} else {
|
||||
if (func == flip_goto)
|
||||
do_gotolinecolumn(openfile->current->lineno,
|
||||
openfile->placewewant + 1, TRUE, TRUE);
|
||||
tidy_up_after_search();
|
||||
free(thedefault);
|
||||
return;
|
||||
}
|
||||
if (ISSET(USE_REGEXP) && !regexp_init(last_search))
|
||||
return -1;
|
||||
else
|
||||
return 0; /* We have a valid string or regex. */
|
||||
}
|
||||
|
||||
func = func_from_key(&i);
|
||||
|
||||
if (func == case_sens_void) {
|
||||
TOGGLE(CASE_SENSITIVE);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
} else if (func == backwards_void) {
|
||||
TOGGLE(BACKWARDS_SEARCH);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
} else if (func == regexp_void) {
|
||||
TOGGLE(USE_REGEXP);
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return 1;
|
||||
} else if (func == flip_replace) {
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return -2; /* Call the opposite search function. */
|
||||
} else if (func == do_gotolinecolumn_void) {
|
||||
do_gotolinecolumn(openfile->current->lineno,
|
||||
openfile->placewewant + 1, TRUE, TRUE);
|
||||
return 3;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Look for needle, starting at (current, current_x). begin is the line
|
||||
@@ -235,7 +205,7 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
lastkbcheck = time(NULL);
|
||||
|
||||
/* Consume all waiting keystrokes until a Cancel. */
|
||||
while (input) {
|
||||
while (input != ERR) {
|
||||
if (func_from_key(&input) == do_cancel) {
|
||||
statusbar(_("Cancelled"));
|
||||
enable_waiting();
|
||||
@@ -250,24 +220,19 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
statusbar(_("Searching..."));
|
||||
}
|
||||
|
||||
/* Search for the needle in the current line. */
|
||||
if (!skipone)
|
||||
found = strstrwrapper(line->data, needle, from);
|
||||
|
||||
/* Ignore the initial match at the starting position: continue
|
||||
* searching from the next character, or invalidate the match. */
|
||||
if (skipone || (!whole_word_only && !came_full_circle &&
|
||||
found == begin->data + begin_x)) {
|
||||
/* When starting a new search, skip the first character, then
|
||||
* (in either case) search for the needle in the current line. */
|
||||
if (skipone) {
|
||||
skipone = FALSE;
|
||||
if (ISSET(BACKWARDS_SEARCH) && from != line->data) {
|
||||
from = line->data + move_mbleft(line->data, from - line->data);
|
||||
continue;
|
||||
found = strstrwrapper(line->data, needle, from);
|
||||
} else if (!ISSET(BACKWARDS_SEARCH) && *from != '\0') {
|
||||
from += move_mbright(from, 0);
|
||||
continue;
|
||||
found = strstrwrapper(line->data, needle, from);
|
||||
}
|
||||
found = NULL;
|
||||
}
|
||||
} else
|
||||
found = strstrwrapper(line->data, needle, from);
|
||||
|
||||
if (found != NULL) {
|
||||
/* When doing a regex search, compute the length of the match. */
|
||||
@@ -333,7 +298,8 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
enable_waiting();
|
||||
|
||||
/* Ensure that the found occurrence is not beyond the starting x. */
|
||||
if (came_full_circle && ((!ISSET(BACKWARDS_SEARCH) && found_x > begin_x) ||
|
||||
if (came_full_circle && ((!ISSET(BACKWARDS_SEARCH) && (found_x > begin_x ||
|
||||
(modus == REPLACING && found_x == begin_x))) ||
|
||||
(ISSET(BACKWARDS_SEARCH) && found_x < begin_x)))
|
||||
return 0;
|
||||
|
||||
@@ -357,17 +323,7 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
/* Ask what to search for and then go looking for it. */
|
||||
void do_search(void)
|
||||
{
|
||||
int i = search_init(FALSE, FALSE);
|
||||
|
||||
if (i == -1) /* Cancelled, or some other exit reason. */
|
||||
search_replace_abort();
|
||||
else if (i == -2) /* Do a replace instead. */
|
||||
do_replace();
|
||||
else if (i == 1) /* Toggled something. */
|
||||
do_search();
|
||||
|
||||
if (i == 0)
|
||||
go_looking();
|
||||
search_init(FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* Search forward for a string. */
|
||||
@@ -384,22 +340,6 @@ void do_search_backward(void)
|
||||
do_search();
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Search in the backward direction for the next occurrence. */
|
||||
void do_findprevious(void)
|
||||
{
|
||||
SET(BACKWARDS_SEARCH);
|
||||
do_research();
|
||||
}
|
||||
|
||||
/* Search in the forward direction for the next occurrence. */
|
||||
void do_findnext(void)
|
||||
{
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
do_research();
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Search for the last string without prompting. */
|
||||
void do_research(void)
|
||||
{
|
||||
@@ -422,6 +362,35 @@ void do_research(void)
|
||||
currmenu = MWHEREIS;
|
||||
|
||||
go_looking();
|
||||
|
||||
tidy_up_after_search();
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Search in the backward direction for the next occurrence. */
|
||||
void do_findprevious(void)
|
||||
{
|
||||
SET(BACKWARDS_SEARCH);
|
||||
do_research();
|
||||
}
|
||||
|
||||
/* Search in the forward direction for the next occurrence. */
|
||||
void do_findnext(void)
|
||||
{
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
do_research();
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Report on the status bar that the given string was not found. */
|
||||
void not_found_msg(const char *str)
|
||||
{
|
||||
char *disp = display_string(str, 0, (COLS / 2) + 1, FALSE);
|
||||
size_t numchars = actual_x(disp, strnlenpt(disp, COLS / 2));
|
||||
|
||||
statusline(HUSH, _("\"%.*s%s\" not found"), numchars, disp,
|
||||
(disp[numchars] == '\0') ? "" : "...");
|
||||
free(disp);
|
||||
}
|
||||
|
||||
/* Search for the global string 'last_search'. Inform the user when
|
||||
@@ -436,7 +405,7 @@ void go_looking(void)
|
||||
|
||||
came_full_circle = FALSE;
|
||||
|
||||
didfind = findnextstr(last_search, FALSE, JUSTFIND, NULL, FALSE,
|
||||
didfind = findnextstr(last_search, FALSE, JUSTFIND, NULL, TRUE,
|
||||
openfile->current, openfile->current_x);
|
||||
|
||||
/* If we found something, and we're back at the exact same spot
|
||||
@@ -452,7 +421,6 @@ void go_looking(void)
|
||||
#endif
|
||||
|
||||
edit_redraw(was_current, CENTERING);
|
||||
search_replace_abort();
|
||||
}
|
||||
|
||||
/* Calculate the size of the replacement text, taking possible
|
||||
@@ -546,7 +514,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
ssize_t numreplaced = -1;
|
||||
size_t match_len;
|
||||
bool replaceall = FALSE;
|
||||
bool skipone = FALSE;
|
||||
bool skipone = ISSET(BACKWARDS_SEARCH);
|
||||
int modus = REPLACING;
|
||||
#ifndef NANO_TINY
|
||||
filestruct *was_mark = openfile->mark;
|
||||
@@ -719,30 +687,22 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
|
||||
/* Replace a string. */
|
||||
void do_replace(void)
|
||||
{
|
||||
if (ISSET(VIEW_MODE))
|
||||
print_view_warning();
|
||||
else {
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
search_init(TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ask the user what the already given search string should be replaced with. */
|
||||
void ask_for_replacement(void)
|
||||
{
|
||||
filestruct *edittop_save, *begin;
|
||||
size_t firstcolumn_save, begin_x;
|
||||
ssize_t numreplaced;
|
||||
int i;
|
||||
|
||||
if (ISSET(VIEW_MODE)) {
|
||||
print_view_warning();
|
||||
return;
|
||||
}
|
||||
|
||||
i = search_init(TRUE, FALSE);
|
||||
|
||||
if (i == -1) /* Cancelled, or some other exit reason. */
|
||||
search_replace_abort();
|
||||
else if (i == -2) /* Do a search instead. */
|
||||
do_search();
|
||||
else if (i == 1) /* Toggled something. */
|
||||
do_replace();
|
||||
|
||||
if (i != 0)
|
||||
return;
|
||||
|
||||
i = do_prompt(FALSE, FALSE, MREPLACEWITH, NULL, &replace_history,
|
||||
int i = do_prompt(FALSE, FALSE, MREPLACEWITH, NULL, &replace_history,
|
||||
/* TRANSLATORS: This is a prompt. */
|
||||
edit_refresh, _("Replace with"));
|
||||
|
||||
@@ -756,7 +716,6 @@ void do_replace(void)
|
||||
if (i == -1 || i > 0) {
|
||||
if (i == -1)
|
||||
statusbar(_("Cancelled"));
|
||||
search_replace_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -778,8 +737,6 @@ void do_replace(void)
|
||||
if (numreplaced >= 0)
|
||||
statusline(HUSH, P_("Replaced %zd occurrence",
|
||||
"Replaced %zd occurrences", numreplaced), numreplaced);
|
||||
|
||||
search_replace_abort();
|
||||
}
|
||||
|
||||
/* Go to the specified line and x position. */
|
||||
@@ -802,8 +759,6 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
bool interactive)
|
||||
{
|
||||
if (interactive) {
|
||||
functionptrtype func;
|
||||
|
||||
/* Ask for the line and column. */
|
||||
int i = do_prompt(FALSE, FALSE, MGOTOLINE,
|
||||
use_answer ? answer : NULL, NULL,
|
||||
@@ -816,12 +771,11 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
return;
|
||||
}
|
||||
|
||||
func = func_from_key(&i);
|
||||
|
||||
if (func == gototext_void) {
|
||||
if (func_from_key(&i) == flip_goto) {
|
||||
UNSET(BACKWARDS_SEARCH);
|
||||
/* Retain what the user typed so far and switch to searching. */
|
||||
search_init(TRUE, TRUE);
|
||||
do_search();
|
||||
search_init(FALSE, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If a function was executed, we're done here. */
|
||||
@@ -877,11 +831,11 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
filestruct *line = openfile->current;
|
||||
filestruct *currentline = openfile->current;
|
||||
size_t leftedge = leftedge_for(xplustabs(), openfile->current);
|
||||
|
||||
rows_from_tail = (editwinrows / 2) -
|
||||
go_forward_chunks(editwinrows / 2, &line, &leftedge);
|
||||
rows_from_tail = (editwinrows / 2) - go_forward_chunks(
|
||||
editwinrows / 2, ¤tline, &leftedge);
|
||||
} else
|
||||
#endif
|
||||
rows_from_tail = openfile->filebot->lineno -
|
||||
|
||||
788
src/text.c
788
src/text.c
File diff suppressed because it is too large
Load Diff
24
src/utils.c
24
src/utils.c
@@ -1,7 +1,7 @@
|
||||
/**************************************************************************
|
||||
* utils.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2016-2017 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
@@ -48,7 +48,7 @@ void get_homedir(void)
|
||||
|
||||
/* Only set homedir if some home directory could be determined,
|
||||
* otherwise keep homedir NULL. */
|
||||
if (homenv != NULL && strcmp(homenv, "") != 0)
|
||||
if (homenv != NULL && *homenv != '\0')
|
||||
homedir = mallocstrcpy(NULL, homenv);
|
||||
}
|
||||
}
|
||||
@@ -325,15 +325,18 @@ const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
else
|
||||
return haystack + regmatches[0].rm_so;
|
||||
}
|
||||
|
||||
if (ISSET(CASE_SENSITIVE)) {
|
||||
if (ISSET(BACKWARDS_SEARCH))
|
||||
return revstrstr(haystack, needle, start);
|
||||
else
|
||||
return strstr(start, needle);
|
||||
} else if (ISSET(BACKWARDS_SEARCH))
|
||||
return mbrevstrcasestr(haystack, needle, start);
|
||||
}
|
||||
|
||||
return mbstrcasestr(start, needle);
|
||||
if (ISSET(BACKWARDS_SEARCH))
|
||||
return mbrevstrcasestr(haystack, needle, start);
|
||||
else
|
||||
return mbstrcasestr(start, needle);
|
||||
}
|
||||
|
||||
/* This is a wrapper for the perror() function. The wrapper temporarily
|
||||
@@ -378,10 +381,11 @@ char *mallocstrncpy(char *dest, const char *src, size_t n)
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
|
||||
if (src != dest)
|
||||
free(dest);
|
||||
|
||||
dest = charalloc(n);
|
||||
#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);
|
||||
|
||||
return dest;
|
||||
@@ -455,7 +459,7 @@ size_t strnlenpt(const char *text, size_t maxlen)
|
||||
return 0;
|
||||
|
||||
while (*text != '\0') {
|
||||
int charlen = parse_mbchar(text, NULL, &width);
|
||||
size_t charlen = parse_mbchar(text, NULL, &width);
|
||||
|
||||
if (maxlen <= charlen)
|
||||
break;
|
||||
|
||||
457
src/winio.c
457
src/winio.c
@@ -1,8 +1,8 @@
|
||||
/**************************************************************************
|
||||
* winio.c -- This file is part of GNU nano. *
|
||||
* *
|
||||
* Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2017 Benno Schulenberg *
|
||||
* Copyright (C) 1999-2011, 2013-2018 Free Software Foundation, Inc. *
|
||||
* Copyright (C) 2014-2018 Benno Schulenberg *
|
||||
* *
|
||||
* GNU nano is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published *
|
||||
@@ -35,12 +35,13 @@
|
||||
#endif
|
||||
|
||||
static int *key_buffer = NULL;
|
||||
/* The keystroke buffer, containing all the keystrokes we
|
||||
* haven't handled yet at a given point. */
|
||||
/* A buffer for the keystrokes that haven't been handled yet. */
|
||||
static size_t key_buffer_len = 0;
|
||||
/* The length of the keystroke buffer. */
|
||||
static bool solitary = FALSE;
|
||||
/* Whether an Esc arrived by itself -- not as leader of a sequence. */
|
||||
static int digit_count = 0;
|
||||
/* How many digits of a three-digit character code we've eaten. */
|
||||
static bool waiting_mode = TRUE;
|
||||
/* Whether getting a character will wait for a key to be pressed. */
|
||||
static int statusblank = 0;
|
||||
@@ -106,8 +107,7 @@ void run_macro(void)
|
||||
return;
|
||||
}
|
||||
|
||||
free(key_buffer);
|
||||
key_buffer = (int *)nmalloc(macro_length * sizeof(int));
|
||||
key_buffer = (int *)nrealloc(key_buffer, macro_length * sizeof(int));
|
||||
key_buffer_len = macro_length;
|
||||
|
||||
for (i = 0; i < macro_length; i++)
|
||||
@@ -169,15 +169,11 @@ void run_macro(void)
|
||||
|
||||
/* Read in a sequence of keystrokes from the given window and save them
|
||||
* in the keystroke buffer. */
|
||||
void get_key_buffer(WINDOW *win)
|
||||
void read_keys_from(WINDOW *win)
|
||||
{
|
||||
int input = ERR;
|
||||
size_t errcount = 0;
|
||||
|
||||
/* If the keystroke buffer isn't empty, get out. */
|
||||
if (key_buffer != NULL)
|
||||
return;
|
||||
|
||||
/* Before reading the first keycode, display any pending screen updates. */
|
||||
doupdate();
|
||||
|
||||
@@ -214,9 +210,9 @@ void get_key_buffer(WINDOW *win)
|
||||
curs_set(0);
|
||||
|
||||
/* Initiate the keystroke buffer, and save the keycode in it. */
|
||||
key_buffer_len++;
|
||||
key_buffer = (int *)nmalloc(sizeof(int));
|
||||
key_buffer = (int *)nrealloc(key_buffer, sizeof(int));
|
||||
key_buffer[0] = input;
|
||||
key_buffer_len = 1;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If we got a SIGWINCH, get out as the win argument is no longer valid. */
|
||||
@@ -262,44 +258,43 @@ size_t get_key_buffer_len(void)
|
||||
return key_buffer_len;
|
||||
}
|
||||
|
||||
/* Add the keycodes in input to the keystroke buffer. */
|
||||
void unget_input(int *input, size_t input_len)
|
||||
/* Add the given keycode to the front of the keystroke buffer. */
|
||||
void put_back(int keycode)
|
||||
{
|
||||
/* If input is empty, get out. */
|
||||
if (input_len == 0)
|
||||
/* If the keystroke buffer is at maximum capacity, don't add anything. */
|
||||
if (key_buffer_len + 1 < key_buffer_len)
|
||||
return;
|
||||
|
||||
/* If adding input would put the keystroke buffer beyond maximum capacity,
|
||||
* only add enough of input to put it at maximum capacity. */
|
||||
if (key_buffer_len + input_len < key_buffer_len)
|
||||
input_len = (size_t)-1 - key_buffer_len;
|
||||
/* Extend the keystroke buffer to make room for the extra keycode. */
|
||||
key_buffer = (int *)nrealloc(key_buffer, ++key_buffer_len * sizeof(int));
|
||||
|
||||
/* Extend the keystroke buffer to make room for the extra keycodes. */
|
||||
key_buffer_len += input_len;
|
||||
key_buffer = (int *)nrealloc(key_buffer, key_buffer_len * sizeof(int));
|
||||
/* If the keystroke buffer wasn't empty before, move all the
|
||||
* existing content one step further away. */
|
||||
if (key_buffer_len > 1)
|
||||
memmove(key_buffer + 1, key_buffer, (key_buffer_len - 1) * sizeof(int));
|
||||
|
||||
/* If the keystroke buffer wasn't empty before, move its beginning
|
||||
* forward far enough so that we can add input to its beginning. */
|
||||
if (key_buffer_len > input_len)
|
||||
memmove(key_buffer + input_len, key_buffer,
|
||||
(key_buffer_len - input_len) * sizeof(int));
|
||||
|
||||
/* Copy input to the beginning of the keystroke buffer. */
|
||||
memcpy(key_buffer, input, input_len * sizeof(int));
|
||||
*key_buffer = keycode;
|
||||
}
|
||||
|
||||
/* Put the character given in kbinput back into the input stream. If it
|
||||
* is a Meta key, also insert an Escape character in front of it. */
|
||||
void unget_kbinput(int kbinput, bool metakey)
|
||||
{
|
||||
unget_input(&kbinput, 1);
|
||||
put_back(kbinput);
|
||||
|
||||
if (metakey) {
|
||||
kbinput = ESC_CODE;
|
||||
unget_input(&kbinput, 1);
|
||||
}
|
||||
if (metakey)
|
||||
put_back(ESC_CODE);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
/* Insert the given string into the keyboard buffer. */
|
||||
void implant(const char *string)
|
||||
{
|
||||
for (int i = strlen(string); i > 0; i--)
|
||||
put_back(string[i - 1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Try to read input_len codes from the keystroke buffer. If the
|
||||
* keystroke buffer is empty and win isn't NULL, try to read in more
|
||||
* codes from win and add them to the keystroke buffer before doing
|
||||
@@ -309,7 +304,7 @@ int *get_input(WINDOW *win, size_t input_len)
|
||||
int *input;
|
||||
|
||||
if (key_buffer_len == 0 && win != NULL)
|
||||
get_key_buffer(win);
|
||||
read_keys_from(win);
|
||||
|
||||
if (key_buffer_len == 0)
|
||||
return NULL;
|
||||
@@ -323,17 +318,10 @@ int *get_input(WINDOW *win, size_t input_len)
|
||||
memcpy(input, key_buffer, input_len * sizeof(int));
|
||||
key_buffer_len -= input_len;
|
||||
|
||||
/* If the keystroke buffer is now empty, mark it as such. */
|
||||
if (key_buffer_len == 0) {
|
||||
free(key_buffer);
|
||||
key_buffer = NULL;
|
||||
} else {
|
||||
/* Trim from the buffer the codes that were copied. */
|
||||
/* If the buffer still contains keystrokes, move them to the front. */
|
||||
if (key_buffer_len > 0)
|
||||
memmove(key_buffer, key_buffer + input_len, key_buffer_len *
|
||||
sizeof(int));
|
||||
key_buffer = (int *)nrealloc(key_buffer, key_buffer_len *
|
||||
sizeof(int));
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
@@ -364,7 +352,7 @@ int get_kbinput(WINDOW *win, bool showcursor)
|
||||
* the function keys (F1-F16), and the numeric keypad with NumLock off. */
|
||||
int parse_kbinput(WINDOW *win)
|
||||
{
|
||||
static int escapes = 0, byte_digits = 0;
|
||||
static int escapes = 0;
|
||||
static bool double_esc = FALSE;
|
||||
int *kbinput, keycode, retval = ERR;
|
||||
|
||||
@@ -375,7 +363,7 @@ int parse_kbinput(WINDOW *win)
|
||||
kbinput = get_input(win, 1);
|
||||
|
||||
if (kbinput == NULL && !waiting_mode)
|
||||
return 0;
|
||||
return ERR;
|
||||
|
||||
while (kbinput == NULL)
|
||||
kbinput = get_input(win, 1);
|
||||
@@ -384,8 +372,8 @@ int parse_kbinput(WINDOW *win)
|
||||
free(kbinput);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "before parsing: keycode = %d, escapes = %d, byte_digits = %d\n",
|
||||
keycode, escapes, byte_digits);
|
||||
fprintf(stderr, "before parsing: keycode = %d, escapes = %d, digit_count = %d\n",
|
||||
keycode, escapes, digit_count);
|
||||
#endif
|
||||
|
||||
if (keycode == ERR)
|
||||
@@ -409,6 +397,8 @@ int parse_kbinput(WINDOW *win)
|
||||
case 1:
|
||||
if (keycode >= 0x80)
|
||||
retval = keycode;
|
||||
else if (keycode == TAB_CODE)
|
||||
retval = SHIFT_TAB;
|
||||
else if ((keycode != 'O' && keycode != 'o' && keycode != '[') ||
|
||||
key_buffer_len == 0 || *key_buffer == ESC_CODE) {
|
||||
/* One escape followed by a single non-escape:
|
||||
@@ -457,45 +447,35 @@ int parse_kbinput(WINDOW *win)
|
||||
double_esc = FALSE;
|
||||
escapes = 0;
|
||||
} else if (key_buffer_len == 0) {
|
||||
if (('0' <= keycode && keycode <= '2' &&
|
||||
byte_digits == 0) || ('0' <= keycode &&
|
||||
keycode <= '9' && byte_digits > 0)) {
|
||||
if ('0' <= keycode && ((keycode <= '2' && digit_count == 0) ||
|
||||
(keycode <= '9' && digit_count > 0))) {
|
||||
/* Two escapes followed by one or more decimal
|
||||
* digits, and there aren't any other codes
|
||||
* waiting: byte sequence mode. If the range
|
||||
* of the byte sequence is limited to 2XX (the
|
||||
* first digit is between '0' and '2' and the
|
||||
* others between '0' and '9', interpret it. */
|
||||
int byte;
|
||||
|
||||
byte_digits++;
|
||||
byte = get_byte_kbinput(keycode);
|
||||
* waiting: byte sequence mode. If the range of the
|
||||
* byte sequence is limited to 2XX, interpret it. */
|
||||
int byte = get_byte_kbinput(keycode);
|
||||
|
||||
/* If the decimal byte value is complete, convert it and
|
||||
* put the obtained byte(s) back into the input buffer. */
|
||||
if (byte != ERR) {
|
||||
char *byte_mb;
|
||||
int byte_mb_len, *seq, i;
|
||||
char *multibyte;
|
||||
int count, onebyte, i;
|
||||
|
||||
/* Convert the decimal code to one or two bytes. */
|
||||
byte_mb = make_mbchar((long)byte, &byte_mb_len);
|
||||
|
||||
seq = (int *)nmalloc(byte_mb_len * sizeof(int));
|
||||
|
||||
for (i = 0; i < byte_mb_len; i++)
|
||||
seq[i] = (unsigned char)byte_mb[i];
|
||||
multibyte = make_mbchar((long)byte, &count);
|
||||
|
||||
/* Insert the byte(s) into the input buffer. */
|
||||
unget_input(seq, byte_mb_len);
|
||||
for (i = count; i > 0 ; i--) {
|
||||
onebyte = (unsigned char)multibyte[i - 1];
|
||||
put_back(onebyte);
|
||||
}
|
||||
|
||||
free(byte_mb);
|
||||
free(seq);
|
||||
free(multibyte);
|
||||
|
||||
byte_digits = 0;
|
||||
escapes = 0;
|
||||
}
|
||||
} else {
|
||||
if (byte_digits == 0)
|
||||
if (digit_count == 0)
|
||||
/* Two escapes followed by a non-decimal
|
||||
* digit (or a decimal digit that would
|
||||
* create a byte sequence greater than 2XX)
|
||||
@@ -506,7 +486,7 @@ int parse_kbinput(WINDOW *win)
|
||||
/* An invalid digit in the middle of a byte
|
||||
* sequence: reset the byte sequence counter
|
||||
* and save the code we got as the result. */
|
||||
byte_digits = 0;
|
||||
digit_count = 0;
|
||||
retval = keycode;
|
||||
}
|
||||
escapes = 0;
|
||||
@@ -602,7 +582,7 @@ int parse_kbinput(WINDOW *win)
|
||||
* Shift/Ctrl/Alt are being held together with them. */
|
||||
unsigned char modifiers = 6;
|
||||
|
||||
if (console && ioctl(0, TIOCLINUX, &modifiers) >= 0) {
|
||||
if (on_a_vt && ioctl(0, TIOCLINUX, &modifiers) >= 0) {
|
||||
#ifndef NANO_TINY
|
||||
/* Is Shift being held? */
|
||||
if (modifiers & 0x01) {
|
||||
@@ -654,21 +634,18 @@ int parse_kbinput(WINDOW *win)
|
||||
#endif
|
||||
|
||||
switch (retval) {
|
||||
#ifdef KEY_SLEFT
|
||||
/* Slang doesn't support KEY_SLEFT. */
|
||||
#ifdef KEY_SLEFT /* Slang doesn't support KEY_SLEFT. */
|
||||
case KEY_SLEFT:
|
||||
shift_held = TRUE;
|
||||
return KEY_LEFT;
|
||||
#endif
|
||||
#ifdef KEY_SRIGHT
|
||||
/* Slang doesn't support KEY_SRIGHT. */
|
||||
#ifdef KEY_SRIGHT /* Slang doesn't support KEY_SRIGHT. */
|
||||
case KEY_SRIGHT:
|
||||
shift_held = TRUE;
|
||||
return KEY_RIGHT;
|
||||
#endif
|
||||
#ifdef KEY_SR
|
||||
#ifdef KEY_SUP
|
||||
/* ncurses and Slang don't support KEY_SUP. */
|
||||
#ifdef KEY_SUP /* ncurses and Slang don't support KEY_SUP. */
|
||||
case KEY_SUP:
|
||||
#endif
|
||||
case KEY_SR: /* Scroll backward, on Xfce4-terminal. */
|
||||
@@ -676,30 +653,31 @@ int parse_kbinput(WINDOW *win)
|
||||
return KEY_UP;
|
||||
#endif
|
||||
#ifdef KEY_SF
|
||||
#ifdef KEY_SDOWN
|
||||
/* ncurses and Slang don't support KEY_SDOWN. */
|
||||
#ifdef KEY_SDOWN /* ncurses and Slang don't support KEY_SDOWN. */
|
||||
case KEY_SDOWN:
|
||||
#endif
|
||||
case KEY_SF: /* Scroll forward, on Xfce4-terminal. */
|
||||
shift_held = TRUE;
|
||||
return KEY_DOWN;
|
||||
#endif
|
||||
#ifdef KEY_SHOME
|
||||
/* HP-UX 10-11 and Slang don't support KEY_SHOME. */
|
||||
#ifdef KEY_SHOME /* HP-UX 10-11 and Slang don't support KEY_SHOME. */
|
||||
case KEY_SHOME:
|
||||
#endif
|
||||
case SHIFT_HOME:
|
||||
shift_held = TRUE;
|
||||
case KEY_A1: /* Home (7) on keypad with NumLock off. */
|
||||
return KEY_HOME;
|
||||
#ifdef KEY_SEND
|
||||
/* HP-UX 10-11 and Slang don't support KEY_SEND. */
|
||||
#ifdef KEY_SEND /* HP-UX 10-11 and Slang don't support KEY_SEND. */
|
||||
case KEY_SEND:
|
||||
#endif
|
||||
case SHIFT_END:
|
||||
shift_held = TRUE;
|
||||
case KEY_C1: /* End (1) on keypad with NumLock off. */
|
||||
return KEY_END;
|
||||
#ifdef KEY_EOL
|
||||
case KEY_EOL: /* Ctrl+End on rxvt-unicode. */
|
||||
return CONTROL_END;
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
#ifdef KEY_SPREVIOUS
|
||||
case KEY_SPREVIOUS:
|
||||
@@ -718,8 +696,7 @@ int parse_kbinput(WINDOW *win)
|
||||
#endif
|
||||
case KEY_C3: /* PageDown (3) on keypad with NumLock off. */
|
||||
return KEY_NPAGE;
|
||||
#ifdef KEY_SDC
|
||||
/* Slang doesn't support KEY_SDC. */
|
||||
#ifdef KEY_SDC /* Slang doesn't support KEY_SDC. */
|
||||
case KEY_SDC:
|
||||
#endif
|
||||
case DEL_CODE:
|
||||
@@ -727,41 +704,33 @@ int parse_kbinput(WINDOW *win)
|
||||
return the_code_for(do_delete, KEY_DC);
|
||||
else
|
||||
return KEY_BACKSPACE;
|
||||
#ifdef KEY_SIC
|
||||
/* Slang doesn't support KEY_SIC. */
|
||||
#ifdef KEY_SIC /* Slang doesn't support KEY_SIC. */
|
||||
case KEY_SIC:
|
||||
return the_code_for(do_insertfile_void, KEY_IC);
|
||||
#endif
|
||||
#ifdef KEY_SBEG
|
||||
/* Slang doesn't support KEY_SBEG. */
|
||||
#ifdef KEY_SBEG /* Slang doesn't support KEY_SBEG. */
|
||||
case KEY_SBEG:
|
||||
#endif
|
||||
#ifdef KEY_BEG
|
||||
/* Slang doesn't support KEY_BEG. */
|
||||
#ifdef KEY_BEG /* Slang doesn't support KEY_BEG. */
|
||||
case KEY_BEG:
|
||||
#endif
|
||||
case KEY_B2: /* Center (5) on keypad with NumLock off. */
|
||||
return ERR;
|
||||
#ifdef KEY_CANCEL
|
||||
#ifdef KEY_SCANCEL
|
||||
/* Slang doesn't support KEY_SCANCEL. */
|
||||
#ifdef KEY_CANCEL /* Slang doesn't support KEY_CANCEL. */
|
||||
#ifdef KEY_SCANCEL /* Slang doesn't support KEY_SCANCEL. */
|
||||
case KEY_SCANCEL:
|
||||
#endif
|
||||
/* Slang doesn't support KEY_CANCEL. */
|
||||
case KEY_CANCEL:
|
||||
return the_code_for(do_cancel, 0x03);
|
||||
#endif
|
||||
#ifdef KEY_SUSPEND
|
||||
#ifdef KEY_SSUSPEND
|
||||
/* Slang doesn't support KEY_SSUSPEND. */
|
||||
#ifdef KEY_SUSPEND /* Slang doesn't support KEY_SUSPEND. */
|
||||
#ifdef KEY_SSUSPEND /* Slang doesn't support KEY_SSUSPEND. */
|
||||
case KEY_SSUSPEND:
|
||||
#endif
|
||||
/* Slang doesn't support KEY_SUSPEND. */
|
||||
case KEY_SUSPEND:
|
||||
return the_code_for(do_suspend_void, KEY_SUSPEND);
|
||||
#endif
|
||||
#ifdef KEY_BTAB
|
||||
/* Slang doesn't support KEY_BTAB. */
|
||||
#ifdef KEY_BTAB /* Slang doesn't support KEY_BTAB. */
|
||||
case KEY_BTAB:
|
||||
return SHIFT_TAB;
|
||||
#endif
|
||||
@@ -774,8 +743,7 @@ int parse_kbinput(WINDOW *win)
|
||||
case KEY_ALT_R:
|
||||
return ERR;
|
||||
#endif
|
||||
#ifdef KEY_RESIZE
|
||||
/* Slang and SunOS 5.7-5.9 don't support KEY_RESIZE. */
|
||||
#ifdef KEY_RESIZE /* Slang and SunOS 5.7-5.9 don't support KEY_RESIZE. */
|
||||
case KEY_RESIZE:
|
||||
#endif
|
||||
#if defined(USE_SLANG) && defined(ENABLE_UTF8)
|
||||
@@ -792,15 +760,17 @@ int parse_kbinput(WINDOW *win)
|
||||
* keypad values, into their corresponding key values. These sequences
|
||||
* are generated when the keypad doesn't support the needed keys.
|
||||
* Assume that Escape has already been read in. */
|
||||
int convert_sequence(const int *seq, size_t seq_len)
|
||||
int convert_sequence(const int *seq, size_t length, int *consumed)
|
||||
{
|
||||
if (seq_len > 1) {
|
||||
if (length > 1) {
|
||||
*consumed = 2;
|
||||
switch (seq[0]) {
|
||||
case 'O':
|
||||
switch (seq[1]) {
|
||||
case '1':
|
||||
if (seq_len > 4 && seq[2] == ';') {
|
||||
|
||||
if (length > 4 && seq[2] == ';') {
|
||||
/* <-<-<-<-<-<-<- */
|
||||
*consumed = 5;
|
||||
switch (seq[3]) {
|
||||
case '2':
|
||||
switch (seq[4]) {
|
||||
@@ -833,11 +803,12 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* ->->->->->->-> */
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
if (seq_len >= 3) {
|
||||
if (length > 2) {
|
||||
*consumed = 3;
|
||||
switch (seq[2]) {
|
||||
case 'P': /* Esc O 2 P == F13 on xterm. */
|
||||
return KEY_F(13);
|
||||
@@ -851,7 +822,8 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
}
|
||||
break;
|
||||
case '5':
|
||||
if (seq_len >= 3) {
|
||||
if (length > 2) {
|
||||
*consumed = 3;
|
||||
switch (seq[2]) {
|
||||
case 'A': /* Esc O 5 A == Ctrl-Up on Haiku. */
|
||||
return CONTROL_UP;
|
||||
@@ -863,6 +835,7 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
return CONTROL_LEFT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'A': /* Esc O A == Up on VT100/VT320/xterm. */
|
||||
case 'B': /* Esc O B == Down on VT100/VT320/xterm. */
|
||||
case 'C': /* Esc O C == Right on VT100/VT320/xterm. */
|
||||
@@ -962,9 +935,15 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
if (seq[1] < '9')
|
||||
*consumed = 3;
|
||||
switch (seq[1]) {
|
||||
case '1':
|
||||
if (seq_len > 3 && seq[3] == '~') {
|
||||
if (length > 2 && seq[2] == '~')
|
||||
/* Esc [ 1 ~ == Home on VT320/Linux console. */
|
||||
return KEY_HOME;
|
||||
else if (length > 3 && seq[3] == '~') {
|
||||
*consumed = 4;
|
||||
switch (seq[2]) {
|
||||
case '1': /* Esc [ 1 1 ~ == F1 on rxvt/Eterm. */
|
||||
return KEY_F(1);
|
||||
@@ -984,8 +963,9 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
case '9': /* Esc [ 1 9 ~ == F8 on the same. */
|
||||
return KEY_F(8);
|
||||
}
|
||||
} else if (seq_len > 4 && seq[2] == ';') {
|
||||
|
||||
} else if (length > 4 && seq[2] == ';') {
|
||||
/* <-<-<-<-<-<-<- */
|
||||
*consumed = 5;
|
||||
switch (seq[3]) {
|
||||
case '2':
|
||||
switch (seq[4]) {
|
||||
@@ -995,6 +975,12 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
case 'D': /* Esc [ 1 ; 2 D == Shift-Left on xterm. */
|
||||
shift_held = TRUE;
|
||||
return arrow_from_abcd(seq[4]);
|
||||
#ifndef NANO_TINY
|
||||
case 'F': /* Esc [ 1 ; 2 F == Shift-End on xterm. */
|
||||
return SHIFT_END;
|
||||
case 'H': /* Esc [ 1 ; 2 H == Shift-Home on xterm. */
|
||||
return SHIFT_HOME;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#ifndef NANO_TINY
|
||||
@@ -1061,13 +1047,12 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
} else if (seq_len > 2 && seq[2] == '~')
|
||||
/* Esc [ 1 ~ == Home on VT320/Linux console. */
|
||||
return KEY_HOME;
|
||||
/* ->->->->->->-> */
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
if (seq_len > 3 && seq[3] == '~') {
|
||||
if (length > 3 && seq[3] == '~') {
|
||||
*consumed = 4;
|
||||
switch (seq[2]) {
|
||||
case '0': /* Esc [ 2 0 ~ == F9 on VT220/VT320/
|
||||
* Linux console/xterm/rxvt/Eterm. */
|
||||
@@ -1088,45 +1073,59 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
case '9': /* Esc [ 2 9 ~ == F16 on the same. */
|
||||
return KEY_F(16);
|
||||
}
|
||||
} else if (seq_len > 2 && seq[2] == '~')
|
||||
} else if (length > 2 && seq[2] == '~')
|
||||
/* Esc [ 2 ~ == Insert on VT220/VT320/
|
||||
* Linux console/xterm/Terminal. */
|
||||
return KEY_IC;
|
||||
break;
|
||||
case '3': /* Esc [ 3 ~ == Delete on VT220/VT320/
|
||||
* Linux console/xterm/Terminal. */
|
||||
if (seq_len > 2 && seq[2] == '~')
|
||||
if (length > 2 && seq[2] == '~')
|
||||
return KEY_DC;
|
||||
break;
|
||||
case '4': /* Esc [ 4 ~ == End on VT220/VT320/
|
||||
* Linux console/xterm. */
|
||||
if (seq_len > 2 && seq[2] == '~')
|
||||
if (length > 2 && seq[2] == '~')
|
||||
return KEY_END;
|
||||
break;
|
||||
case '5': /* Esc [ 5 ~ == PageUp on VT220/VT320/
|
||||
* Linux console/xterm/Terminal;
|
||||
* Esc [ 5 ^ == PageUp on Eterm. */
|
||||
if (seq_len > 2 && (seq[2] == '~' || seq[2] == '^'))
|
||||
if (length > 2 && (seq[2] == '~' || seq[2] == '^'))
|
||||
return KEY_PPAGE;
|
||||
#ifndef NANO_TINY
|
||||
else if (length > 4 && seq[2] == ';' &&
|
||||
seq[3] == '2' && seq[4] == '~') {
|
||||
*consumed = 5;
|
||||
return shiftaltup;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case '6': /* Esc [ 6 ~ == PageDown on VT220/VT320/
|
||||
* Linux console/xterm/Terminal;
|
||||
* Esc [ 6 ^ == PageDown on Eterm. */
|
||||
if (seq_len > 2 && (seq[2] == '~' || seq[2] == '^'))
|
||||
if (length > 2 && (seq[2] == '~' || seq[2] == '^'))
|
||||
return KEY_NPAGE;
|
||||
#ifndef NANO_TINY
|
||||
else if (length > 4 && seq[2] == ';' &&
|
||||
seq[3] == '2' && seq[4] == '~') {
|
||||
*consumed = 5;
|
||||
return shiftaltdown;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case '7': /* Esc [ 7 ~ == Home on Eterm/rxvt;
|
||||
* Esc [ 7 $ == Shift-Home on Eterm/rxvt;
|
||||
* Esc [ 7 ^ == Control-Home on Eterm/rxvt;
|
||||
* Esc [ 7 @ == Shift-Control-Home on same. */
|
||||
if (seq_len > 2 && seq[2] == '~')
|
||||
if (length > 2 && seq[2] == '~')
|
||||
return KEY_HOME;
|
||||
else if (seq_len > 2 && seq[2] == '$')
|
||||
else if (length > 2 && seq[2] == '$')
|
||||
return SHIFT_HOME;
|
||||
else if (seq_len > 2 && seq[2] == '^')
|
||||
else if (length > 2 && seq[2] == '^')
|
||||
return CONTROL_HOME;
|
||||
#ifndef NANO_TINY
|
||||
else if (seq_len > 2 && seq[2] == '@')
|
||||
else if (length > 2 && seq[2] == '@')
|
||||
return shiftcontrolhome;
|
||||
#endif
|
||||
break;
|
||||
@@ -1134,14 +1133,14 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
* Esc [ 8 $ == Shift-End on Eterm/rxvt;
|
||||
* Esc [ 8 ^ == Control-End on Eterm/rxvt;
|
||||
* Esc [ 8 @ == Shift-Control-End on same. */
|
||||
if (seq_len > 2 && seq[2] == '~')
|
||||
if (length > 2 && seq[2] == '~')
|
||||
return KEY_END;
|
||||
else if (seq_len > 2 && seq[2] == '$')
|
||||
else if (length > 2 && seq[2] == '$')
|
||||
return SHIFT_END;
|
||||
else if (seq_len > 2 && seq[2] == '^')
|
||||
else if (length > 2 && seq[2] == '^')
|
||||
return CONTROL_END;
|
||||
#ifndef NANO_TINY
|
||||
else if (seq_len > 2 && seq[2] == '@')
|
||||
else if (length > 2 && seq[2] == '@')
|
||||
return shiftcontrolend;
|
||||
#endif
|
||||
break;
|
||||
@@ -1174,7 +1173,8 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
case 'N': /* Esc [ N == F2 on FreeBSD console. */
|
||||
return KEY_F(2);
|
||||
case 'O':
|
||||
if (seq_len > 2) {
|
||||
if (length > 2) {
|
||||
*consumed = 3;
|
||||
switch (seq[2]) {
|
||||
case 'P': /* Esc [ O P == F1 on xterm. */
|
||||
return KEY_F(1);
|
||||
@@ -1219,7 +1219,8 @@ int convert_sequence(const int *seq, size_t seq_len)
|
||||
shift_held = TRUE;
|
||||
return arrow_from_abcd(seq[1]);
|
||||
case '[':
|
||||
if (seq_len > 2 ) {
|
||||
if (length > 2) {
|
||||
*consumed = 3;
|
||||
switch (seq[2]) {
|
||||
case 'A': /* Esc [ [ A == F1 on Linux console. */
|
||||
return KEY_F(1);
|
||||
@@ -1265,15 +1266,20 @@ int arrow_from_abcd(int kbinput)
|
||||
* isn't empty, and that the initial escape has already been read in. */
|
||||
int parse_escape_sequence(WINDOW *win, int kbinput)
|
||||
{
|
||||
int retval, *sequence, length;
|
||||
int retval, *sequence, length, consumed;
|
||||
|
||||
/* Put back the non-escape character, get the complete escape
|
||||
* sequence, translate the sequence into its corresponding key
|
||||
* value, and save that as the result. */
|
||||
unget_input(&kbinput, 1);
|
||||
length = key_buffer_len;
|
||||
/* Put back the non-escape code, then grab at most five integers
|
||||
* (the longest possible escape sequence) from the keybuffer and
|
||||
* translate the sequence into its corresponding keycode. */
|
||||
put_back(kbinput);
|
||||
length = (key_buffer_len < 5 ? key_buffer_len : 5);
|
||||
sequence = get_input(NULL, length);
|
||||
retval = convert_sequence(sequence, length);
|
||||
retval = convert_sequence(sequence, length, &consumed);
|
||||
|
||||
/* If not all grabbed integers were consumed, put the leftovers back. */
|
||||
for (int i = length - 1; i >= consumed; i--)
|
||||
put_back(sequence[i]);
|
||||
|
||||
free(sequence);
|
||||
|
||||
/* If we got an unrecognized escape sequence, notify the user. */
|
||||
@@ -1292,74 +1298,52 @@ int parse_escape_sequence(WINDOW *win, int kbinput)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Translate a byte sequence: turn a three-digit decimal number (from
|
||||
* 000 to 255) into its corresponding byte value. */
|
||||
/* Turn a three-digit decimal number (from 000 to 255) into its corresponding
|
||||
* byte value. */
|
||||
int get_byte_kbinput(int kbinput)
|
||||
{
|
||||
static int byte_digits = 0, byte = 0;
|
||||
static int byte = 0;
|
||||
int retval = ERR;
|
||||
|
||||
/* Increment the byte digit counter. */
|
||||
byte_digits++;
|
||||
|
||||
switch (byte_digits) {
|
||||
/* Check that the given digit is within the allowed range for its position.
|
||||
* If yes, store it. If no, return the digit (or character) itself. */
|
||||
switch (++digit_count) {
|
||||
case 1:
|
||||
/* First digit: This must be from zero to two. Put it in
|
||||
* the 100's position of the byte sequence holder. */
|
||||
/* The first digit (the 100's position) must be from zero to two. */
|
||||
if ('0' <= kbinput && kbinput <= '2')
|
||||
byte = (kbinput - '0') * 100;
|
||||
else
|
||||
/* This isn't the start of a byte sequence. Return this
|
||||
* character as the result. */
|
||||
retval = kbinput;
|
||||
break;
|
||||
case 2:
|
||||
/* Second digit: This must be from zero to five if the first
|
||||
* was two, and may be any decimal value if the first was
|
||||
* zero or one. Put it in the 10's position of the byte
|
||||
* sequence holder. */
|
||||
if (('0' <= kbinput && kbinput <= '5') || (byte < 200 &&
|
||||
'6' <= kbinput && kbinput <= '9'))
|
||||
/* The second digit (the 10's position) must be from zero to five
|
||||
* if the first was two, and may be any decimal value otherwise. */
|
||||
if ((byte < 200 && '0' <= kbinput && kbinput <= '9') ||
|
||||
('0' <= kbinput && kbinput <= '5'))
|
||||
byte += (kbinput - '0') * 10;
|
||||
else
|
||||
/* This isn't the second digit of a byte sequence.
|
||||
* Return this character as the result. */
|
||||
retval = kbinput;
|
||||
break;
|
||||
case 3:
|
||||
/* Third digit: This must be from zero to five if the first
|
||||
* was two and the second was five, and may be any decimal
|
||||
* value otherwise. Put it in the 1's position of the byte
|
||||
* sequence holder. */
|
||||
if (('0' <= kbinput && kbinput <= '5') || (byte < 250 &&
|
||||
'6' <= kbinput && kbinput <= '9')) {
|
||||
/* The third digit (the 1's position) must be from zero to five
|
||||
* if the first was two and the second was five, and may be any
|
||||
* decimal value otherwise. */
|
||||
if ((byte < 250 && '0' <= kbinput && kbinput <= '9') ||
|
||||
('0' <= kbinput && kbinput <= '5')) {
|
||||
byte += kbinput - '0';
|
||||
/* The byte sequence is complete. */
|
||||
retval = byte;
|
||||
} else
|
||||
/* This isn't the third digit of a byte sequence.
|
||||
* Return this character as the result. */
|
||||
retval = kbinput;
|
||||
break;
|
||||
default:
|
||||
/* If there are more than three digits, return this
|
||||
* character as the result. (Maybe we should produce an
|
||||
* error instead?) */
|
||||
retval = kbinput;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have a result, reset the byte digit counter and the byte
|
||||
* sequence holder. */
|
||||
/* If we have a result, reset the counter and the byte holder. */
|
||||
if (retval != ERR) {
|
||||
byte_digits = 0;
|
||||
digit_count = 0;
|
||||
byte = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "get_byte_kbinput(): kbinput = %d, byte_digits = %d, byte = %d, retval = %d\n", kbinput, byte_digits, byte, retval);
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1553,7 +1537,7 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count)
|
||||
|
||||
/* If the first code isn't the digit 0 nor 1, put it back. */
|
||||
if (unicode != ERR)
|
||||
unget_input(kbinput, 1);
|
||||
put_back(*kbinput);
|
||||
/* Otherwise, continue reading in digits until we have a complete
|
||||
* Unicode value, and put back the corresponding byte(s). */
|
||||
else {
|
||||
@@ -1575,7 +1559,7 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count)
|
||||
/* Insert the multibyte sequence into the input buffer. */
|
||||
for (i = *count; i > 0 ; i--) {
|
||||
onebyte = (unsigned char)multibyte[i - 1];
|
||||
unget_input(&onebyte, 1);
|
||||
put_back(onebyte);
|
||||
}
|
||||
|
||||
free(multibyte);
|
||||
@@ -1583,7 +1567,7 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count)
|
||||
} else
|
||||
#endif /* ENABLE_UTF8 */
|
||||
/* Put back the first code. */
|
||||
unget_input(kbinput, 1);
|
||||
put_back(*kbinput);
|
||||
|
||||
free(kbinput);
|
||||
|
||||
@@ -1599,26 +1583,20 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count)
|
||||
/* Handle any mouse event that may have occurred. We currently handle
|
||||
* releases/clicks of the first mouse button. If allow_shortcuts is
|
||||
* TRUE, releasing/clicking on a visible shortcut will put back the
|
||||
* keystroke associated with that shortcut. If NCURSES_MOUSE_VERSION is
|
||||
* at least 2, we also currently handle presses of the fourth mouse
|
||||
* button (upward rolls of the mouse wheel) by putting back the
|
||||
* keystrokes to move up, and presses of the fifth mouse button
|
||||
* (downward rolls of the mouse wheel) by putting back the keystrokes to
|
||||
* move down. We also store the coordinates of a mouse event that needs
|
||||
* to be handled in mouse_x and mouse_y, relative to the entire screen.
|
||||
* Return -1 on error, 0 if the mouse event needs to be handled, 1 if
|
||||
* it's been handled by putting back keystrokes that need to be handled.
|
||||
* or 2 if it's been ignored. Assume that KEY_MOUSE has already been
|
||||
* read in. */
|
||||
int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
|
||||
* keystroke associated with that shortcut. If ncurses supports them,
|
||||
* we also handle presses of the fourth mouse button (upward rolls of
|
||||
* the mouse wheel) by putting back keystrokes to move up, and presses
|
||||
* of the fifth mouse button (downward rolls of the mouse wheel) by
|
||||
* putting back keystrokes to move down. We also store the coordinates
|
||||
* of a mouse event that needs further handling in mouse_x and mouse_y.
|
||||
* Return -1 on error, 0 if the mouse event needs to be handled, 1 if it's
|
||||
* been handled by putting back keystrokes, or 2 if it's been ignored. */
|
||||
int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
{
|
||||
MEVENT mevent;
|
||||
bool in_bottomwin;
|
||||
subnfunc *f;
|
||||
|
||||
*mouse_x = -1;
|
||||
*mouse_y = -1;
|
||||
|
||||
/* First, get the actual mouse event. */
|
||||
if (getmouse(&mevent) == ERR)
|
||||
return -1;
|
||||
@@ -1631,7 +1609,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
|
||||
|
||||
/* Handle releases/clicks of the first mouse button. */
|
||||
if (mevent.bstate & (BUTTON1_RELEASED | BUTTON1_CLICKED)) {
|
||||
/* If we're allowing shortcuts, the current shortcut list is
|
||||
/* If we're allowing shortcuts, and the current shortcut list is
|
||||
* being displayed on the last two lines of the screen, and the
|
||||
* first mouse button was released on/clicked inside it, we need
|
||||
* to figure out which shortcut was released on/clicked and put
|
||||
@@ -1691,7 +1669,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
|
||||
for (f = allfuncs; f != NULL; f = f->next) {
|
||||
if ((f->menus & currmenu) == 0)
|
||||
continue;
|
||||
if (first_sc_for(currmenu, f->scfunc) == NULL)
|
||||
if (first_sc_for(currmenu, f->func) == NULL)
|
||||
continue;
|
||||
/* Tick off an actually shown shortcut. */
|
||||
j -= 1;
|
||||
@@ -1701,7 +1679,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
|
||||
|
||||
/* And put the corresponding key into the keyboard buffer. */
|
||||
if (f != NULL) {
|
||||
const sc *s = first_sc_for(currmenu, f->scfunc);
|
||||
const sc *s = first_sc_for(currmenu, f->func);
|
||||
unget_kbinput(s->keycode, s->meta);
|
||||
}
|
||||
return 1;
|
||||
@@ -1995,6 +1973,7 @@ char *display_string(const char *buf, size_t column, size_t span, bool isdata)
|
||||
return converted;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* Determine the sequence number of the given buffer in the circular list. */
|
||||
int buffer_number(openfilestruct *buffer)
|
||||
{
|
||||
@@ -2007,6 +1986,7 @@ int buffer_number(openfilestruct *buffer)
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If path is NULL, we're in normal editing mode, so display the current
|
||||
* version of nano, the current filename, and whether the current file
|
||||
@@ -2052,6 +2032,7 @@ void titlebar(const char *path)
|
||||
else
|
||||
#endif
|
||||
if (!inhelp) {
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* If there are/were multiple buffers, show which out of how many. */
|
||||
if (more_than_one) {
|
||||
indicator = charalloc(24);
|
||||
@@ -2059,6 +2040,7 @@ void titlebar(const char *path)
|
||||
buffer_number(firstfile->prev));
|
||||
upperleft = indicator;
|
||||
} else
|
||||
#endif
|
||||
upperleft = BRANDING;
|
||||
|
||||
if (openfile->filename[0] == '\0')
|
||||
@@ -2162,6 +2144,7 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
static int alerts = 0;
|
||||
int colorpair;
|
||||
char *compound, *message;
|
||||
size_t start_col;
|
||||
bool bracketed;
|
||||
@@ -2200,7 +2183,9 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
msg = _("Further warnings were suppressed");
|
||||
else if (alerts < 4)
|
||||
beep();
|
||||
}
|
||||
colorpair = interface_color_pair[ERROR_MESSAGE];
|
||||
} else
|
||||
colorpair = interface_color_pair[STATUS_BAR];
|
||||
|
||||
lastmessage = importance;
|
||||
|
||||
@@ -2217,14 +2202,14 @@ void statusline(message_type importance, const char *msg, ...)
|
||||
bracketed = (start_col > 1);
|
||||
|
||||
wmove(bottomwin, 0, (bracketed ? start_col - 2 : start_col));
|
||||
wattron(bottomwin, interface_color_pair[STATUS_BAR]);
|
||||
wattron(bottomwin, colorpair);
|
||||
if (bracketed)
|
||||
waddstr(bottomwin, "[ ");
|
||||
waddstr(bottomwin, message);
|
||||
free(message);
|
||||
if (bracketed)
|
||||
waddstr(bottomwin, " ]");
|
||||
wattroff(bottomwin, interface_color_pair[STATUS_BAR]);
|
||||
wattroff(bottomwin, colorpair);
|
||||
|
||||
/* Defeat a VTE/Konsole bug, where the cursor can go off-limits. */
|
||||
if (ISSET(CONSTANT_SHOW) && ISSET(NO_HELP))
|
||||
@@ -2283,7 +2268,7 @@ void bottombars(int menu)
|
||||
if ((f->menus & menu) == 0)
|
||||
continue;
|
||||
|
||||
s = first_sc_for(menu, f->scfunc);
|
||||
s = first_sc_for(menu, f->func);
|
||||
if (s == NULL)
|
||||
continue;
|
||||
|
||||
@@ -2931,57 +2916,42 @@ bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge)
|
||||
return (openfile->current->lineno - was_lineno < editwinrows);
|
||||
}
|
||||
|
||||
/* Scroll the edit window in the given direction and the given number of rows,
|
||||
* and draw new lines on the blank lines left after the scrolling. */
|
||||
void edit_scroll(bool direction, int nrows)
|
||||
/* Scroll the edit window one row in the given direction, and
|
||||
* draw the relevant content on the resultant blank row. */
|
||||
void edit_scroll(bool direction)
|
||||
{
|
||||
filestruct *line;
|
||||
size_t leftedge;
|
||||
int remainder = 0, nrows = 1;
|
||||
|
||||
/* Part 1: nrows is the number of rows we're going to scroll the text of
|
||||
* the edit window. */
|
||||
|
||||
/* Move the top line of the edit window the requested number of rows up or
|
||||
* down, and reduce the number of rows with the amount we couldn't move. */
|
||||
/* Move the top line of the edit window one row up or down. */
|
||||
if (direction == BACKWARD)
|
||||
nrows -= go_back_chunks(nrows, &openfile->edittop, &openfile->firstcolumn);
|
||||
remainder = go_back_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
else
|
||||
nrows -= go_forward_chunks(nrows, &openfile->edittop, &openfile->firstcolumn);
|
||||
remainder = go_forward_chunks(1, &openfile->edittop, &openfile->firstcolumn);
|
||||
|
||||
/* Don't bother scrolling zero rows, nor more than the window can hold. */
|
||||
if (nrows == 0) {
|
||||
if (remainder > 0) {
|
||||
#ifndef NANO_TINY
|
||||
statusline(ALERT, "Underscrolling -- please report a bug");
|
||||
statusline(ALERT, "Could not scroll -- please report a bug");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (nrows >= editwinrows) {
|
||||
#ifndef NANO_TINY
|
||||
if (editwinrows > 1)
|
||||
statusline(ALERT, "Overscrolling -- please report a bug");
|
||||
#endif
|
||||
refresh_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Scroll the text of the edit window a number of rows up or down. */
|
||||
/* Actually scroll the text of the edit window one row up or down. */
|
||||
scrollok(edit, TRUE);
|
||||
wscrl(edit, (direction == BACKWARD) ? -nrows : nrows);
|
||||
wscrl(edit, (direction == BACKWARD) ? -1 : 1);
|
||||
scrollok(edit, FALSE);
|
||||
|
||||
/* Part 2: nrows is now the number of rows in the scrolled region of the
|
||||
* edit window that we need to draw. */
|
||||
|
||||
/* If we're not on the first "page" (when not softwrapping), or the mark
|
||||
* is on, the row next to the scrolled region needs to be redrawn too. */
|
||||
if (line_needs_update(openfile->placewewant, 0) && nrows < editwinrows)
|
||||
nrows++;
|
||||
|
||||
/* If we scrolled backward, start on the first line of the blank region. */
|
||||
/* If we scrolled backward, the top row needs to be redrawn. */
|
||||
line = openfile->edittop;
|
||||
leftedge = openfile->firstcolumn;
|
||||
|
||||
/* If we scrolled forward, move down to the start of the blank region. */
|
||||
/* If we scrolled forward, the bottom row needs to be redrawn. */
|
||||
if (direction == FORWARD)
|
||||
go_forward_chunks(editwinrows - nrows, &line, &leftedge);
|
||||
|
||||
@@ -2996,8 +2966,8 @@ void edit_scroll(bool direction, int nrows)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Draw new content on the blank rows inside the scrolled region
|
||||
* (and on the bordering row too when it was deemed necessary). */
|
||||
/* Draw new content on the blank row (and on the bordering row too
|
||||
* when it was deemed necessary). */
|
||||
while (nrows > 0 && line != NULL) {
|
||||
nrows -= update_line(line, (line == openfile->current) ?
|
||||
openfile->current_x : 0);
|
||||
@@ -3332,6 +3302,7 @@ void total_refresh(void)
|
||||
#endif
|
||||
if (currmenu != MBROWSER && currmenu != MWHEREISFILE && currmenu != MGOTODIR)
|
||||
edit_refresh();
|
||||
wipe_statusbar();
|
||||
bottombars(currmenu);
|
||||
}
|
||||
|
||||
@@ -3339,7 +3310,7 @@ void total_refresh(void)
|
||||
* portion of the window. */
|
||||
void display_main_list(void)
|
||||
{
|
||||
#ifdef ENABLE_COLOR
|
||||
#if defined(ENABLE_COLOR) && defined(ENABLE_SPELLER)
|
||||
if (openfile->syntax &&
|
||||
(openfile->syntax->formatter || openfile->syntax->linter))
|
||||
set_lint_or_format_shortcuts();
|
||||
@@ -3572,7 +3543,7 @@ void do_credits(void)
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"(C) 2017",
|
||||
"(C) 2018",
|
||||
"Free Software Foundation, Inc.",
|
||||
"",
|
||||
"",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for assembler.
|
||||
|
||||
syntax "asm" "\.(S|s|asm)$"
|
||||
syntax asm "\.(S|s|asm)$"
|
||||
magic "assembler source"
|
||||
comment "//"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Autoconf.
|
||||
|
||||
syntax "autoconf" "\.(ac|m4)$"
|
||||
syntax autoconf "\.(ac|m4)$"
|
||||
comment "#"
|
||||
|
||||
# Keywords:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for awk.
|
||||
|
||||
syntax "awk" "\.awk$"
|
||||
syntax awk "\.awk$"
|
||||
magic "awk script"
|
||||
comment "#"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for C/C++.
|
||||
|
||||
syntax "c" "\.(c(c|pp|xx|\+\+)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
|
||||
syntax c "\.(c(c|pp|xx|\+\+)?|C)$" "\.(h(h|pp|xx)?|H)$" "\.ii?$"
|
||||
magic "^(C|C\+\+) (source|program)"
|
||||
comment "//"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Colouring for Changelogs.
|
||||
|
||||
syntax "changelog" "Change[Ll]og.*"
|
||||
syntax changelog "Change[Ll]og.*"
|
||||
|
||||
# Author lines.
|
||||
color green "^(19|20).*$"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Syntax highlighting for CMake files.
|
||||
|
||||
syntax "cmake" "(CMakeLists\.txt|\.cmake)$"
|
||||
syntax cmake "(CMakeLists\.txt|\.cmake)$"
|
||||
comment "#"
|
||||
|
||||
icolor green "^[[:space:]]*[A-Z0-9_]+"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for CSS files.
|
||||
|
||||
syntax "css" "\.css$"
|
||||
syntax css "\.css$"
|
||||
comment "/*|*/"
|
||||
|
||||
color brightred "."
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for apt's sources.list.
|
||||
|
||||
syntax "sources.list" "sources\.list(~|\.old|\.save)?$" "sources\.list\.d/.*\.list(~|\.old|\.save)?$"
|
||||
syntax sources.list "sources\.list(~|\.old|\.save)?$" "sources\.list\.d/.*\.list(~|\.old|\.save)?$"
|
||||
comment "#"
|
||||
|
||||
# Coloring the deb lines, working from tail to head. First the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## An example of a default syntax. The default syntax is used for
|
||||
## files that do not match any other syntax.
|
||||
|
||||
syntax "default"
|
||||
syntax default
|
||||
comment "#"
|
||||
|
||||
# Comments.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Emacs Lisp.
|
||||
|
||||
syntax "elisp" "\.el$"
|
||||
syntax elisp "\.el$"
|
||||
magic "Lisp/Scheme program"
|
||||
comment ";"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Fortran 90/95.
|
||||
|
||||
syntax "fortran" "\.(f|f90|f95)$"
|
||||
syntax fortran "\.(f|f90|f95)$"
|
||||
comment "!"
|
||||
|
||||
color red "\<[0-9]+\>"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Here is an example for Gentoo ebuilds/eclasses,
|
||||
## and (further down) one for Portage control files.
|
||||
|
||||
syntax "ebuild" "\.e(build|class|blit)$"
|
||||
syntax ebuild "\.e(build|class|blit)$"
|
||||
comment "#"
|
||||
|
||||
## All the standard portage functions:
|
||||
@@ -48,7 +48,7 @@ color ,green "[[:space:]]+$"
|
||||
color ,green " "
|
||||
|
||||
|
||||
syntax "/etc/portage" "\.(accept_keywords|env|keywords|mask|unmask|use)(/.+)?$"
|
||||
syntax /etc/portage "\.(accept_keywords|env|keywords|mask|unmask|use)(/.+)?$"
|
||||
comment "#"
|
||||
|
||||
## Base text:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Go.
|
||||
|
||||
syntax "go" "\.go$"
|
||||
syntax go "\.go$"
|
||||
comment "//"
|
||||
|
||||
# Set up a formatter since spelling is probably useless...
|
||||
@@ -24,9 +24,11 @@ color brightcyan "\<(package|import)\>"
|
||||
color brightcyan "//[[:space:]]*\+build[[:space:]]+(([a-zA-Z_0-9]+[[:space:]]*)+,[[:space:]]*)*[a-zA-Z_0-9]+"
|
||||
|
||||
# Literals.
|
||||
color red "\<[0-9]+(\.[0-9]*)?([Ee][+-]?[0-9]+)?i?\>"
|
||||
color red "\B\.[0-9]+([Ee][+-]?[0-9]+)?i?\>"
|
||||
color red "\<(0[0-7]*|[1-9][0-9]*|0[xX][0-9a-fA-F]+)\>"
|
||||
color red "\<([1-9][0-9]*|0[0-7]*|0[xX][0-9A-Fa-f]+)\>"
|
||||
color red "\<[0-9]+\.[0-9]*([eE][+-]?[0-9]+)?i?\>"
|
||||
color red "\<[0-9]+[eE][+-]?[0-9]+i?\>"
|
||||
color red "\B\.[0-9]+([eE][+-]?[0-9]+)?i?\>"
|
||||
color red "\<[0-9]+i\>"
|
||||
|
||||
# Strings and characters; slightly fuzzy.
|
||||
color red "\<(true|false|nil|iota|_)\>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for groff.
|
||||
|
||||
syntax "groff" "\.m[ems]$" "\.rof" "\.tmac$" "^tmac."
|
||||
syntax groff "\.m[ems]$" "\.rof" "\.tmac$" "^tmac."
|
||||
comment ".\""
|
||||
|
||||
# The argument of .ds or .nr
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Guile Scheme.
|
||||
|
||||
syntax "guile" "\.scm$"
|
||||
syntax guile "\.scm$"
|
||||
header "^#!.*guile"
|
||||
comment ";"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for HTML.
|
||||
|
||||
syntax "html" "\.html?$"
|
||||
syntax html "\.html?$"
|
||||
magic "HTML document"
|
||||
comment "<!--|-->"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Java.
|
||||
|
||||
syntax "java" "\.java$"
|
||||
syntax java "\.java$"
|
||||
magic "Java "
|
||||
comment "//"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Syntax highlighting for Javascript.
|
||||
|
||||
syntax "javascript" "\.js$"
|
||||
syntax javascript "\.js$"
|
||||
comment "//"
|
||||
|
||||
# Declarational stuff.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Original author: Aapo Rantalainen
|
||||
# License: GPLv3 or newer
|
||||
|
||||
syntax "json" "\.json$"
|
||||
syntax json "\.json$"
|
||||
# No comments are permitted in JSON.
|
||||
comment ""
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
## Original author: Matthew Wild <mwild1 (at) gmail.com>
|
||||
## License: GPL 3 or later
|
||||
|
||||
syntax "lua" "\.lua$"
|
||||
syntax lua "\.lua$"
|
||||
magic "Lua script"
|
||||
comment "--"
|
||||
|
||||
@@ -20,7 +20,7 @@ color brightyellow "\<(_G|_VERSION|assert|collectgarbage|dofile|error|getfenv|ge
|
||||
|
||||
# Standard library
|
||||
color brightyellow "\<coroutine\.(create|isyieldable|resume|running|status|wrap|yield)\>"
|
||||
color brightyellow "\<debug\.(debug|(get|set)(fenv|hook|info|local|metatable|(up|user)value)|getregistry|traceback|upvalue(id|join))\>"
|
||||
color brightyellow "\<debug\.(debug|(get|set)(fenv|hook|local|metatable|(up|user)value)|getinfo|getregistry|traceback|upvalue(id|join))\>"
|
||||
color brightyellow "\<io\.(close|flush|input|lines|output|p?open|read|tmpfile|type|write|std(in|out|err))\>"
|
||||
color brightyellow "\<math\.(abs|acos|asin|atan2?|ceil|cosh?|deg|exp|floor|fmod|frexp|huge|ldexp|log10|log)\>"
|
||||
color brightyellow "\<math\.((max|min)(integer)?|modf?|pi|pow|rad|random(seed)?|sinh?|sqrt|tan|tointeger|type|ult)\>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Makefiles.
|
||||
|
||||
syntax "makefile" "Makefile[^/]*$" "\.(make|mk)$"
|
||||
syntax makefile "Makefile[^/]*$" "\.(make|mk)$"
|
||||
magic "makefile script"
|
||||
comment "#"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for manpages.
|
||||
|
||||
syntax "man" "\.[1-9]x?$"
|
||||
syntax man "\.[1-9]x?$"
|
||||
magic "troff or preprocessor input"
|
||||
comment ".\""
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Magicpoint presentations.
|
||||
|
||||
syntax "mgp" "\.mgp$"
|
||||
syntax mgp "\.mgp$"
|
||||
header "^%include.*"
|
||||
comment "#"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for quoted emails (under e.g. mutt).
|
||||
|
||||
syntax "mutt"
|
||||
syntax mutt
|
||||
|
||||
# Quoted lines.
|
||||
color green "^>.*"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
## This is meant for highlighting key combos in a nano help text.
|
||||
|
||||
# It should not apply to any normal file, so no fileregex.
|
||||
syntax "nanohelp"
|
||||
syntax nanohelp
|
||||
|
||||
# Key combos:
|
||||
color cyan "\^[]4-8A-Z^\_◀▶▲▼]" "[◀▶▲▼]" "(\^|M-)Space" "\<M-." "\<F1?[0-9]"
|
||||
color cyan "\<(Tab|Enter|Ins|Del|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
|
||||
color cyan "\<(Tab|Sh-Tab|Enter|Ins|Del|Bsp|Up|Down|Left|Right|Home|End|PgUp|PgDn)\>"
|
||||
|
||||
# Quoted indicators:
|
||||
color brightred "'(\^|M-)'"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for nanorc files.
|
||||
|
||||
syntax "nanorc" "\.?nanorc$"
|
||||
syntax nanorc "\.?nanorc$"
|
||||
comment "#"
|
||||
|
||||
# Possible errors and parameters
|
||||
@@ -8,19 +8,19 @@ icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comm
|
||||
|
||||
# Keywords
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cutfromcursor|fill[[:space:]]+-?[[:digit:]]+|historylog|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize[[:space:]]+[1-9][0-9]*|tabstospaces|tempfile|trimblanks|unix|view|wordbounds)\>"
|
||||
icolor yellow "^[[:space:]]*set[[:space:]]+((function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
||||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+[[:alpha:]]+[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor yellow "^[[:space:]]*set[[:space:]]+((error|function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|titlecolor|whitespace|wordchars)[[:space:]]+"
|
||||
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+([[:alpha:]]+|".*")[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|linter|formatter)[[:space:]]+.*$"
|
||||
icolor brightgreen "^[[:space:]]*(linter|formatter)[[:space:]]+[[:alpha:]]+"
|
||||
icolor brightgreen "^[[:space:]]*(syntax|linter|formatter)[[:space:]]+[^[:blank:]]+"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|formatter|extendsyntax)\>"
|
||||
|
||||
# Strings
|
||||
color brightmagenta "".+"([[:space:]]|$)"
|
||||
|
||||
# Colors
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan|normal)?(,(white|black|red|blue|green|yellow|magenta|cyan|normal))?\>"
|
||||
icolor magenta "^[[:space:]]*i?color\>" "\<(start|end)="
|
||||
|
||||
# Comments
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for nftables.
|
||||
|
||||
syntax "nftables" "\.(nft|nftables)$"
|
||||
syntax nftables "\.(nft|nftables)$"
|
||||
header "^#!.*(nft|nftables)"
|
||||
comment "#"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for C/C++/Obj-C.
|
||||
|
||||
syntax "m" "\.m$"
|
||||
syntax m "\.m$"
|
||||
magic "Objective-C source"
|
||||
comment "//"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Syntax highlighting for OCaml.
|
||||
|
||||
syntax "ocaml" "\.mli?$"
|
||||
syntax ocaml "\.mli?$"
|
||||
magic "OCaml"
|
||||
comment "(*|*)"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for patch files.
|
||||
|
||||
syntax "patch" "\.(patch|diff|debdiff)$"
|
||||
syntax patch "\.(patch|diff|debdiff)$"
|
||||
magic "diff output"
|
||||
# There is no official support for comments in patch files.
|
||||
comment ""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for Perl.
|
||||
|
||||
syntax "perl" "\.p[lm]$"
|
||||
syntax perl "\.p[lm]$"
|
||||
header "^#!.*perl[-0-9._]*"
|
||||
magic "Perl script"
|
||||
comment "#"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for PHP.
|
||||
|
||||
syntax "php" "\.ph(p[23457s~]?|tml)$"
|
||||
syntax php "\.ph(p[23457s~]?|tml)$"
|
||||
magic "PHP script"
|
||||
comment "//"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user