Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72b13adeff | ||
|
|
481178428b | ||
|
|
9a2ef3a542 | ||
|
|
b480e7fc9c | ||
|
|
3e33d1eba6 | ||
|
|
cdb9b04980 | ||
|
|
31ff7ead73 | ||
|
|
5398d986ef | ||
|
|
b02dccc51f | ||
|
|
3158133edd | ||
|
|
acf50ae26d | ||
|
|
01b840890d | ||
|
|
9bd60e7d5d | ||
|
|
c5e46101b1 | ||
|
|
53b77cb4c6 | ||
|
|
cc4ce8d83b | ||
|
|
23c8ef70aa | ||
|
|
2a4d338d97 | ||
|
|
9c202198a3 | ||
|
|
c8dc67717b | ||
|
|
4df2f81295 | ||
|
|
78def852d1 | ||
|
|
a4933873c9 | ||
|
|
1861052234 | ||
|
|
2307b31887 | ||
|
|
108a3b0b41 | ||
|
|
e0d9b7a8af | ||
|
|
b3ace4d8f6 | ||
|
|
e9d6ceab0b | ||
|
|
5103bfe6b8 | ||
|
|
cfd17f5722 | ||
|
|
43235c2f16 | ||
|
|
b14ad451a9 | ||
|
|
cd00d0975e | ||
|
|
40f6dbc34e | ||
|
|
a9fb56a8c9 | ||
|
|
07c0d29276 | ||
|
|
310c971d50 | ||
|
|
3644d51b97 | ||
|
|
591d3170aa | ||
|
|
752dde1130 | ||
|
|
b5eda7f812 | ||
|
|
4d44b03fc8 | ||
|
|
2d16c27820 | ||
|
|
ad65b79ac7 | ||
|
|
fe5bd8cdef | ||
|
|
c848ec3d53 | ||
|
|
ab6390cad0 | ||
|
|
48124fdba4 | ||
|
|
ebd9eb346d | ||
|
|
413116e1b5 | ||
|
|
69a3d39bc4 | ||
|
|
f081fa3047 | ||
|
|
4383b01b9b | ||
|
|
b901a20a06 | ||
|
|
d6e05d8376 | ||
|
|
21e307e820 | ||
|
|
dbcf4f0cbe | ||
|
|
7b88557ef5 | ||
|
|
75a6abe6d2 | ||
|
|
ba5b85baf0 | ||
|
|
9f95fa9ce5 | ||
|
|
8853bc448d | ||
|
|
15148a5e6d | ||
|
|
7d9ad31cd9 | ||
|
|
aecbc6faa9 | ||
|
|
a06b921f12 | ||
|
|
bdf1a9d4e7 | ||
|
|
5c399dfc6e | ||
|
|
ed4b6486a1 | ||
|
|
2326bf695e | ||
|
|
a9dd73fb16 | ||
|
|
073bd3ad6e | ||
|
|
4bcc224560 | ||
|
|
f2f367ba9c | ||
|
|
48bff32ee3 | ||
|
|
304f07258b | ||
|
|
e1c2573c7a | ||
|
|
07ec7de8eb | ||
|
|
82f5fed45a | ||
|
|
a2f7e31ba2 | ||
|
|
55983ee9d1 | ||
|
|
cd274a7830 | ||
|
|
f773fa3968 | ||
|
|
288355686b | ||
|
|
f7d5a82a5d | ||
|
|
63e04ac31e | ||
|
|
0c63b50fdc | ||
|
|
94c9defde1 | ||
|
|
ee91c51e09 | ||
|
|
1e3f3a7511 | ||
|
|
8fce33afe0 | ||
|
|
4314b8ded3 | ||
|
|
52e39ae5f7 | ||
|
|
5e7ba03ad1 | ||
|
|
97fec5603f | ||
|
|
3b8847f319 | ||
|
|
a578d2706c | ||
|
|
44d38815cc | ||
|
|
b23a5d5b29 | ||
|
|
b96cc8c212 | ||
|
|
09ad0eb5f7 | ||
|
|
62ca113ed3 | ||
|
|
5cfb74650d | ||
|
|
8cd6aa0a32 | ||
|
|
fcbe41942f | ||
|
|
39e5b52734 | ||
|
|
70b347183b | ||
|
|
699cacf7a4 | ||
|
|
23cb26c58f | ||
|
|
3422ec3419 | ||
|
|
5f1d9af375 | ||
|
|
f3a441043d | ||
|
|
e6c629951f | ||
|
|
c06d5452f5 | ||
|
|
1fcb9b99cf | ||
|
|
d8c840692e | ||
|
|
8c7b6bd21a | ||
|
|
21d0755de5 | ||
|
|
bbab9e2e62 | ||
|
|
9ea1cd947c |
136
ChangeLog
136
ChangeLog
@@ -1,3 +1,139 @@
|
||||
Changes between v4.4 and v4.5:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (60):
|
||||
bindings: add a dedicated keycode for <Tab> for when a region is marked
|
||||
bump version numbers and add a news item for the 4.5 release
|
||||
color: don't concatenate an absolute path with the working directory
|
||||
docs: add two examples of the 'tabgives' command to the sample nanorc
|
||||
docs: describe the new syntax-specific 'tabgives' command
|
||||
docs: mark the undoing of justifications as done in the TODO list
|
||||
docs: mention that gcc must be at least version 5.0
|
||||
gnulib: update to its current upstream state
|
||||
mouse: make the clickable width of menu items more consistent
|
||||
new feature: a 'tabgives' command to define what the Tab key produces
|
||||
search: after search-at-startup, store the column (for vertical movement)
|
||||
tweaks: add a translator hint, and correct two others
|
||||
tweaks: add some translator hints, be more precise on permissible length
|
||||
tweaks: add two hints for translators, to try and help avoid mistakes
|
||||
tweaks: adjust indentation after previous change, reshuffle declarations
|
||||
tweaks: avoid a comparison between signed and unsigned [coverity]
|
||||
tweaks: avoid leaking memory when finding an invalid string [coverity]
|
||||
tweaks: avoid recomputing a maximum value every time round the loop
|
||||
tweaks: don't burden all menus with something meant for the WriteOut menu
|
||||
tweaks: elide a function from a non-UTF8 build
|
||||
tweaks: elide two multiplications with something that is always 1
|
||||
tweaks: frob a few comments
|
||||
tweaks: improve a bunch of comments, and reshuffle some declarations
|
||||
tweaks: improve a handful of comments, and reduce the needed padding
|
||||
tweaks: mark as 'const' a parameter that takes fixed strings [coverity]
|
||||
tweaks: meld two calls of free() into a single one, to elide an 'else'
|
||||
tweaks: move a fragment of common code into the appropriate function
|
||||
tweaks: move a function to a better file, to be amongst its kind
|
||||
tweaks: move a function to before its callers and next to its kind
|
||||
tweaks: move two functions to after the ones that they call
|
||||
tweaks: remove some timing code that has served its purpose
|
||||
tweaks: remove two superfluous macros, as sizeof(char) is always 1
|
||||
tweaks: rename a function, to be a bit more fitting
|
||||
tweaks: rename another type, again to better fit the general pattern
|
||||
tweaks: rename another type, to also better fit the general pattern
|
||||
tweaks: rename another variable, for a better fit
|
||||
tweaks: rename a type, to better fit the general pattern
|
||||
tweaks: rename a variable, normalize a comment, and reshuffle a free()
|
||||
tweaks: rename a variable, to be more compact
|
||||
tweaks: rename three variables, for contrast and more sense
|
||||
tweaks: rename three variables, for more contrast
|
||||
tweaks: rename three variables, to better indicate what they hold
|
||||
tweaks: rename two variables, away from single letters
|
||||
tweaks: rename two variables, to better describe what they contain
|
||||
tweaks: reshuffle a fragment, to group some toggles together
|
||||
tweaks: reshuffle a line, to group things better
|
||||
tweaks: reshuffle some lines, to elide an unneeded assignment
|
||||
tweaks: reshuffle some lines, to have the same order as elsewhere
|
||||
tweaks: reshuffle two fragments, to group things better
|
||||
tweaks: rewrap a line, reshuffle a declaration, and improve some comments
|
||||
tweaks: simplify a calculation, as done elsewhere
|
||||
tweaks: simplify the determination of a canonical path
|
||||
tweaks: sort two keywords strictly alphabetically
|
||||
tweaks: speed up determining the width of plain ASCII characters
|
||||
tweaks: speed up the counting of the menu entries to be shown
|
||||
tweaks: use a more effecient way to skip storing an empty file name
|
||||
tweaks: use an early return when there is no tilde
|
||||
tweaks: use 'void' in prototypes of parameterless functions [coverity]
|
||||
usage: mark the -J/--guidestripe option plus argument as translatable
|
||||
usage: properly align --help output also when it has accented characters
|
||||
|
||||
Brand Huntsman (1):
|
||||
search: accept a match at start of file when searching from command line
|
||||
|
||||
Dirkjan Ochtman (1):
|
||||
syntax: rust: add the words reserved in 2018, and remove unreserved ones
|
||||
|
||||
|
||||
Changes between v4.3 and v4.4:
|
||||
------------------------------
|
||||
|
||||
Benno Schulenberg (53):
|
||||
browser: draw a bar of spaces only where needed -- for the selected item
|
||||
build: exclude the search-at-startup feature from the tiny version
|
||||
bump version numbers and add a news item for the 4.4 release
|
||||
copying: do not prevent M-6 from copying emptiness into the cutbuffer
|
||||
display: blank the status bar on a successful cut or paste
|
||||
display: clear the remainder of a row only when there actually is some
|
||||
display: don't clear a row beforehand -- just clear the remainder
|
||||
display: use a somewhat faster method to clear a row
|
||||
display: when linenumbering, correctly spotlight text that spans two rows
|
||||
display: where needed, use slow blanking, but elsewhere do it much faster
|
||||
docs: change a few URLs over to https, and rewrap a couple of NEWS items
|
||||
docs: document the search-at-startup feature (+/string or +?string)
|
||||
docs: make the synopsis of --speller and 'set speller' more accurate
|
||||
docs: mention the M-N toggle instead of the obsolete M-# one
|
||||
docs: slightly reword some of the descriptions around syntax highlighting
|
||||
docs: slightly reword the descriptions of most configure options
|
||||
docs: stop mentioning the 'unjustify' function, as it no longer exists
|
||||
gnulib: update to its current upstream state
|
||||
new document: a condensed overview of nano's shortcut keystrokes
|
||||
new feature: allow specifying a search string to "jump to" at startup
|
||||
rcfile: properly handle an empty syntax before an 'include' statement
|
||||
scrolling: don't overscroll when the edit window has just one row
|
||||
search: don't wipe the status bar at startup when there was an error
|
||||
search: wipe the status bar before searching again (M-W / M-Q)
|
||||
syntax: c: allow an underscore in lowercase type names
|
||||
syntax: default: colorize bracketed section headers in some config files
|
||||
syntaxes: change some unneeded 'icolor' commands to 'color' commands
|
||||
syntaxes: recognize .ctp extension as a PHP file, and .cu as a C/C++ file
|
||||
syntax: perl: avoid recognizing embedded hash signs as a comment starter
|
||||
syntax: perl: avoid upsetting older glibcs with crafty range expression
|
||||
syntax: perl: don't color the character after a variable name
|
||||
syntax: po: colorize numbers only when they form a self-contained word
|
||||
text: copy leading quote characters when automatic hard-wrapping occurs
|
||||
tweaks: add a translator hint, to clarify four short words
|
||||
tweaks: call the correct lighting function directly when softwrapping
|
||||
tweaks: condense some comments, and drop two unneeded initializations
|
||||
tweaks: drop two parameters that are no longer needed
|
||||
tweaks: improve a comment, and drop a superfluous one
|
||||
tweaks: improve a handful of comments
|
||||
tweaks: make a function name unique, to not overlap with others
|
||||
tweaks: move a call from two different places to a single place
|
||||
tweaks: move a function to before the first one that calls it
|
||||
tweaks: move a general function to a better place
|
||||
tweaks: remove a saving and restoring that has become superfluous
|
||||
tweaks: rename a function, to suit better, and reshuffle its parameters
|
||||
tweaks: rename a parameter in three functions, to say what it points to
|
||||
tweaks: reshuffle an assignment, and trim some excessive blank lines
|
||||
tweaks: reshuffle an 'if' out of a function, and rename the function
|
||||
tweaks: reword and condense two comments, and correct another
|
||||
tweaks: rewrap two lines, and reshuffle some logic to make more sense
|
||||
tweaks: shorten two messages that translators tend to make too long
|
||||
tweaks: try the allocation of a multidata cache just once per line
|
||||
tweaks: when precalculating, allocate all the cache space upfront
|
||||
|
||||
Brand Huntsman (3):
|
||||
rcfile: for an empty syntax, show the line number of the 'syntax' command
|
||||
rcfile: report the correct command location for an invalid 'include'
|
||||
search: accept toggles for case and regex when searching at startup
|
||||
|
||||
|
||||
Changes between v4.2 and v4.3:
|
||||
------------------------------
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@ Improvements in GNU nano
|
||||
========================
|
||||
|
||||
Since 4.0:
|
||||
- What the <Tab> key produces can be specified per syntax with 'tabgives'.
|
||||
- The ability to perform a search at startup with +/string or +?string.
|
||||
- Comment characters are copied when automatic hard-wrapping occurs.
|
||||
- The ability to both read from and write to a FIFO.
|
||||
- Automatic hard-wrapping is no longer the default.
|
||||
- Addition of --guidestripe to draw a helpful vertical bar.
|
||||
|
||||
93
NEWS
93
NEWS
@@ -1,3 +1,16 @@
|
||||
2019.10.04 - GNU nano 4.5 "Košice"
|
||||
• The new 'tabgives' command allows you to specify per syntax what
|
||||
the <Tab> key should produce: some spaces, a hard TAB, ...
|
||||
• The output of --help is properly aligned again for all languages.
|
||||
• <Tab> will indent a marked region also when M-} has been rebound.
|
||||
|
||||
2019.08.25 - GNU nano 4.4 "Hagelslag"
|
||||
• At startup, the cursor can be put on the first or last occurrence
|
||||
of a string by preceding the filename with +/string or +?string.
|
||||
• When automatic hard-wrapping occurs (--breaklonglines), any leading
|
||||
quoting characters will be automatically copied to the new line.
|
||||
• M-6 works again also when the cursor is at end of buffer.
|
||||
|
||||
2019.06.18 - GNU nano 4.3 "Musa Kart"
|
||||
• The ability to read from and write to a FIFO has been regained.
|
||||
• Startup time is reduced by fully parsing a syntax only when needed.
|
||||
@@ -615,7 +628,7 @@
|
||||
like this what could POSSIBLY go WRONG? Hahaha.
|
||||
Enjoy and if you find new bugs, as always please
|
||||
use Savannah's bug tracker.
|
||||
http://savannah.gnu.org/bugs/?func=additem&group=nano
|
||||
https://savannah.gnu.org/bugs/?func=additem&group=nano
|
||||
|
||||
2010.01.17 - GNU nano 2.2.2 is released for you, you, you. This
|
||||
release includes fixes for: crashes when writing
|
||||
@@ -700,7 +713,7 @@
|
||||
editor, via the -$ or --softwrap command-line flags,
|
||||
or via "set softwrap" in your .nanorc. As always,
|
||||
please report any bugs to the nano Savannah project page
|
||||
(http://savannah.gnu.org/bugs/?func=additem&group=nano)
|
||||
(https://savannah.gnu.org/bugs/?func=additem&group=nano)
|
||||
Remember: data loss happens, back up your files.
|
||||
|
||||
2009.07.28 - GNU nano 2.1.10 "Ellie" is released. This version includes
|
||||
@@ -728,45 +741,41 @@
|
||||
birthday lenny!
|
||||
|
||||
2009.02.07 - GNU nano 2.1.8 "unsafe at any speed" is released. This
|
||||
release include some long overdue performance
|
||||
improvements in syntax color highlighting, the ability
|
||||
to abort running searches (useful mainly when
|
||||
editing very large files) and the ability to use nano
|
||||
like a pager for viewing standard input (i.e. "nano -").
|
||||
Additionally, there are gentoo syntax highlighting
|
||||
updates and fixes for issues with reading files
|
||||
in a directory with strange parent directory permissions.
|
||||
The key bindings code was also substantially changed
|
||||
in order to be more ISO-C compatible. Be sure to use
|
||||
the Savannah page not only for bug reports but for any
|
||||
release includes some long overdue performance improvements
|
||||
in syntax color highlighting, the ability to abort running
|
||||
searches (useful mainly when editing very large files) and
|
||||
the ability to use nano like a pager for viewing standard
|
||||
input (i.e. "nano -"). Additionally, there are gentoo
|
||||
syntax highlighting updates and fixes for issues with
|
||||
reading files in a directory with strange parent directory
|
||||
permissions. The key-bindings code was also substantially
|
||||
changed in order to be more ISO-C compatible. Be sure to
|
||||
use the Savannah page not only for bug reports but for any
|
||||
features you would like to see before the next stable
|
||||
series is released. Have fun with it!
|
||||
|
||||
2008.11.10 - GNU nano 2.1.7 "Effingham" is ready to make good on those
|
||||
campaign promises of lower bug rates and 50% more pie.
|
||||
This release includes a new check for external
|
||||
modifications when saving a file, some code and
|
||||
documentation cleanups, and more bug fixes for
|
||||
the new undo code (but we continue to welcome
|
||||
your bug reports via the Savannah bug page at
|
||||
http://savannah.gnu.org/bugs/?func=additem&group=nano).
|
||||
This release includes a new check for external modifications
|
||||
when saving a file, some code and documentation cleanups,
|
||||
and more bug fixes for the new undo code (but we continue
|
||||
to welcome your bug reports via the Savannah bug page at
|
||||
https://savannah.gnu.org/bugs/?func=additem&group=nano).
|
||||
Come get some.
|
||||
|
||||
2008.10.03 - GNU nano 2.1.6 was for new features before it was against
|
||||
them. This release includes more undo capability,
|
||||
several new syntax highlighting configurations including
|
||||
Objective C, OCaml, and Fortran, and a new capability
|
||||
to activate highlighting based on the 1st line of the
|
||||
file being edited. Also, the new default configure
|
||||
options now include color syntax highlighting, .nanorc
|
||||
support, multibuffer and extras. These items can still
|
||||
be disabled and are not enabled with --enable-tiny. Bug
|
||||
fixes include better signal handling under Cygwin, and
|
||||
that's about it. Again please remember to
|
||||
submit bug reports via Savannah at
|
||||
http://savannah.gnu.org/bugs/?func=additem&group=nano
|
||||
as undo functions certainly need more testing.
|
||||
Bon appetit.
|
||||
them. This release includes more undo capability, several
|
||||
new syntax highlighting configurations including Objective
|
||||
C, OCaml, and Fortran, and a new capability to activate
|
||||
highlighting based on the 1st line of the file being
|
||||
edited. Also, the new default configure options now
|
||||
include color syntax highlighting, .nanorc support,
|
||||
multibuffer and extras. These items can still be disabled
|
||||
and are not enabled with --enable-tiny. Bug fixes include
|
||||
better signal handling under Cygwin, and that's about it.
|
||||
Again please remember to submit bug reports via Savannah at
|
||||
https://savannah.gnu.org/bugs/?func=additem&group=nano as
|
||||
undo functions certainly need more testing. Bon appetit.
|
||||
|
||||
2008.08.30 - GNU nano 2.1.5 is ready to lead on day one. This release
|
||||
contains a better fix for incorrectly reported successful
|
||||
@@ -789,15 +798,15 @@
|
||||
are likely to run out of space; see Savannah bug #24000.
|
||||
Have fun with it!
|
||||
|
||||
2008.08.04 - GNU nano 2.1.3 "least stable version ever" is released. This
|
||||
release includes new (and experimental) undo and redo
|
||||
functionality for most text operations. The default
|
||||
key bindings are Meta-U for undo and Meta-E for redo, but
|
||||
these can be remapped using the new 2.1 keybinding code.
|
||||
Also included are some fixes for configuring using wide
|
||||
curses, crashing when invoking the help menu with
|
||||
certain locales, and not saving the search history when
|
||||
compiled with configure options.
|
||||
2008.08.04 - GNU nano 2.1.3 "least stable version ever" is released.
|
||||
This release includes new (and experimental) undo and redo
|
||||
functionality for most text operations. The default key
|
||||
bindings are Meta-U for undo and Meta-E for redo, but these
|
||||
can be remapped using the new 2.1 keybinding code. Also
|
||||
included are some fixes for configuring using wide curses,
|
||||
crashing when invoking the help menu with certain locales,
|
||||
and not saving the search history when compiled with
|
||||
configure options.
|
||||
|
||||
2008.04.24 - GNU nano 2.1.2 "New York City" is released. This release
|
||||
contains fixes for binding bad keys, some
|
||||
|
||||
@@ -14,13 +14,13 @@ packages:
|
||||
- autoconf (version >= 2.69)
|
||||
- automake (version >= 1.14)
|
||||
- autopoint (version >= 0.18.3)
|
||||
- gcc (version >= 5.0)
|
||||
- gettext (version >= 0.18.3)
|
||||
- git (version >= 2.7.4)
|
||||
- groff (version >= 1.12)
|
||||
- make (any version)
|
||||
- pkg-config (version >= 0.22)
|
||||
- texinfo (version >= 4.0)
|
||||
- gcc (any version)
|
||||
- make (any version)
|
||||
|
||||
If you want UTF-8 support, you will also need libncursesw5-dev installed
|
||||
(version >= 5.7), or libslang2-dev (version >= 2.0) if you use --with-slang.
|
||||
|
||||
4
TODO
4
TODO
@@ -2,7 +2,6 @@ A list of desired features
|
||||
--------------------------
|
||||
|
||||
Somewhat urgent:
|
||||
- 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 color syntaxes to apply to more than just color, so that we can
|
||||
@@ -17,6 +16,9 @@ Vague musings:
|
||||
- Make matching bracket searches sophisticated enough to skip over
|
||||
brackets inside comments?
|
||||
|
||||
For version 4.0:
|
||||
- Make undo/redo work also for justifying. [DONE]
|
||||
|
||||
For version 2.9:
|
||||
- Allow piping (marked) text to an external command and replacing it with
|
||||
the command's output. That is: implement filtering. [DONE]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generate configure & friends for GIT users.
|
||||
|
||||
gnulib_url="git://git.sv.gnu.org/gnulib.git"
|
||||
gnulib_hash="a1beabcb14cde661c36f7a3c7c17b5871704003e"
|
||||
gnulib_hash="ab02af9d47248a1d8b4ade4e8ab2c927d0543ea1"
|
||||
|
||||
modules="
|
||||
futimens
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
AC_INIT([GNU nano], [4.3], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [4.5], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.14])
|
||||
|
||||
131
doc/cheatsheet.html
Normal file
131
doc/cheatsheet.html
Normal file
@@ -0,0 +1,131 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Cheatsheet for nano</title>
|
||||
<meta name="description" content="nano">
|
||||
<meta name="keywords" content="cheatsheet, nano, editor, shortcuts, keystrokes, functions">
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
|
||||
<br>
|
||||
<h1 align="center">Overview of nano's shortcuts </h1>
|
||||
<h3 align="center">The editor's keystrokes and their functions </h3>
|
||||
<br>
|
||||
|
||||
<table align="center"><tbody>
|
||||
<tr><td>
|
||||
|
||||
<b>File handling</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+S </td><td>Save current file</td></tr>
|
||||
<tr><td>Ctrl+O </td><td> Offer to write file ("Save as")</td></tr>
|
||||
<tr><td>Ctrl+R </td><td> Insert a file into current one</td></tr>
|
||||
<tr><td>Ctrl+X </td><td> Close buffer, exit from nano</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
<b>Editing</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+K </td><td>Cut current line into cutbuffer</td></tr>
|
||||
<tr><td>Alt+6</td><td>Copy current line into cutbuffer</td></tr>
|
||||
<tr><td>Ctrl+U</td><td>Paste contents of cutbuffer</td></tr>
|
||||
<tr><td>Alt+T</td><td>Cut until end of buffer</td></tr>
|
||||
<tr><td>Ctrl+]</td><td>Complete current word</td></tr>
|
||||
<tr><td>Alt+3</td><td>Comment/uncomment line/region</td></tr>
|
||||
<tr><td>Alt+U</td><td>Undo last action</td></tr>
|
||||
<tr><td>Alt+E</td><td>Redo last undone action</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
<b>Search and replace</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+Q </td><td>Start backward search</td></tr>
|
||||
<tr><td>Ctrl+W</td><td>Start forward search</td></tr>
|
||||
<tr><td>Alt+Q</td><td>Find next occurrence backward</td></tr>
|
||||
<tr><td>Alt+W</td><td>Find next occurrence forward</td></tr>
|
||||
<tr><td>Alt+R</td><td>Start a replacing session</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
<b>Deletion</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+H</td><td>Delete character before cursor </td></tr>
|
||||
<tr><td>Ctrl+D</td><td>Delete character under cursor</td></tr>
|
||||
<tr><td>Ctrl+Shift+Del </td><td>Delete word to the left</td></tr>
|
||||
<tr><td>Ctrl+Del</td><td>Delete word to the right</td></tr>
|
||||
<tr><td>Alt+Del</td><td>Delete current line</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
<b>Operations</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+T </td><td>Run a spell check</td></tr>
|
||||
<tr><td>Ctrl+J</td><td>Justify paragraph or region</td></tr>
|
||||
<tr><td>Alt+J</td><td>Justify entire buffer</td></tr>
|
||||
<tr><td>Alt+B</td><td>Run a syntax check</td></tr>
|
||||
<tr><td>Alt+:</td><td>Start/stop recording of macro</td></tr>
|
||||
<tr><td>Alt+;</td><td>Replay macro</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
</td><td>
|
||||
|
||||
<b>Moving around</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+B </td><td>One character backward</td></tr>
|
||||
<tr><td>Ctrl+F</td><td>One character forward</td></tr>
|
||||
<tr><td>Ctrl+⯇</td><td>One word backward</td></tr>
|
||||
<tr><td>Ctrl+⯈</td><td>One word forward</td></tr>
|
||||
<tr><td>Ctrl+A</td><td>To start of line</td></tr>
|
||||
<tr><td>Ctrl+E</td><td>To end of line</td></tr>
|
||||
<tr><td>Ctrl+P</td><td>One line up</td></tr>
|
||||
<tr><td>Ctrl+N</td><td>One line down</td></tr>
|
||||
<tr><td>Ctrl+⯅</td><td>To previous block</td></tr>
|
||||
<tr><td>Ctrl+⯆</td><td>To next block</td></tr>
|
||||
<tr><td>Ctrl+Y</td><td>One page up</td></tr>
|
||||
<tr><td>Ctrl+V</td><td>One page down</td></tr>
|
||||
<tr><td>Alt+\</td><td>To top of buffer</td></tr>
|
||||
<tr><td>Alt+/</td><td>To end of buffer</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
<b>Special movement</b>
|
||||
<table><tbody>
|
||||
<tr><td>Alt+G </td><td>Go to specified line</td></tr>
|
||||
<tr><td>Alt+]</td><td>Go to complementary bracket</td></tr>
|
||||
<tr><td>Alt+⯅</td><td>Scroll viewport up</td></tr>
|
||||
<tr><td>Alt+⯆</td><td>Scroll viewport down</td></tr>
|
||||
<tr><td>Alt+<</td><td>Switch to preceding buffer</td></tr>
|
||||
<tr><td>Alt+></td><td>Switch to succeeding buffer</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
<b>Information</b>
|
||||
<table><tbody>
|
||||
<tr><td>Ctrl+C </td><td>Report cursor position</td></tr>
|
||||
<tr><td>Alt+D</td><td>Report word/line/char count</td></tr>
|
||||
<tr><td>Ctrl+G</td><td>Display help text</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
<b>Various</b>
|
||||
<table><tbody>
|
||||
<tr><td>Alt+A</td><td>Turn the mark on/off</td></tr>
|
||||
<tr><td>Tab</td><td>Indent marked region</td></tr>
|
||||
<tr><td>Shift+Tab </td><td>Unindent marked region</td></tr>
|
||||
<tr><td>Alt+P</td><td>Turn visible whitespace on/off</td></tr>
|
||||
<tr><td>Alt+V</td><td>Enter next keystroke verbatim</td></tr>
|
||||
<tr><td>Ctrl+L</td><td>Refresh the screen</td></tr>
|
||||
<tr><td>Ctrl+Z</td><td>Suspend nano</td></tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
|
||||
</td></tr>
|
||||
</tbody></table>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -85,7 +85,7 @@
|
||||
<h3><a name="1.3"></a>1.3. Why the name change from TIP?</h3>
|
||||
<blockquote><p>On January 10, 2000, TIP was officially renamed to nano because of a namespace conflict with another program called 'tip'. The original 'tip' program "establishes a full duplex terminal connection to a remote host", and was included with many older Unix systems (and newer ones like Solaris). The conflict was not noticed at first because there is no 'tip' utility included with most GNU/Linux distributions (where nano was developed).</p></blockquote>
|
||||
<h3><a name="1.4"></a>1.4. What is the current version of nano?</h3>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>4.3</b>. Of course, you should always check the <a href="https://nano-editor.org/">nano homepage</a> to see what the latest and greatest version is.</p></blockquote>
|
||||
<blockquote><p>The current version of nano <i>should</i> be <b>4.5</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%">
|
||||
|
||||
26
doc/nano.1
26
doc/nano.1
@@ -16,14 +16,16 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANO 1 "version 4.3" "June 2019"
|
||||
.TH NANO 1 "version 4.5" "October 2019"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, inspired by Pico
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B nano
|
||||
.RI [ options "] [[+" line [, column "]]\ " file "]..."
|
||||
.RI [ options "] [[\fB+" line [\fB, column "]] " file ]...
|
||||
.sp
|
||||
.BR nano " [" \fIoptions "] [[" + [ crCR ]( / | ? ) \fIstring "] " \fIfile ]...
|
||||
|
||||
.SH NOTICE
|
||||
Starting with version 4.0, \fBnano\fR no longer hard-wraps an overlong
|
||||
@@ -38,11 +40,23 @@ If you want the old, Pico behavior back, you can use \fB\-\-breaklonglines\fR,
|
||||
of Pico, but is free software, and implements several features that Pico
|
||||
lacks, such as: opening multiple files, scrolling per line, undo/redo,
|
||||
syntax coloring, line numbering, and soft-wrapping overlong lines.
|
||||
|
||||
.sp
|
||||
When giving a filename on the command line, the cursor can be put on a
|
||||
specific line by adding the line number with a plus sign (\fB+\fR) before
|
||||
the filename, and even in a specific column by adding it with a comma.
|
||||
|
||||
The cursor can be put on the first or last occurrence of a specific string
|
||||
by specifying that string after \fB+/\fR or \fB+?\fR before the filename.
|
||||
The string can be made case sensitive and/or caused to be interpreted as a
|
||||
regular expression by inserting \fBc\fR and/or \fBr\fR after the \fB+\fR sign.
|
||||
These search modes can be explicitly disabled by using the uppercase variant
|
||||
of those letters: \fBC\fR and/or \fBR\fR. When the string contains spaces,
|
||||
it needs to be enclosed in quotes. To give an example: to open a file at
|
||||
the first occurrence of the word "Foo", one would do:
|
||||
.sp
|
||||
.RS 4
|
||||
.BI "nano +c/Foo " file
|
||||
.RE
|
||||
.sp
|
||||
As a special case: if instead of a filename a dash (\fB\-\fR) is given,
|
||||
\fBnano\fR will read data from standard input.
|
||||
|
||||
@@ -263,8 +277,8 @@ at the width of the screen minus \fInumber\fR columns, allowing the wrap
|
||||
point to vary along with the width of the screen if the screen is resized.
|
||||
The default value is \-8.
|
||||
.TP
|
||||
.BR \-s\ \fIprogram ", " \-\-speller= \fIprogram
|
||||
Use this alternative spell checker command.
|
||||
.B "\-s ""\fIprogram\fR [\fIarg\fR...]\fB""\fR, \fB\-\-speller=""\fIprogram\fR [\fIarg\fR...]\fB"""
|
||||
Use this alternative command to perform spell checking.
|
||||
.TP
|
||||
.BR \-t ", " \-\-tempfile
|
||||
Save a changed buffer without prompting (when exiting with \fB^X\fR).
|
||||
|
||||
111
doc/nano.texi
111
doc/nano.texi
@@ -8,8 +8,8 @@
|
||||
|
||||
@smallbook
|
||||
@set EDITION 0.5
|
||||
@set VERSION 4.3
|
||||
@set UPDATED June 2019
|
||||
@set VERSION 4.5
|
||||
@set UPDATED October 2019
|
||||
|
||||
@dircategory Editors
|
||||
@direntry
|
||||
@@ -23,7 +23,7 @@
|
||||
@titlepage
|
||||
@title GNU @command{nano}
|
||||
@subtitle a small and friendly text editor
|
||||
@subtitle version 4.3
|
||||
@subtitle version 4.5
|
||||
|
||||
@author Chris Allegretta
|
||||
@page
|
||||
@@ -63,7 +63,7 @@ e-mail: @email{chrisa@@asty.org}@*
|
||||
@node Top
|
||||
@top
|
||||
|
||||
This manual documents the GNU @command{nano} editor, version 4.3.
|
||||
This manual documents the GNU @command{nano} editor, version 4.5.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
@@ -127,13 +127,21 @@ But it is also possible to specify one or more options (see the next
|
||||
section), and to edit several files in a row. Additionally, the cursor
|
||||
can be put on a specific line of a file by adding the line number
|
||||
with a plus sign before the filename, and even in a specific column by
|
||||
adding it with a comma. So a more complete command synopsis is:
|
||||
adding it with a comma.
|
||||
The cursor can also be put on the first or last occurrence of a specific string
|
||||
by specifying that string after @code{+/} or @code{+?} before the filename.
|
||||
The string can be made case sensitive and/or caused to be interpreted as a
|
||||
regular expression by inserting a @code{c} and/or @code{r} after the plus sign.
|
||||
These search modes can be explicitly disabled by using the uppercase variant
|
||||
of those letters: @code{C} and/or @code{R}. When the string contains spaces,
|
||||
it needs to be enclosed in quotes.
|
||||
A more complete command synopsis thus is:
|
||||
|
||||
@iftex
|
||||
@sp 1
|
||||
@end iftex
|
||||
@example
|
||||
@code{nano [OPTION]@dots{} [[+LINE[,COLUMN]|+,COLUMN] FILE]@dots{}}
|
||||
@code{nano [OPTION]@dots{} [[+LINE[,COLUMN]|+[crCR](/|?)STRING] FILE]@dots{}}
|
||||
@end example
|
||||
@iftex
|
||||
@sp 1
|
||||
@@ -388,8 +396,8 @@ point to vary along with the width of the screen if the screen is resized.
|
||||
The default value is @t{-8}.
|
||||
|
||||
@anchor{@option{--speller}}
|
||||
@item -s @var{program}
|
||||
@itemx --speller=@var{program}
|
||||
@item -s "@var{program} [@var{arg} @dots{}]"
|
||||
@itemx --speller="@var{program} [@var{arg} @dots{}]"
|
||||
Use the given program to do spell checking and correcting. By default,
|
||||
@command{nano} uses the command specified in the @env{SPELL} environment
|
||||
variable. If @env{SPELL} is not set, and @option{--speller} is
|
||||
@@ -915,7 +923,7 @@ When needed, use @code{unset jumpyscrolling} instead.
|
||||
@item set softwrap
|
||||
Enable soft line wrapping for easier viewing of very long lines.
|
||||
|
||||
@item set speller "@var{program}"
|
||||
@item set speller "@var{program} [@var{arg} @dots{}]"
|
||||
Use the given program to do spell checking and correcting.
|
||||
@xref{@option{--speller}} for details.
|
||||
|
||||
@@ -989,7 +997,7 @@ powerful enough to fully parse a file. Nevertheless, regular
|
||||
expressions can do a lot and are easy to make, so they are a
|
||||
good fit for a small editor like @command{nano}.
|
||||
|
||||
All regular expressions in @command{nano} are extended regular expressions
|
||||
All regular expressions in @command{nano} are POSIX extended regular expressions
|
||||
(ERE). This means that @code{.}, @code{?}, @code{*}, @code{+}, @code{^},
|
||||
@code{$}, and several other characters are special.
|
||||
The period @code{.} matches any single character,
|
||||
@@ -1021,7 +1029,7 @@ activated by using the @option{-Y} or @option{--syntax}
|
||||
command-line option followed by the @var{name}.
|
||||
|
||||
The @code{default} syntax is special: it takes no @var{fileregex},
|
||||
and applies to files that don't match any syntax's @var{fileregex}.
|
||||
and applies to files that don't match any syntax's regexes.
|
||||
The @code{none} syntax is reserved; specifying it on the
|
||||
command line is the same as not having a syntax at all.
|
||||
|
||||
@@ -1052,26 +1060,30 @@ Python files. If empty double quotes are specified, the comment/uncomment
|
||||
functions are disabled; for example, @t{""} for JSON.
|
||||
The default value is @t{"#"}.
|
||||
|
||||
@item tabgives "@var{string}"
|
||||
Make the <Tab> key produce the given @var{string}. Useful for languages like
|
||||
Python that want to see only spaces for indentation.
|
||||
This overrides the setting of the @code{tabstospaces} option.
|
||||
|
||||
@item color @var{fgcolor},@var{bgcolor} "@var{regex}" @dots{}
|
||||
Display all pieces of text that match the
|
||||
extended regular expression "regex" with foreground color "fgcolor" and
|
||||
background color "bgcolor", at least one of which must be specified.
|
||||
Valid names for foreground and background color are:
|
||||
Paint all pieces of text that match the extended regular expression "regex"
|
||||
with the given foreground and background colors, at least one of which must
|
||||
be specified. Valid color names are:
|
||||
@code{white}, @code{black}, @code{blue}, @code{green},
|
||||
@code{red}, @code{cyan}, @code{yellow}, @code{magenta}, and @code{normal}
|
||||
--- where @code{normal} means the default foreground or background color.
|
||||
You may use the prefix @code{bright}
|
||||
to get a stronger color highlight for the foreground. If your
|
||||
terminal supports transparency, not specifying a "bgcolor" tells @command{nano}
|
||||
to attempt to use a transparent background.
|
||||
You may use the prefix @code{bright} for the foreground color to get a
|
||||
stronger highlight.
|
||||
If your terminal supports transparency, not specifying a "bgcolor"
|
||||
tells @command{nano} to attempt to use a transparent background.
|
||||
|
||||
@item icolor @var{fgcolor},@var{bgcolor} "@var{regex}" @dots{}
|
||||
Same as above, except that the matching is case insensitive.
|
||||
|
||||
@item color @var{fgcolor},@var{bgcolor} start="@var{fromrx}" end="@var{torx}"
|
||||
Display all pieces of text whose start matches extended regular expression
|
||||
Paint all pieces of text whose start matches extended regular expression
|
||||
"fromrx" and whose end matches extended regular expression "torx" with
|
||||
foreground color "fgcolor" and background color "bgcolor", at least one of
|
||||
the given foreground and background colors, at least one of
|
||||
which must be specified. This means that, after an initial instance of
|
||||
"fromrx", all text until the first instance of "torx" will be colored.
|
||||
This allows syntax highlighting to span multiple lines.
|
||||
@@ -1677,54 +1689,54 @@ The possible options to @code{./configure} are:
|
||||
@table @code
|
||||
|
||||
@item --disable-browser
|
||||
Disable the mini file browser that can be called with @kbd{^T} when reading
|
||||
or writing files.
|
||||
Exclude the mini file browser that can be called with @kbd{^T} when
|
||||
wanting to read or write a file.
|
||||
|
||||
@item --disable-color
|
||||
Disable support for the syntax coloring of files. This also eliminates
|
||||
the @option{-Y} command-line option, which chooses a specific syntax.
|
||||
Exclude support for syntax coloring. This also eliminates the @option{-Y}
|
||||
command-line option, which allows choosing a specific syntax.
|
||||
|
||||
@item --disable-comment
|
||||
Disable the single-keystroke comment/uncomment function (@kbd{M-3}).
|
||||
Exclude the single-keystroke comment/uncomment function (@kbd{M-3}).
|
||||
|
||||
@item --disable-extra
|
||||
Disable the Easter egg: a crawl of major contributors.
|
||||
Exclude the Easter egg: a crawl of major contributors.
|
||||
|
||||
@item --disable-help
|
||||
Disable the help function. Doing this makes the binary much smaller,
|
||||
but makes it difficult for new users to learn more than very basic
|
||||
Exclude the help texts (@kbd{^G}). This makes the binary much smaller,
|
||||
but also makes it difficult for new users to learn more than very basic
|
||||
things about using the editor.
|
||||
|
||||
@item --disable-histories
|
||||
Disable the code for the handling of the history files: the search and
|
||||
Exclude the code for handling the history files: the search and
|
||||
replace strings that were used, and the cursor position at which each
|
||||
file was closed. This also eliminates the @option{-H} and @option{-P}
|
||||
command-line options, which switch on the logging of search/replace
|
||||
strings and cursor positions.
|
||||
|
||||
@item --disable-justify
|
||||
Disable the justify and unjustify functions.
|
||||
Exclude the justify functions (@kbd{^J} and @kbd{M-J}).
|
||||
|
||||
@item --disable-libmagic
|
||||
Disable the use of the library of magic-number tests (for determining
|
||||
the file type and thus which syntax to use for colouring --- often the
|
||||
tests on filename extension and header line will be enough).
|
||||
Exclude the code for using the library of magic-number tests (for determining
|
||||
the file type and thus which syntax to use for coloring --- often the regexes
|
||||
for filename and header line will be enough).
|
||||
|
||||
@item --disable-linenumbers
|
||||
Disable the line-numbering function (@kbd{M-#}). This also eliminates the
|
||||
Exclude the line-numbering function (@kbd{M-N}). This also eliminates the
|
||||
@option{-l} command-line option, which turns line numbering on.
|
||||
|
||||
@item --disable-mouse
|
||||
Disable all mouse functionality. This also eliminates the @option{-m}
|
||||
Exclude all mouse functionality. This also eliminates the @option{-m}
|
||||
command-line option, which enables the mouse functionality.
|
||||
|
||||
@item --disable-multibuffer
|
||||
Disable support for opening multiple files at a time and switching
|
||||
Exclude support for opening multiple files at a time and switching
|
||||
between them on the fly. This also eliminates the @option{-F} command-line
|
||||
option, which causes a file to be read into a separate buffer by default.
|
||||
|
||||
@item --disable-nanorc
|
||||
Disable support for reading the nanorc files at startup. With such
|
||||
Exclude support for reading the nanorc files at startup. With such
|
||||
support, you can store custom settings in a system-wide and a per-user
|
||||
nanorc file rather than having to pass command-line options to get
|
||||
the desired behavior. @xref{Nanorc Files} for more info.
|
||||
@@ -1732,22 +1744,23 @@ Disabling this also eliminates the @option{-I} command-line option,
|
||||
which inhibits the reading of nanorc files.
|
||||
|
||||
@item --disable-operatingdir
|
||||
Disable setting the operating directory. This also eliminates the @option{-o}
|
||||
command-line option, which sets the operating directory.
|
||||
Exclude the code for setting the operating directory. This also eliminates
|
||||
the @option{-o} command-line option, which sets the operating directory.
|
||||
|
||||
@item --disable-speller
|
||||
Disable use of the spell checker. This also eliminates the @option{-s}
|
||||
Exclude the code for spell checking. This also eliminates the @option{-s}
|
||||
command-line option, which allows specifying an alternate spell checker.
|
||||
|
||||
@item --disable-tabcomp
|
||||
Disable tab completion (when nano asks for a filename or a search string).
|
||||
Exclude tab completion (when nano asks for a filename or a search string).
|
||||
|
||||
@item --disable-wordcomp
|
||||
Disable word completion (@kbd{^]}).
|
||||
Exclude word completion (@kbd{^]}).
|
||||
|
||||
@item --disable-wrapping
|
||||
Disable all hard-wrapping of overlong lines. This also eliminates the
|
||||
@option{-w} command-line option, which switches long-line wrapping off.
|
||||
Exclude all hard-wrapping of overlong lines. This also eliminates the
|
||||
@option{-b} and @option{-w} command-line options, which switch automatic
|
||||
long-line wrapping on and off, respectively.
|
||||
|
||||
@item --enable-tiny
|
||||
This option implies all of the above. It also disables some other
|
||||
@@ -1757,19 +1770,19 @@ counterpart of the above options together with @option{--enable-tiny},
|
||||
specific features can be switched back on --- but a few cannot.
|
||||
|
||||
@item --enable-debug
|
||||
Enable support for runtime debug output. This can get pretty messy, so
|
||||
Include some code for runtime debugging output. This can get pretty messy, so
|
||||
chances are you only want this feature when you're working on the nano source.
|
||||
|
||||
@item --disable-nls
|
||||
Disables Native Language support. This will disable the use of any
|
||||
Exclude Native Language support. This will disable the use of any
|
||||
available GNU @command{nano} translations.
|
||||
|
||||
@item --enable-utf8
|
||||
Enable support for reading and writing Unicode files. This will require
|
||||
Include support for reading and writing Unicode files. This will require
|
||||
either a wide version of curses, or a UTF-8-enabled version of Slang.
|
||||
|
||||
@item --disable-utf8
|
||||
Disable support for reading and writing Unicode files. Normally the
|
||||
Exclude support for reading and writing Unicode files. Normally the
|
||||
configure script auto-detects whether to enable UTF-8 support or not.
|
||||
You can use this or the previous option to override that detection.
|
||||
|
||||
|
||||
31
doc/nanorc.5
31
doc/nanorc.5
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH NANORC 5 "version 4.3" "June 2019"
|
||||
.TH NANORC 5 "version 4.5" "October 2019"
|
||||
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's configuration file
|
||||
@@ -261,7 +261,7 @@ When needed, use \fBunset jumpyscrolling\fR instead.
|
||||
.B set softwrap
|
||||
Enable soft line wrapping for easier viewing of very long lines.
|
||||
.TP
|
||||
.B set speller "\fIprogram\fP"
|
||||
.B set speller """\fIprogram\fR [\fIarg\fR...]\fB"""
|
||||
Use the given \fIprogram\fR to do spell checking and correcting,
|
||||
instead of the built-in corrector that calls \fBspell\fR.
|
||||
.TP
|
||||
@@ -335,7 +335,7 @@ powerful enough to fully parse a file. Nevertheless, regular
|
||||
expressions can do a lot and are easy to make, so they are a
|
||||
good fit for a small editor like \fBnano\fR.
|
||||
.sp
|
||||
All regular expressions in \fBnano\fR are extended regular expressions (ERE).
|
||||
All regular expressions in \fBnano\fR are POSIX extended regular expressions.
|
||||
This means that \fB.\fR, \fB?\fR, \fB*\fR, \fB+\fR, \fB^\fR, \fB$\fR, and
|
||||
several other characters are special.
|
||||
The period \fB.\fR matches any single character,
|
||||
@@ -396,26 +396,29 @@ for Python files. If empty double quotes are specified, the comment/uncomment
|
||||
function is disabled; for example, "" for JSON.
|
||||
The default value is "\fB#\fP".
|
||||
.TP
|
||||
.BI "tabgives """ string """
|
||||
Make the <Tab> key produce the given \fIstring\fR. Useful for languages like
|
||||
Python that want to see only spaces for indentation.
|
||||
This overrides the setting of the \fBtabstospaces\fR option.
|
||||
.TP
|
||||
.BI "color " fgcolor , bgcolor " """ regex """ " \fR...
|
||||
Display all pieces of text that match
|
||||
the extended regular expression \fIregex\fP with foreground color
|
||||
\fIfgcolor\fP and background color \fIbgcolor\fP, at least one of which
|
||||
must be specified. Valid names for foreground and background colors are:
|
||||
Paint all pieces of text that match the extended regular expression
|
||||
\fIregex\fP with the given foreground and background colors, at least
|
||||
one of which must be specified. Valid color names are:
|
||||
.BR white ", " black ", " blue ", " green ", " red ", "
|
||||
.BR cyan ", " yellow ", " magenta ", and " normal
|
||||
-- where \fBnormal\fR means the default foreground or background color.
|
||||
You may use the prefix \fBbright\fR to get a stronger color highlight for the
|
||||
foreground. If your terminal supports transparency, not specifying a
|
||||
\fIbgcolor\fP tells \fBnano\fP to attempt to use a transparent
|
||||
background.
|
||||
You may use the prefix \fBbright\fR for the foreground color to get a
|
||||
stronger highlight. If your terminal supports transparency, not specifying
|
||||
a \fIbgcolor\fP tells \fBnano\fP to attempt to use a transparent background.
|
||||
.TP
|
||||
.BI "icolor " fgcolor , bgcolor " """ regex """ " \fR...
|
||||
Same as above, except that the matching is case insensitive.
|
||||
.TP
|
||||
.BI "color " fgcolor , bgcolor " start=""" fromrx """ end=""" torx """
|
||||
Display all pieces of text whose start matches extended regular expression
|
||||
\fIfromrx\fP and whose end matches extended regular expression \fItorx\fP with
|
||||
foreground color \fIfgcolor\fP and background color \fIbgcolor\fP,
|
||||
Paint all pieces of text whose start matches extended regular expression
|
||||
\fIfromrx\fP and whose end matches extended regular expression \fItorx\fP
|
||||
with the given foreground and background colors,
|
||||
at least one of which must be specified. This means that, after an
|
||||
initial instance of \fIfromrx\fP, all text until the first instance of
|
||||
\fItorx\fP will be colored. This allows syntax highlighting to span
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" Documentation License along with this program. If not, see
|
||||
.\" <https://www.gnu.org/licenses/>.
|
||||
.\"
|
||||
.TH RNANO 1 "version 4.3" "June 2019"
|
||||
.TH RNANO 1 "version 4.5" "October 2019"
|
||||
|
||||
.SH NAME
|
||||
rnano \- a restricted nano
|
||||
|
||||
@@ -261,6 +261,14 @@
|
||||
# include "@PKGDATADIR@/*.nanorc"
|
||||
|
||||
|
||||
## If <Tab> should always produce four spaces when editing a Python file,
|
||||
## independent of the settings of 'tabsize' and 'tabstospaces':
|
||||
# extendsyntax python tabgives " "
|
||||
#
|
||||
## If <Tab> should always produce an actual TAB when editing a Makefile:
|
||||
# extendsyntax makefile tabgives " "
|
||||
|
||||
|
||||
## Key bindings.
|
||||
## See nanorc(5) (section REBINDING KEYS) for more details on this.
|
||||
|
||||
|
||||
1048
po/nano.pot
1048
po/nano.pot
File diff suppressed because it is too large
Load Diff
1050
po/pt_BR.po
1050
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1052
po/zh_CN.po
1052
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1050
po/zh_TW.po
1050
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION="4.3"
|
||||
VERSION="4.5"
|
||||
|
||||
./configure -C --enable-tiny && make && ./configure -C &&
|
||||
|
||||
|
||||
@@ -458,21 +458,6 @@ functionptrtype parse_browser_input(int *kbinput)
|
||||
return do_page_up;
|
||||
case ' ':
|
||||
return do_page_down;
|
||||
case '?':
|
||||
return do_help_void;
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'Q':
|
||||
case 'q':
|
||||
case 'X':
|
||||
case 'x':
|
||||
return do_exit;
|
||||
case 'G':
|
||||
case 'g':
|
||||
return goto_dir_void;
|
||||
case 'S':
|
||||
case 's':
|
||||
return do_enter;
|
||||
case 'W':
|
||||
case 'w':
|
||||
case '/':
|
||||
@@ -481,6 +466,21 @@ functionptrtype parse_browser_input(int *kbinput)
|
||||
return do_findprevious;
|
||||
case 'n':
|
||||
return do_findnext;
|
||||
case 'G':
|
||||
case 'g':
|
||||
return goto_dir_void;
|
||||
case '?':
|
||||
return do_help_void;
|
||||
case 'S':
|
||||
case 's':
|
||||
return do_enter;
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'Q':
|
||||
case 'q':
|
||||
case 'X':
|
||||
case 'x':
|
||||
return do_exit;
|
||||
}
|
||||
}
|
||||
return func_from_key(kbinput);
|
||||
@@ -524,16 +524,15 @@ void browser_refresh(void)
|
||||
/* The filename (or a fragment of it) in displayable format.
|
||||
* When a fragment, account for dots plus one space padding. */
|
||||
|
||||
/* If this is the selected item, start its highlighting, and
|
||||
/* If this is the selected item, draw its highlighted bar upfront, and
|
||||
* remember its location to be able to place the cursor on it. */
|
||||
if (i == selected) {
|
||||
wattron(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
mvwprintw(edit, row, col, "%*s", longest, " ");
|
||||
the_row = row;
|
||||
the_column = col;
|
||||
}
|
||||
|
||||
blank_row(edit, row, col, longest);
|
||||
|
||||
/* If the name is too long, we display something like "...ename". */
|
||||
if (dots)
|
||||
mvwaddstr(edit, row, col, "...");
|
||||
@@ -671,6 +670,7 @@ int filesearch_init(bool forwards)
|
||||
/* Now ask what to search for. */
|
||||
response = do_prompt(FALSE, FALSE, MWHEREISFILE, NULL, &search_history,
|
||||
browser_refresh, "%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: A modifier of the Search prompt. */
|
||||
!forwards ? _(" [Backwards]") : "", thedefault);
|
||||
free(thedefault);
|
||||
|
||||
|
||||
84
src/chars.c
84
src/chars.c
@@ -200,11 +200,12 @@ char control_mbrep(const char *c, bool isdata)
|
||||
return control_rep(*c);
|
||||
}
|
||||
|
||||
/* This function is equivalent to wcwidth() for multibyte characters. */
|
||||
#ifdef ENABLE_UTF8
|
||||
/* Return the width in columns of the given (multibyte) character. */
|
||||
int mbwidth(const char *c)
|
||||
{
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
/* Ask for the width only when the character isn't plain ASCII. */
|
||||
if ((signed char)*c <= 0) {
|
||||
wchar_t wc;
|
||||
int width;
|
||||
|
||||
@@ -213,41 +214,41 @@ int mbwidth(const char *c)
|
||||
|
||||
width = wcwidth(wc);
|
||||
|
||||
if (width == -1)
|
||||
if (width < 0)
|
||||
return 1;
|
||||
|
||||
return width;
|
||||
} else
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Convert the Unicode value in chr to a multibyte character, if possible.
|
||||
/* Convert the Unicode value in code to a multibyte character, if possible.
|
||||
* If the conversion succeeds, return the (dynamically allocated) multibyte
|
||||
* character and its length. Otherwise, return an undefined (dynamically
|
||||
* allocated) multibyte character and a length of zero. */
|
||||
char *make_mbchar(long chr, int *chr_mb_len)
|
||||
char *make_mbchar(long code, int *length)
|
||||
{
|
||||
char *chr_mb;
|
||||
char *mb_char;
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
if (use_utf8) {
|
||||
chr_mb = charalloc(MAXCHARLEN);
|
||||
*chr_mb_len = wctomb(chr_mb, (wchar_t)chr);
|
||||
mb_char = charalloc(MAXCHARLEN);
|
||||
*length = wctomb(mb_char, (wchar_t)code);
|
||||
|
||||
/* Reject invalid Unicode characters. */
|
||||
if (*chr_mb_len < 0 || !is_valid_unicode((wchar_t)chr)) {
|
||||
if (*length < 0 || !is_valid_unicode((wchar_t)code)) {
|
||||
IGNORE_CALL_RESULT(wctomb(NULL, 0));
|
||||
*chr_mb_len = 0;
|
||||
*length = 0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
*chr_mb_len = 1;
|
||||
chr_mb = mallocstrncpy(NULL, (char *)&chr, 1);
|
||||
mb_char = mallocstrncpy(NULL, (char *)&code, 1);
|
||||
*length = 1;
|
||||
}
|
||||
|
||||
return chr_mb;
|
||||
return mb_char;
|
||||
}
|
||||
|
||||
/* Return the length (in bytes) of the character located at *pointer. */
|
||||
@@ -264,6 +265,27 @@ int char_length(const char *pointer)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the number of (multibyte) characters in the given string. */
|
||||
size_t mbstrlen(const char *pointer)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
while (*pointer != '\0') {
|
||||
#ifdef ENABLE_UTF8
|
||||
if ((signed char)*pointer < 0) {
|
||||
int length = mblen(pointer, MAXCHARLEN);
|
||||
|
||||
pointer += (length < 0 ? 1 : length);
|
||||
} else
|
||||
#endif
|
||||
pointer++;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Parse a multibyte character from buf. Return the number of bytes
|
||||
* used. If chr isn't NULL, store the multibyte character in it. If
|
||||
* col isn't NULL, add the character's width (in columns) to it. */
|
||||
@@ -346,7 +368,7 @@ size_t step_left(const char *buf, size_t pos)
|
||||
return before - charlen;
|
||||
} else
|
||||
#endif
|
||||
return (pos == 0 ? 0 : pos - 1);
|
||||
return (pos == 0 ? 0 : pos - 1);
|
||||
}
|
||||
|
||||
/* Return the index in buf of the beginning of the multibyte character
|
||||
@@ -487,27 +509,6 @@ char *mbrevstrcasestr(const char *haystack, const char *needle,
|
||||
return revstrcasestr(haystack, needle, pointer);
|
||||
}
|
||||
|
||||
/* Count the number of (multibyte) characters in the given string. */
|
||||
size_t mbstrlen(const char *pointer)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
while (*pointer != '\0') {
|
||||
#ifdef ENABLE_UTF8
|
||||
if ((signed char)*pointer < 0) {
|
||||
int length = mblen(pointer, MAXCHARLEN);
|
||||
|
||||
pointer += (length < 0 ? 1 : length);
|
||||
} else
|
||||
#endif
|
||||
pointer++;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
|
||||
/* This function is equivalent to strchr() for multibyte strings. */
|
||||
char *mbstrchr(const char *string, const char *chr)
|
||||
@@ -602,6 +603,15 @@ bool has_blank_char(const char *string)
|
||||
}
|
||||
#endif /* ENABLE_NANORC && (!NANO_TINY || ENABLE_JUSTIFY) */
|
||||
|
||||
/* Return TRUE when the given string is empty or consists of only blanks. */
|
||||
bool white_string(const char *string)
|
||||
{
|
||||
while (*string != '\0' && (is_blank_mbchar(string) || *string == '\r'))
|
||||
string += char_length(string);
|
||||
|
||||
return !*string;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
/* Return TRUE if wc is valid Unicode, and FALSE otherwise. */
|
||||
bool is_valid_unicode(wchar_t wc)
|
||||
|
||||
52
src/color.c
52
src/color.c
@@ -26,7 +26,6 @@
|
||||
#include <magic.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
@@ -192,20 +191,7 @@ void color_update(void)
|
||||
/* If no syntax-override string was specified, or it didn't match,
|
||||
* try finding a syntax based on the filename (extension). */
|
||||
if (sint == NULL && !inhelp) {
|
||||
char *reserved = charalloc(PATH_MAX + 1);
|
||||
char *currentdir = getcwd(reserved, PATH_MAX + 1);
|
||||
char *joinednames = charalloc(PATH_MAX + 1);
|
||||
char *fullname = NULL;
|
||||
|
||||
if (currentdir == NULL)
|
||||
free(reserved);
|
||||
else {
|
||||
/* Concatenate the current working directory with the
|
||||
* specified filename, and canonicalize the result. */
|
||||
sprintf(joinednames, "%s/%s", currentdir, openfile->filename);
|
||||
fullname = get_full_path(joinednames);
|
||||
free(currentdir);
|
||||
}
|
||||
char *fullname = get_full_path(openfile->filename);
|
||||
|
||||
if (fullname == NULL)
|
||||
fullname = mallocstrcpy(fullname, openfile->filename);
|
||||
@@ -215,7 +201,6 @@ void color_update(void)
|
||||
break;
|
||||
}
|
||||
|
||||
free(joinednames);
|
||||
free(fullname);
|
||||
}
|
||||
|
||||
@@ -282,6 +267,15 @@ void color_update(void)
|
||||
openfile->colorstrings = (sint == NULL ? NULL : sint->color);
|
||||
}
|
||||
|
||||
/* Allocate and initialize (for the given line) the cache for multiline info. */
|
||||
void set_up_multicache(linestruct *line)
|
||||
{
|
||||
line->multidata = (short *)nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
|
||||
for (int index = 0; index < openfile->syntax->nmultis; index++)
|
||||
line->multidata[index] = -1;
|
||||
}
|
||||
|
||||
/* Determine whether the matches of multiline regexes are still the same,
|
||||
* and if not, schedule a screen refresh, so things will be repainted. */
|
||||
void check_the_multis(linestruct *line)
|
||||
@@ -295,13 +289,14 @@ void check_the_multis(linestruct *line)
|
||||
if (openfile->syntax == NULL || openfile->syntax->nmultis == 0)
|
||||
return;
|
||||
|
||||
if (line->multidata == NULL)
|
||||
set_up_multicache(line);
|
||||
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
/* If it's not a multiline regex, skip. */
|
||||
if (ink->end == NULL)
|
||||
continue;
|
||||
|
||||
alloc_multidata_if_needed(line);
|
||||
|
||||
astart = (regexec(ink->start, line->data, 1, &startmatch, 0) == 0);
|
||||
afterstart = line->data + (astart ? startmatch.rm_eo : 0);
|
||||
anend = (regexec(ink->end, afterstart, 1, &endmatch, 0) == 0);
|
||||
@@ -328,17 +323,6 @@ void check_the_multis(linestruct *line)
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate (for one line) the cache space for multiline color regexes. */
|
||||
void alloc_multidata_if_needed(linestruct *fileptr)
|
||||
{
|
||||
if (fileptr->multidata == NULL) {
|
||||
fileptr->multidata = (short *)nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
|
||||
for (int i = 0; i < openfile->syntax->nmultis; i++)
|
||||
fileptr->multidata[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Precalculate the multi-line start and end regex info so we can
|
||||
* speed up rendering (with any hope at all...). */
|
||||
void precalc_multicolorinfo(void)
|
||||
@@ -350,6 +334,10 @@ void precalc_multicolorinfo(void)
|
||||
if (openfile->colorstrings == NULL || ISSET(NO_COLOR_SYNTAX))
|
||||
return;
|
||||
|
||||
/* For each line, allocate cache space for the multiline-regex info. */
|
||||
for (line = openfile->filetop; line != NULL; line = line->next)
|
||||
set_up_multicache(line);
|
||||
|
||||
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
|
||||
/* If this is not a multi-line regex, skip it. */
|
||||
if (ink->end == NULL)
|
||||
@@ -358,7 +346,6 @@ void precalc_multicolorinfo(void)
|
||||
for (line = openfile->filetop; line != NULL; line = line->next) {
|
||||
int index = 0;
|
||||
|
||||
alloc_multidata_if_needed(line);
|
||||
/* Assume nothing applies until proven otherwise below. */
|
||||
line->multidata[ink->id] = CNONE;
|
||||
|
||||
@@ -410,12 +397,9 @@ void precalc_multicolorinfo(void)
|
||||
* the lines in between and the end properly. */
|
||||
line->multidata[ink->id] = CENDAFTER;
|
||||
|
||||
for (line = line->next; line != tailline; line = line->next) {
|
||||
alloc_multidata_if_needed(line);
|
||||
for (line = line->next; line != tailline; line = line->next)
|
||||
line->multidata[ink->id] = CWHOLELINE;
|
||||
}
|
||||
|
||||
alloc_multidata_if_needed(tailline);
|
||||
tailline->multidata[ink->id] = CBEGINBEFORE;
|
||||
|
||||
/* Begin looking for a new start after the end match. */
|
||||
|
||||
26
src/cut.c
26
src/cut.c
@@ -50,7 +50,7 @@ void do_deletion(undo_type action)
|
||||
old_amount = number_of_chunks_in(openfile->current);
|
||||
#endif
|
||||
/* Move the remainder of the line "in", over the current character. */
|
||||
charmove(&openfile->current->data[openfile->current_x],
|
||||
memmove(&openfile->current->data[openfile->current_x],
|
||||
&openfile->current->data[openfile->current_x + charlen],
|
||||
line_len - charlen + 1);
|
||||
#ifndef NANO_TINY
|
||||
@@ -182,7 +182,9 @@ void chop_word(bool forward)
|
||||
openfile->current_x = is_current_x;
|
||||
|
||||
/* Now kill the marked region and a word is gone. */
|
||||
cut_text();
|
||||
add_undo(CUT);
|
||||
do_snip(FALSE, TRUE, FALSE, FALSE);
|
||||
update_undo(CUT);
|
||||
|
||||
/* Discard the cut word and restore the cutbuffer. */
|
||||
free_lines(cutbuffer);
|
||||
@@ -268,7 +270,7 @@ void cut_to_eof(void)
|
||||
* If until_eof is TRUE, move all text from the current cursor
|
||||
* position to the end of the file into the cutbuffer. If append
|
||||
* is TRUE (when zapping), always append the cut to the cutbuffer. */
|
||||
void do_cut_text(bool copying, bool marked, bool until_eof, bool append)
|
||||
void do_snip(bool copying, bool marked, bool until_eof, bool append)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
linestruct *was_bottom = NULL;
|
||||
@@ -383,13 +385,14 @@ void cut_text(void)
|
||||
add_undo(CUT);
|
||||
}
|
||||
|
||||
do_cut_text(FALSE, openfile->mark != NULL, FALSE, FALSE);
|
||||
do_snip(FALSE, openfile->mark != NULL, FALSE, FALSE);
|
||||
|
||||
update_undo(CUT);
|
||||
#else
|
||||
if (is_cuttable(FALSE))
|
||||
do_cut_text(FALSE, FALSE, FALSE, FALSE);
|
||||
do_snip(FALSE, FALSE, FALSE, FALSE);
|
||||
#endif
|
||||
wipe_statusbar();
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -406,11 +409,7 @@ void copy_text(void)
|
||||
ssize_t is_current_lineno = openfile->current->lineno;
|
||||
size_t is_current_x = openfile->current_x;
|
||||
|
||||
/* If there is nothing to copy, don't even try. */
|
||||
if (openfile->current->next == NULL && openfile->current->data[0] == '\0')
|
||||
return;
|
||||
|
||||
do_cut_text(TRUE, mark_is_set, FALSE, FALSE);
|
||||
do_snip(TRUE, mark_is_set, FALSE, FALSE);
|
||||
|
||||
/* If the mark was set, restore the viewport and cursor position. */
|
||||
if (mark_is_set) {
|
||||
@@ -435,8 +434,9 @@ void cut_till_eof(void)
|
||||
}
|
||||
|
||||
add_undo(CUT_TO_EOF);
|
||||
do_cut_text(FALSE, FALSE, TRUE, FALSE);
|
||||
do_snip(FALSE, FALSE, TRUE, FALSE);
|
||||
update_undo(CUT_TO_EOF);
|
||||
wipe_statusbar();
|
||||
}
|
||||
|
||||
/* Erase text (current line or marked region), sending it into oblivion. */
|
||||
@@ -456,9 +456,10 @@ void zap_text(void)
|
||||
/* Use the cutbuffer from the ZAP undo item, so the cut can be undone. */
|
||||
cutbuffer = openfile->current_undo->cutbuffer;
|
||||
|
||||
do_cut_text(FALSE, openfile->mark != NULL, FALSE, TRUE);
|
||||
do_snip(FALSE, openfile->mark != NULL, FALSE, TRUE);
|
||||
|
||||
update_undo(ZAP);
|
||||
wipe_statusbar();
|
||||
|
||||
cutbuffer = was_cutbuffer;
|
||||
}
|
||||
@@ -500,5 +501,6 @@ void paste_text(void)
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
set_modified();
|
||||
wipe_statusbar();
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
233
src/files.c
233
src/files.c
@@ -178,8 +178,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
/* First run things that might fail before blowing away the old state. */
|
||||
if ((mypwuid = getpwuid(myuid)) == NULL) {
|
||||
/* TRANSLATORS: Keep the next eight messages at most 76 characters. */
|
||||
statusline(MILD, _("Couldn't determine my identity for lock file "
|
||||
"(getpwuid() failed)"));
|
||||
statusline(MILD, _("Couldn't determine my identity for lock file"));
|
||||
goto free_the_data;
|
||||
}
|
||||
|
||||
@@ -187,8 +186,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
|
||||
if (errno == ENAMETOOLONG)
|
||||
myhostname[31] = '\0';
|
||||
else {
|
||||
statusline(MILD, _("Couldn't determine hostname for lock file: %s"),
|
||||
strerror(errno));
|
||||
statusline(MILD, _("Couldn't determine hostname: %s"), strerror(errno));
|
||||
goto free_the_data;
|
||||
}
|
||||
}
|
||||
@@ -542,7 +540,7 @@ bool replace_buffer(const char *filename, undo_type action, bool marked)
|
||||
#ifndef NANO_TINY
|
||||
add_undo(action);
|
||||
#endif
|
||||
do_cut_text(FALSE, marked, !marked, FALSE);
|
||||
do_snip(FALSE, marked, !marked, FALSE);
|
||||
#ifndef NANO_TINY
|
||||
update_undo(action);
|
||||
#endif
|
||||
@@ -1031,7 +1029,7 @@ void do_insertfile(void)
|
||||
char *given = mallocstrcpy(NULL, "");
|
||||
/* The last answer the user typed at the statusbar prompt. */
|
||||
#ifndef NANO_TINY
|
||||
file_format original_fmt = openfile->fmt;
|
||||
format_type was_fmt = openfile->fmt;
|
||||
bool execute = FALSE;
|
||||
#endif
|
||||
|
||||
@@ -1117,6 +1115,11 @@ void do_insertfile(void)
|
||||
execute = !execute;
|
||||
continue;
|
||||
}
|
||||
if (func == flip_pipe) {
|
||||
add_or_remove_pipe_symbol_from_answer();
|
||||
given = mallocstrcpy(given, answer);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_BROWSER
|
||||
if (func == to_files_void) {
|
||||
@@ -1130,13 +1133,6 @@ void do_insertfile(void)
|
||||
answer = chosen;
|
||||
response = 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (func == flip_pipe) {
|
||||
add_or_remove_pipe_symbol_from_answer();
|
||||
given = mallocstrcpy(given, answer);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* If we don't have a file yet, go back to the prompt. */
|
||||
if (response != 0 && (!ISSET(MULTIBUFFER) || response != -2))
|
||||
@@ -1201,7 +1197,7 @@ void do_insertfile(void)
|
||||
set_modified();
|
||||
#ifndef NANO_TINY
|
||||
/* Ensure that the buffer retains the format that it had. */
|
||||
openfile->fmt = original_fmt;
|
||||
openfile->fmt = was_fmt;
|
||||
#endif
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
@@ -1222,134 +1218,112 @@ void do_insertfile_void(void)
|
||||
do_insertfile();
|
||||
}
|
||||
|
||||
/* When passed "[relative path]" or "[relative path][filename]" in
|
||||
* origpath, return "[full path]" or "[full path][filename]" on success,
|
||||
* or NULL on error. Do this if the file doesn't exist but the relative
|
||||
* path does, since the file could exist in memory but not yet on disk).
|
||||
* Don't do this if the relative path doesn't exist, since we won't be
|
||||
* able to go there. */
|
||||
/* For the given bare path (or path plus filename), return the canonical,
|
||||
* absolute path (plus filename) when the path exists, and NULL when not. */
|
||||
char *get_full_path(const char *origpath)
|
||||
{
|
||||
char *allocation, *here, *target, *last_slash;
|
||||
char *just_filename = NULL;
|
||||
int attempts = 0;
|
||||
/* How often we've tried climbing back up the tree. */
|
||||
struct stat fileinfo;
|
||||
char *currentdir, *d_here, *d_there, *d_there_file = NULL;
|
||||
char *last_slash;
|
||||
bool path_only;
|
||||
|
||||
if (origpath == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Get the current directory. If it doesn't exist, back up and try
|
||||
* again until we get a directory that does, and use that as the
|
||||
* current directory. */
|
||||
currentdir = charalloc(PATH_MAX + 1);
|
||||
d_here = getcwd(currentdir, PATH_MAX + 1);
|
||||
allocation = charalloc(PATH_MAX + 1);
|
||||
here = getcwd(allocation, PATH_MAX + 1);
|
||||
|
||||
while (d_here == NULL && attempts < 20) {
|
||||
/* If getting the current directory failed, go up one level and try again,
|
||||
* until we find an existing directory, and use that as the current one. */
|
||||
while (here == NULL && attempts < 20) {
|
||||
IGNORE_CALL_RESULT(chdir(".."));
|
||||
d_here = getcwd(currentdir, PATH_MAX + 1);
|
||||
here = getcwd(allocation, PATH_MAX + 1);
|
||||
attempts++;
|
||||
}
|
||||
|
||||
/* If we succeeded, canonicalize it in d_here. */
|
||||
if (d_here != NULL) {
|
||||
/* If the current directory isn't "/", tack a slash onto the end
|
||||
* of it. */
|
||||
if (strcmp(d_here, "/") != 0) {
|
||||
d_here = charealloc(d_here, strlen(d_here) + 2);
|
||||
strcat(d_here, "/");
|
||||
/* If we found a directory, make sure its path ends in a slash. */
|
||||
if (here != NULL) {
|
||||
if (strcmp(here, "/") != 0) {
|
||||
here = charealloc(here, strlen(here) + 2);
|
||||
strcat(here, "/");
|
||||
}
|
||||
/* Otherwise, set d_here to "". */
|
||||
} else {
|
||||
d_here = mallocstrcpy(NULL, "");
|
||||
free(currentdir);
|
||||
here = mallocstrcpy(NULL, "");
|
||||
free(allocation);
|
||||
}
|
||||
|
||||
d_there = real_dir_from_tilde(origpath);
|
||||
target = real_dir_from_tilde(origpath);
|
||||
|
||||
/* If stat()ing d_there fails, assume that d_there refers to a new
|
||||
* file that hasn't been saved to disk yet. Set path_only to TRUE
|
||||
* if d_there refers to a directory, and FALSE otherwise. */
|
||||
path_only = (stat(d_there, &fileinfo) != -1 && S_ISDIR(fileinfo.st_mode));
|
||||
/* Determine whether the target path refers to a directory. If stat()ing
|
||||
* target fails, however, assume that it refers to a new, unsaved file. */
|
||||
path_only = (stat(target, &fileinfo) != -1 && S_ISDIR(fileinfo.st_mode));
|
||||
|
||||
/* If path_only is TRUE, make sure d_there ends in a slash. */
|
||||
/* If the target is a directory, make sure its path ends in a slash. */
|
||||
if (path_only) {
|
||||
size_t d_there_len = strlen(d_there);
|
||||
size_t length = strlen(target);
|
||||
|
||||
if (d_there[d_there_len - 1] != '/') {
|
||||
d_there = charealloc(d_there, d_there_len + 2);
|
||||
strcat(d_there, "/");
|
||||
if (target[length - 1] != '/') {
|
||||
target = charealloc(target, length + 2);
|
||||
strcat(target, "/");
|
||||
}
|
||||
}
|
||||
|
||||
/* Search for the last slash in d_there. */
|
||||
last_slash = strrchr(d_there, '/');
|
||||
last_slash = strrchr(target, '/');
|
||||
|
||||
/* If we didn't find one, then make sure the answer is in the format
|
||||
* "d_here/d_there". */
|
||||
/* If the target path does not contain a slash, then it is a bare filename
|
||||
* and must therefore be located in the working directory. */
|
||||
if (last_slash == NULL) {
|
||||
d_there_file = d_there;
|
||||
d_there = d_here;
|
||||
just_filename = target;
|
||||
target = here;
|
||||
} else {
|
||||
/* If path_only is FALSE, then save the filename portion of the
|
||||
* answer (everything after the last slash) in d_there_file. */
|
||||
if (!path_only)
|
||||
d_there_file = mallocstrcpy(NULL, last_slash + 1);
|
||||
/* If target contains a filename, separate the two. */
|
||||
if (!path_only) {
|
||||
just_filename = mallocstrcpy(NULL, last_slash + 1);
|
||||
*(last_slash + 1) = '\0';
|
||||
}
|
||||
|
||||
/* Remove the filename portion of the answer from d_there. */
|
||||
*(last_slash + 1) = '\0';
|
||||
|
||||
/* Go to the path specified in d_there. */
|
||||
if (chdir(d_there) == -1) {
|
||||
free(d_there);
|
||||
d_there = NULL;
|
||||
/* If we can't change to the target directory, give up. Otherwise,
|
||||
* get the canonical path to this target directory. */
|
||||
if (chdir(target) == -1) {
|
||||
free(target);
|
||||
target = NULL;
|
||||
} else {
|
||||
free(d_there);
|
||||
free(target);
|
||||
|
||||
/* Get the full path. */
|
||||
currentdir = charalloc(PATH_MAX + 1);
|
||||
d_there = getcwd(currentdir, PATH_MAX + 1);
|
||||
allocation = charalloc(PATH_MAX + 1);
|
||||
target = getcwd(allocation, PATH_MAX + 1);
|
||||
|
||||
/* If we succeeded, canonicalize it in d_there. */
|
||||
if (d_there != NULL) {
|
||||
/* If the current directory isn't "/", tack a slash onto
|
||||
* the end of it. */
|
||||
if (strcmp(d_there, "/") != 0) {
|
||||
d_there = charealloc(d_there, strlen(d_there) + 2);
|
||||
strcat(d_there, "/");
|
||||
/* If we got a result, make sure it ends in a slash.
|
||||
* Otherwise, ensure that we return NULL. */
|
||||
if (target != NULL) {
|
||||
if (strcmp(target, "/") != 0) {
|
||||
target = charealloc(target, strlen(target) + 2);
|
||||
strcat(target, "/");
|
||||
}
|
||||
/* Otherwise, make sure that we return NULL. */
|
||||
} else {
|
||||
path_only = TRUE;
|
||||
free(currentdir);
|
||||
free(allocation);
|
||||
}
|
||||
|
||||
/* Finally, go back to the path specified in d_here,
|
||||
* where we were before. We don't check for a chdir()
|
||||
* error, since we can do nothing if we get one. */
|
||||
IGNORE_CALL_RESULT(chdir(d_here));
|
||||
/* Finally, go back to where we were before. We don't check
|
||||
* for an error, since we can't do anything if we get one. */
|
||||
IGNORE_CALL_RESULT(chdir(here));
|
||||
}
|
||||
|
||||
/* Free d_here, since we're done using it. */
|
||||
free(d_here);
|
||||
free(here);
|
||||
}
|
||||
|
||||
/* At this point, if path_only is FALSE and d_there isn't NULL,
|
||||
* d_there contains the path portion of the answer and d_there_file
|
||||
* contains the filename portion of the answer. If this is the
|
||||
* case, tack the latter onto the end of the former. d_there will
|
||||
* then contain the complete answer. */
|
||||
if (!path_only && d_there != NULL) {
|
||||
d_there = charealloc(d_there, strlen(d_there) +
|
||||
strlen(d_there_file) + 1);
|
||||
strcat(d_there, d_there_file);
|
||||
/* If we were given more than a bare path, concatenate the target path
|
||||
* with the filename portion to get the full, absolute file path. */
|
||||
if (!path_only && target != NULL) {
|
||||
target = charealloc(target, strlen(target) + strlen(just_filename) + 1);
|
||||
strcat(target, just_filename);
|
||||
}
|
||||
|
||||
/* Free d_there_file, since we're done using it. */
|
||||
free(d_there_file);
|
||||
free(just_filename);
|
||||
|
||||
return d_there;
|
||||
return target;
|
||||
}
|
||||
|
||||
/* Return the full version of path, as returned by get_full_path(). On
|
||||
@@ -2305,49 +2279,46 @@ void do_savefile(void)
|
||||
close_and_go();
|
||||
}
|
||||
|
||||
/* Return a malloc()ed string containing the actual directory, used to
|
||||
* convert ~user/ and ~/ notation. */
|
||||
char *real_dir_from_tilde(const char *buf)
|
||||
/* Convert the tilde notation when the given path begins with ~/ or ~user/.
|
||||
* Return an allocated string containing the expanded path. */
|
||||
char *real_dir_from_tilde(const char *path)
|
||||
{
|
||||
char *retval;
|
||||
char *tilded, *retval;
|
||||
size_t i = 1;
|
||||
|
||||
if (*buf == '~') {
|
||||
size_t i = 1;
|
||||
char *tilde_dir;
|
||||
if (*path != '~')
|
||||
return mallocstrcpy(NULL, path);
|
||||
|
||||
/* Figure out how much of the string we need to compare. */
|
||||
for (; buf[i] != '/' && buf[i] != '\0'; i++)
|
||||
;
|
||||
/* Figure out how much of the string we need to compare. */
|
||||
while (path[i] != '/' && path[i] != '\0')
|
||||
i++;
|
||||
|
||||
/* Get the home directory. */
|
||||
if (i == 1) {
|
||||
get_homedir();
|
||||
tilde_dir = mallocstrcpy(NULL, homedir);
|
||||
} else {
|
||||
if (i == 1) {
|
||||
get_homedir();
|
||||
tilded = mallocstrcpy(NULL, homedir);
|
||||
} else {
|
||||
#ifdef HAVE_PWD_H
|
||||
const struct passwd *userdata;
|
||||
const struct passwd *userdata;
|
||||
|
||||
tilde_dir = mallocstrncpy(NULL, buf, i + 1);
|
||||
tilde_dir[i] = '\0';
|
||||
tilded = mallocstrncpy(NULL, path, i + 1);
|
||||
tilded[i] = '\0';
|
||||
|
||||
do {
|
||||
userdata = getpwent();
|
||||
} while (userdata != NULL &&
|
||||
strcmp(userdata->pw_name, tilde_dir + 1) != 0);
|
||||
endpwent();
|
||||
if (userdata != NULL)
|
||||
tilde_dir = mallocstrcpy(tilde_dir, userdata->pw_dir);
|
||||
do {
|
||||
userdata = getpwent();
|
||||
} while (userdata && strcmp(userdata->pw_name, tilded + 1) != 0);
|
||||
endpwent();
|
||||
|
||||
if (userdata != NULL)
|
||||
tilded = mallocstrcpy(tilded, userdata->pw_dir);
|
||||
#else
|
||||
tilde_dir = strdup("");
|
||||
tilded = strdup("");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
retval = charalloc(strlen(tilde_dir) + strlen(buf + i) + 1);
|
||||
sprintf(retval, "%s%s", tilde_dir, buf + i);
|
||||
retval = charalloc(strlen(tilded) + strlen(path + i) + 1);
|
||||
sprintf(retval, "%s%s", tilded, path + i);
|
||||
|
||||
free(tilde_dir);
|
||||
} else
|
||||
retval = mallocstrcpy(NULL, buf);
|
||||
free(tilded);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -2611,7 +2582,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
/* If the matches have something in common, show that part. */
|
||||
if (common_len != *place) {
|
||||
buf = charealloc(buf, common_len + buf_len - *place + 1);
|
||||
charmove(buf + common_len, buf + *place, buf_len - *place + 1);
|
||||
memmove(buf + common_len, buf + *place, buf_len - *place + 1);
|
||||
strncpy(buf, mzero, common_len);
|
||||
*place = common_len;
|
||||
}
|
||||
|
||||
125
src/global.c
125
src/global.c
@@ -68,6 +68,9 @@ bool more_than_one = FALSE;
|
||||
bool also_the_last = FALSE;
|
||||
/* Whether indenting/commenting should include the last line of
|
||||
* the marked region. */
|
||||
bool is_shorter;
|
||||
/* Whether a row's text is narrower than the screen's width. */
|
||||
|
||||
int didfind = 0;
|
||||
/* Whether the last search found something. */
|
||||
|
||||
@@ -86,7 +89,7 @@ int shiftaltleft, shiftaltright, shiftaltup, shiftaltdown;
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
ssize_t fill = -COLUMNS_FROM_EOL;
|
||||
/* The relative column where we will wrap lines. */
|
||||
ssize_t wrap_at = 0;
|
||||
size_t wrap_at = 0;
|
||||
/* The actual column where we will wrap lines, based on fill. */
|
||||
#endif
|
||||
|
||||
@@ -269,19 +272,6 @@ size_t light_from_col = 0;
|
||||
size_t light_to_col = 0;
|
||||
/* Where the spotlighted text ends. */
|
||||
|
||||
/* Return the number of entries in the shortcut list for a given menu. */
|
||||
size_t length_of_list(int menu)
|
||||
{
|
||||
funcstruct *f;
|
||||
size_t i = 0;
|
||||
|
||||
for (f = allfuncs; f != NULL; f = f->next)
|
||||
if ((f->menus & menu) && first_sc_for(menu, f->func) != NULL)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* To make the functions and shortcuts lists clearer. */
|
||||
#define VIEW TRUE /* Is allowed in view mode. */
|
||||
#define NOVIEW FALSE
|
||||
@@ -358,9 +348,9 @@ 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,
|
||||
bool blank_after, bool viewok)
|
||||
/* Add a function to the linked list of functions. */
|
||||
void add_to_funcs(void (*func)(void), int menus, const char *desc,
|
||||
const char *help, bool blank_after, bool viewok)
|
||||
{
|
||||
funcstruct *f = nmalloc(sizeof(funcstruct));
|
||||
|
||||
@@ -381,7 +371,7 @@ void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *h
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add a key combo to the shortcut list. */
|
||||
/* Add a key combo to the linked list of shortcuts. */
|
||||
void add_to_sclist(int menus, const char *scstring, const int keycode,
|
||||
void (*func)(void), int toggle)
|
||||
{
|
||||
@@ -438,6 +428,46 @@ int the_code_for(void (*func)(void), int defaultval)
|
||||
return s->keycode;
|
||||
}
|
||||
|
||||
/* Return the number of entries that can be shown in the given menu. */
|
||||
size_t shown_entries_for(int menu)
|
||||
{
|
||||
funcstruct *item = allfuncs;
|
||||
size_t maximum = ((COLS + 40) / 20) * 2;
|
||||
size_t count = 0;
|
||||
|
||||
while (count < maximum && item != NULL) {
|
||||
if (item->menus & menu)
|
||||
count++;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
/* When --tempfile is not used, widen the grid of the WriteOut menu. */
|
||||
if (menu == MWRITEFILE && first_sc_for(menu, discard_buffer) == NULL)
|
||||
count--;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Return the shortcut that corresponds to the values of kbinput (the
|
||||
* key itself) and meta_key (whether the key is a meta sequence). The
|
||||
* returned shortcut will be the first in the list that corresponds to
|
||||
* the given sequence. */
|
||||
const keystruct *get_shortcut(int *kbinput)
|
||||
{
|
||||
/* Plain characters cannot be shortcuts, so just skip those. */
|
||||
if (!meta_key && ((*kbinput >= 0x20 && *kbinput < 0x7F) ||
|
||||
(*kbinput >= 0xA0 && *kbinput <= 0xFF)))
|
||||
return NULL;
|
||||
|
||||
for (keystruct *s = sclist; s != NULL; s = s->next) {
|
||||
if ((s->menus & currmenu) && *kbinput == s->keycode &&
|
||||
meta_key == s->meta)
|
||||
return s;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return a pointer to the function that is bound to the given key. */
|
||||
functionptrtype func_from_key(int *kbinput)
|
||||
{
|
||||
@@ -449,18 +479,6 @@ functionptrtype func_from_key(int *kbinput)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the string and its corresponding keycode for the given shortcut s. */
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode)
|
||||
{
|
||||
s->keystr = keystring;
|
||||
s->meta = (keystring[0] == 'M' && keycode == 0);
|
||||
|
||||
if (keycode)
|
||||
s->keycode = keycode;
|
||||
else
|
||||
s->keycode = keycode_from_string(keystring);
|
||||
}
|
||||
|
||||
/* Parse the given keystring and return the corresponding keycode,
|
||||
* or return -1 when the string is invalid. */
|
||||
int keycode_from_string(const char *keystring)
|
||||
@@ -496,6 +514,18 @@ int keycode_from_string(const char *keystring)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the string and its corresponding keycode for the given shortcut s. */
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode)
|
||||
{
|
||||
s->keystr = keystring;
|
||||
s->meta = (keystring[0] == 'M' && keycode == 0);
|
||||
|
||||
if (keycode)
|
||||
s->keycode = keycode;
|
||||
else
|
||||
s->keycode = keycode_from_string(keystring);
|
||||
}
|
||||
|
||||
/* These two tags are used elsewhere too, so they are global. */
|
||||
/* TRANSLATORS: Try to keep the next two strings at most 10 characters. */
|
||||
const char *exit_tag = N_("Exit");
|
||||
@@ -675,8 +705,7 @@ void shortcut_init(void)
|
||||
/* Start populating the different menus with functions. */
|
||||
|
||||
add_to_funcs(do_help_void, (MMOST | MBROWSER) & ~MFINDINHELP,
|
||||
/* TRANSLATORS: Try to keep the next ninety strings or so at most 10
|
||||
* characters. Some strings may be longer -- run nano and see. */
|
||||
/* TRANSLATORS: Try to keep the next eleven strings at most 10 characters. */
|
||||
N_("Get Help"), WITHORSANS(help_gist), TOGETHER, VIEW);
|
||||
|
||||
add_to_funcs(do_cancel, ((MMOST & ~MMAIN) | MYESNO),
|
||||
@@ -724,14 +753,6 @@ void shortcut_init(void)
|
||||
add_to_funcs(do_replace, MMAIN,
|
||||
N_("Replace"), WITHORSANS(replace_gist), TOGETHER, NOVIEW);
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
add_to_funcs(goto_dir_void, MBROWSER,
|
||||
N_("Go To Dir"), WITHORSANS(gotodir_gist), TOGETHER, VIEW);
|
||||
|
||||
add_to_funcs(total_refresh, MBROWSER,
|
||||
N_("Refresh"), WITHORSANS(browserrefresh_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(cut_text, MMAIN,
|
||||
N_("Cut Text"), WITHORSANS(cut_gist), TOGETHER, NOVIEW);
|
||||
|
||||
@@ -750,6 +771,7 @@ void shortcut_init(void)
|
||||
}
|
||||
|
||||
add_to_funcs(do_cursorpos_void, MMAIN,
|
||||
/* TRANSLATORS: Try to keep the next thirteen strings at most 12 characters. */
|
||||
N_("Cur Pos"), WITHORSANS(cursorpos_gist), TOGETHER, VIEW);
|
||||
|
||||
#if (defined(ENABLE_JUSTIFY) && (defined(ENABLE_SPELLER) || defined(ENABLE_COLOR)) || \
|
||||
@@ -800,12 +822,14 @@ void shortcut_init(void)
|
||||
N_("FullJstify"), WITHORSANS(fulljustify_gist), BLANKAFTER, NOVIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_find_bracket, MMAIN,
|
||||
N_("To Bracket"), WITHORSANS(bracket_gist), BLANKAFTER, VIEW);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_BROWSER
|
||||
add_to_funcs(goto_dir_void, MBROWSER,
|
||||
/* TRANSLATORS: Try to keep the next seven strings at most 10 characters. */
|
||||
N_("Go To Dir"), WITHORSANS(gotodir_gist), TOGETHER, VIEW);
|
||||
|
||||
add_to_funcs(total_refresh, MBROWSER,
|
||||
N_("Refresh"), WITHORSANS(browserrefresh_gist), BLANKAFTER, VIEW);
|
||||
|
||||
add_to_funcs(do_search_forward, MBROWSER,
|
||||
N_("Where Is"), WITHORSANS(browserwhereis_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_search_backward, MBROWSER,
|
||||
@@ -813,6 +837,9 @@ void shortcut_init(void)
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_find_bracket, MMAIN,
|
||||
N_("To Bracket"), WITHORSANS(bracket_gist), BLANKAFTER, VIEW);
|
||||
|
||||
add_to_funcs(do_search_backward, MMAIN|MHELP,
|
||||
/* TRANSLATORS: This starts a backward search. */
|
||||
N_("Where Was"), WITHORSANS(wherewas_gist), TOGETHER, VIEW);
|
||||
@@ -847,6 +874,7 @@ void shortcut_init(void)
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_prev_word_void, MMAIN,
|
||||
/* TRANSLATORS: Try to keep the next eighteen strings at most 12 characters. */
|
||||
N_("Prev Word"), WITHORSANS(prevword_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_next_word_void, MMAIN,
|
||||
N_("Next Word"), WITHORSANS(nextword_gist), TOGETHER, VIEW);
|
||||
@@ -902,6 +930,7 @@ void shortcut_init(void)
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_tab, MMAIN,
|
||||
/* TRANSLATORS: The next four strings are names of keyboard keys. */
|
||||
N_("Tab"), WITHORSANS(tab_gist), TOGETHER, NOVIEW);
|
||||
add_to_funcs(do_enter, MMAIN,
|
||||
N_("Enter"), WITHORSANS(enter_gist), BLANKAFTER, NOVIEW);
|
||||
@@ -1057,7 +1086,7 @@ void shortcut_init(void)
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
add_to_funcs(do_page_up, MLINTER,
|
||||
/* TRANSLATORS: Try to keep the next two strings at most 20 characters. */
|
||||
/* TRANSLATORS: The next two strings may be up to 37 characters each. */
|
||||
N_("Prev Lint Msg"), WITHORSANS(prevlint_gist), TOGETHER, VIEW);
|
||||
add_to_funcs(do_page_down, MLINTER,
|
||||
N_("Next Lint Msg"), WITHORSANS(nextlint_gist), TOGETHER, VIEW);
|
||||
@@ -1120,7 +1149,7 @@ void shortcut_init(void)
|
||||
add_to_sclist(MMAIN, "M-6", 0, copy_text, 0);
|
||||
add_to_sclist(MMAIN, "M-^", 0, copy_text, 0);
|
||||
add_to_sclist(MMAIN, "M-}", 0, do_indent, 0);
|
||||
add_to_sclist(MMAIN, "Tab", TAB_CODE, do_indent, 0);
|
||||
add_to_sclist(MMAIN, "Tab", INDENT_KEY, do_indent, 0);
|
||||
add_to_sclist(MMAIN, "M-{", 0, do_unindent, 0);
|
||||
add_to_sclist(MMAIN, "Sh-Tab", SHIFT_TAB, do_unindent, 0);
|
||||
add_to_sclist(MMAIN, "M-:", 0, record_macro, 0);
|
||||
@@ -1380,7 +1409,7 @@ const char *flagtostr(int flag)
|
||||
{
|
||||
switch (flag) {
|
||||
case NO_HELP:
|
||||
/* TRANSLATORS: The next fourteen strings are toggle descriptions;
|
||||
/* TRANSLATORS: The next thirteen strings are toggle descriptions;
|
||||
* they are best kept shorter than 40 characters, but may be longer. */
|
||||
return N_("Help mode");
|
||||
case CONSTANT_SHOW:
|
||||
|
||||
@@ -40,7 +40,7 @@ static size_t location;
|
||||
/* The offset (in bytes) of the topleft of the shown help text. */
|
||||
|
||||
/* Hard-wrap the concatenated help text, and write it into a new buffer. */
|
||||
void wrap_help_text_into_buffer()
|
||||
void wrap_help_text_into_buffer(void)
|
||||
{
|
||||
size_t sum = 0;
|
||||
const char *ptr = start_of_body;
|
||||
|
||||
@@ -528,7 +528,7 @@ void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
|
||||
poshiststruct *posptr, *theone, *posprev = NULL;
|
||||
char *fullpath = get_full_path(filename);
|
||||
|
||||
if (fullpath == NULL || fullpath[strlen(fullpath) - 1] == '/') {
|
||||
if (fullpath == NULL || *filename == '\0') {
|
||||
free(fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
12
src/move.c
12
src/move.c
@@ -109,7 +109,7 @@ void set_proper_index_and_pww(size_t *leftedge, size_t target, bool forward)
|
||||
openfile->placewewant = *leftedge + target;
|
||||
}
|
||||
|
||||
/* Move up nearly one screenful. */
|
||||
/* Move up almost one screenful. */
|
||||
void do_page_up(void)
|
||||
{
|
||||
int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
|
||||
@@ -139,7 +139,7 @@ void do_page_up(void)
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
/* Move down nearly one screenful. */
|
||||
/* Move down almost one screenful. */
|
||||
void do_page_down(void)
|
||||
{
|
||||
int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
|
||||
@@ -534,7 +534,7 @@ void do_down(void)
|
||||
}
|
||||
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_HELP)
|
||||
/* Scroll up one line or chunk without scrolling the cursor. */
|
||||
/* Scroll up one line or chunk without moving the cursor textwise. */
|
||||
void do_scroll_up(void)
|
||||
{
|
||||
/* When the top of the file is onscreen, we can't scroll. */
|
||||
@@ -548,18 +548,18 @@ void do_scroll_up(void)
|
||||
edit_scroll(BACKWARD);
|
||||
}
|
||||
|
||||
/* Scroll down one line or chunk without scrolling the cursor. */
|
||||
/* Scroll down one line or chunk without moving the cursor textwise. */
|
||||
void do_scroll_down(void)
|
||||
{
|
||||
if (openfile->current_y == 0)
|
||||
do_down();
|
||||
|
||||
if (openfile->edittop->next != NULL
|
||||
if (editwinrows > 1 && (openfile->edittop->next != NULL
|
||||
#ifndef NANO_TINY
|
||||
|| chunk_for(openfile->firstcolumn, openfile->edittop) <
|
||||
number_of_chunks_in(openfile->edittop)
|
||||
#endif
|
||||
)
|
||||
))
|
||||
edit_scroll(FORWARD);
|
||||
}
|
||||
#endif
|
||||
|
||||
176
src/nano.c
176
src/nano.c
@@ -53,8 +53,8 @@ static int oldinterval = -1;
|
||||
/* Used to store the user's original mouse click interval. */
|
||||
#endif
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
static struct termios oldterm;
|
||||
/* The user's original terminal settings. */
|
||||
static struct termios original_state;
|
||||
/* The original settings of the user's terminal. */
|
||||
#else
|
||||
# define tcsetattr(...)
|
||||
# define tcgetattr(...)
|
||||
@@ -239,11 +239,11 @@ void partition_buffer(linestruct *top, size_t top_x,
|
||||
bot->data[bot_x] = '\0';
|
||||
|
||||
/* At the beginning of the partition, remove all text before top_x. */
|
||||
charmove(top->data, top->data + top_x, strlen(top->data) - top_x + 1);
|
||||
memmove(top->data, top->data + top_x, strlen(top->data) - top_x + 1);
|
||||
}
|
||||
|
||||
/* Unpartition the current buffer so that it is complete again. */
|
||||
void unpartition_buffer()
|
||||
void unpartition_buffer(void)
|
||||
{
|
||||
/* Reattach the line that was above the top of the partition. */
|
||||
openfile->filetop->prev = foreline;
|
||||
@@ -253,7 +253,7 @@ void unpartition_buffer()
|
||||
/* Restore the text that was on the first partition line before its start. */
|
||||
openfile->filetop->data = charealloc(openfile->filetop->data,
|
||||
strlen(antedata) + strlen(openfile->filetop->data) + 1);
|
||||
charmove(openfile->filetop->data + strlen(antedata),
|
||||
memmove(openfile->filetop->data + strlen(antedata),
|
||||
openfile->filetop->data, strlen(openfile->filetop->data) + 1);
|
||||
strncpy(openfile->filetop->data, antedata, strlen(antedata));
|
||||
free(antedata);
|
||||
@@ -288,10 +288,8 @@ void extract(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x)
|
||||
bool mark_inside = FALSE;
|
||||
bool same_line = FALSE;
|
||||
|
||||
if (top == bot && top_x == bot_x) {
|
||||
statusline(ALERT, "Extracting nothing -- please report a bug");
|
||||
if (top == bot && top_x == bot_x)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Partition the buffer so that it contains only the text from
|
||||
@@ -500,7 +498,7 @@ void finish(void)
|
||||
endwin();
|
||||
|
||||
/* Restore the old terminal settings. */
|
||||
tcsetattr(0, TCSANOW, &oldterm);
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
display_rcfile_errors();
|
||||
@@ -531,7 +529,7 @@ void die(const char *msg, ...)
|
||||
endwin();
|
||||
|
||||
/* Restore the old terminal settings. */
|
||||
tcsetattr(0, TCSANOW, &oldterm);
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
display_rcfile_errors();
|
||||
@@ -651,11 +649,12 @@ void window_init(void)
|
||||
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
/* Set up the wrapping point, accounting for screen width when negative. */
|
||||
wrap_at = fill;
|
||||
if (wrap_at <= 0)
|
||||
wrap_at += COLS;
|
||||
if (wrap_at < 0)
|
||||
if (COLS + fill < 0)
|
||||
wrap_at = 0;
|
||||
else if (fill <= 0)
|
||||
wrap_at = COLS + fill;
|
||||
else
|
||||
wrap_at = fill;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -685,7 +684,18 @@ void mouse_init(void)
|
||||
/* Print the usage line for the given option to the screen. */
|
||||
void print_opt(const char *shortflag, const char *longflag, const char *desc)
|
||||
{
|
||||
printf(" %-14s %-23s %s\n", shortflag, longflag, _(desc));
|
||||
int firstwidth = breadth(shortflag);
|
||||
int secondwidth = breadth(longflag);
|
||||
|
||||
printf(" %s", shortflag);
|
||||
if (firstwidth < 14)
|
||||
printf("%*s", 14 - firstwidth, " ");
|
||||
|
||||
printf(" %s", longflag);
|
||||
if (secondwidth < 24)
|
||||
printf("%*s", 24 - secondwidth, " ");
|
||||
|
||||
printf("%s\n", _(desc));
|
||||
}
|
||||
|
||||
/* Explain how to properly use nano and its command-line options. */
|
||||
@@ -698,7 +708,7 @@ void usage(void)
|
||||
"a '+' before the filename. The column number can be added after a comma.\n"));
|
||||
printf(_("When a filename is '-', nano reads data from standard input.\n\n"));
|
||||
/* TRANSLATORS: The next three are column headers of the --help output. */
|
||||
printf("%-16s%-26s%s\n", _("Option"), _("Long option"), _("Meaning"));
|
||||
print_opt(_("Option"), _("Long option"), N_("Meaning"));
|
||||
#ifndef NANO_TINY
|
||||
/* TRANSLATORS: The next forty or so strings are option descriptions
|
||||
* for the --help output. Try to keep them at most 40 characters. */
|
||||
@@ -730,7 +740,7 @@ void usage(void)
|
||||
print_opt("-I", "--ignorercfiles", N_("Don't look at nanorc files"));
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
print_opt("-J <number>", "--guidestripe=<number>",
|
||||
print_opt(_("-J <number>"), _("--guidestripe=<number>"),
|
||||
N_("Show a guiding bar at this column"));
|
||||
#endif
|
||||
print_opt("-K", "--rawsequences",
|
||||
@@ -754,7 +764,9 @@ void usage(void)
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
print_opt(_("-Q <regex>"), _("--quotestr=<regex>"),
|
||||
N_("Regular expression to match quoting"));
|
||||
/* TRANSLATORS: This refers to email quoting,
|
||||
* like the > in: > quoted text. */
|
||||
N_("Regular expression to match quoting"));
|
||||
#endif
|
||||
if (!ISSET(RESTRICTED))
|
||||
print_opt("-R", "--restricted", N_("Restricted mode"));
|
||||
@@ -1070,7 +1082,7 @@ void reconnect_and_store_state(void)
|
||||
|
||||
/* If input was not cut short, store the current state of the terminal. */
|
||||
if (!control_C_was_pressed)
|
||||
tcgetattr(0, &oldterm);
|
||||
tcgetattr(0, &original_state);
|
||||
}
|
||||
|
||||
/* Read whatever comes from standard input into a new buffer. */
|
||||
@@ -1080,7 +1092,7 @@ bool scoop_stdin(void)
|
||||
|
||||
/* Exit from curses mode and put the terminal into its original state. */
|
||||
endwin();
|
||||
tcsetattr(0, TCSANOW, &oldterm);
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
|
||||
/* When input comes from a terminal, show a helpful message. */
|
||||
if (isatty(STANDARD_INPUT))
|
||||
@@ -1205,7 +1217,7 @@ RETSIGTYPE do_suspend(int signal)
|
||||
fflush(stdout);
|
||||
|
||||
/* Restore the old terminal settings. */
|
||||
tcsetattr(0, TCSANOW, &oldterm);
|
||||
tcsetattr(0, TCSANOW, &original_state);
|
||||
|
||||
/* The suspend keystroke must not elicit cursor-position display. */
|
||||
suppress_cursorpos=TRUE;
|
||||
@@ -1380,12 +1392,12 @@ void do_toggle(int flag)
|
||||
void disable_extended_io(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios term = {0};
|
||||
struct termios settings = {0};
|
||||
|
||||
tcgetattr(0, &term);
|
||||
term.c_lflag &= ~IEXTEN;
|
||||
term.c_oflag &= ~OPOST;
|
||||
tcsetattr(0, TCSANOW, &term);
|
||||
tcgetattr(0, &settings);
|
||||
settings.c_lflag &= ~IEXTEN;
|
||||
settings.c_oflag &= ~OPOST;
|
||||
tcsetattr(0, TCSANOW, &settings);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1393,11 +1405,11 @@ void disable_extended_io(void)
|
||||
void disable_kb_interrupt(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios term = {0};
|
||||
struct termios settings = {0};
|
||||
|
||||
tcgetattr(0, &term);
|
||||
term.c_lflag &= ~ISIG;
|
||||
tcsetattr(0, TCSANOW, &term);
|
||||
tcgetattr(0, &settings);
|
||||
settings.c_lflag &= ~ISIG;
|
||||
tcsetattr(0, TCSANOW, &settings);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1405,11 +1417,11 @@ void disable_kb_interrupt(void)
|
||||
void enable_kb_interrupt(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios term = {0};
|
||||
struct termios settings = {0};
|
||||
|
||||
tcgetattr(0, &term);
|
||||
term.c_lflag |= ISIG;
|
||||
tcsetattr(0, TCSANOW, &term);
|
||||
tcgetattr(0, &settings);
|
||||
settings.c_lflag |= ISIG;
|
||||
tcsetattr(0, TCSANOW, &settings);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1417,11 +1429,11 @@ void enable_kb_interrupt(void)
|
||||
void disable_flow_control(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios term;
|
||||
struct termios settings;
|
||||
|
||||
tcgetattr(0, &term);
|
||||
term.c_iflag &= ~IXON;
|
||||
tcsetattr(0, TCSANOW, &term);
|
||||
tcgetattr(0, &settings);
|
||||
settings.c_iflag &= ~IXON;
|
||||
tcsetattr(0, TCSANOW, &settings);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1429,11 +1441,11 @@ void disable_flow_control(void)
|
||||
void enable_flow_control(void)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
struct termios term;
|
||||
struct termios settings;
|
||||
|
||||
tcgetattr(0, &term);
|
||||
term.c_iflag |= IXON;
|
||||
tcsetattr(0, TCSANOW, &term);
|
||||
tcgetattr(0, &settings);
|
||||
settings.c_iflag |= IXON;
|
||||
tcsetattr(0, TCSANOW, &settings);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1454,27 +1466,27 @@ void terminal_init(void)
|
||||
* disable the special control keys and interpretation of the flow
|
||||
* control characters using termios, save the terminal state after
|
||||
* the first call, and restore it on subsequent calls. */
|
||||
static struct termios newterm;
|
||||
static bool newterm_set = FALSE;
|
||||
static struct termios desired_state;
|
||||
static bool have_new_state = FALSE;
|
||||
|
||||
if (!newterm_set) {
|
||||
if (!have_new_state) {
|
||||
#endif
|
||||
raw();
|
||||
nonl();
|
||||
noecho();
|
||||
disable_extended_io();
|
||||
disable_kb_interrupt();
|
||||
|
||||
if (ISSET(PRESERVE))
|
||||
enable_flow_control();
|
||||
|
||||
disable_kb_interrupt();
|
||||
#ifdef USE_SLANG
|
||||
if (!ISSET(PRESERVE))
|
||||
else
|
||||
disable_flow_control();
|
||||
|
||||
tcgetattr(0, &newterm);
|
||||
newterm_set = TRUE;
|
||||
tcgetattr(0, &desired_state);
|
||||
have_new_state = TRUE;
|
||||
} else
|
||||
tcsetattr(0, TCSANOW, &newterm);
|
||||
tcsetattr(0, TCSANOW, &desired_state);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1810,7 +1822,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
/* Make room for the new character and copy it into the line. */
|
||||
openfile->current->data = charealloc(openfile->current->data,
|
||||
current_len + charlen + 1);
|
||||
charmove(openfile->current->data + openfile->current_x + charlen,
|
||||
memmove(openfile->current->data + openfile->current_x + charlen,
|
||||
openfile->current->data + openfile->current_x,
|
||||
current_len - openfile->current_x + 1);
|
||||
strncpy(openfile->current->data + openfile->current_x, onechar,
|
||||
@@ -1993,7 +2005,7 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
/* Back up the terminal settings so that they can be restored. */
|
||||
tcgetattr(0, &oldterm);
|
||||
tcgetattr(0, &original_state);
|
||||
|
||||
/* Get the state of standard input and ensure it uses blocking mode. */
|
||||
stdin_flags = fcntl(0, F_GETFL, 0);
|
||||
@@ -2317,18 +2329,8 @@ int main(int argc, char **argv)
|
||||
#ifdef ENABLE_SPELLER
|
||||
alt_speller = NULL;
|
||||
#endif
|
||||
|
||||
//#define TIMEIT 12
|
||||
#ifdef TIMEIT
|
||||
#include <time.h>
|
||||
clock_t start = clock();
|
||||
#endif
|
||||
/* Now process the system's and the user's nanorc file, if any. */
|
||||
do_rcfiles();
|
||||
#ifdef TIMEIT
|
||||
fprintf(stderr, "Took: %.3f\n",
|
||||
(double)(clock() - start) / CLOCKS_PER_SEC);
|
||||
#endif
|
||||
|
||||
/* If the backed-up command-line options have a value, restore them. */
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
@@ -2583,10 +2585,37 @@ int main(int argc, char **argv)
|
||||
/* Read the files mentioned on the command line into new buffers. */
|
||||
while (optind < argc && (!openfile || read_them_all)) {
|
||||
ssize_t givenline = 0, givencol = 0;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
char *searchstring = NULL;
|
||||
#endif
|
||||
/* If there's a +LINE[,COLUMN] argument here, eat it up. */
|
||||
if (optind < argc - 1 && argv[optind][0] == '+') {
|
||||
if (!parse_line_column(&argv[optind++][1], &givenline, &givencol))
|
||||
int n = 1;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
while (isalpha(argv[optind][n])) {
|
||||
switch (argv[optind][n++]) {
|
||||
case 'c': SET(CASE_SENSITIVE); break;
|
||||
case 'C': UNSET(CASE_SENSITIVE); break;
|
||||
case 'r': SET(USE_REGEXP); break;
|
||||
case 'R': UNSET(USE_REGEXP); break;
|
||||
default:
|
||||
statusline(ALERT, _("Invalid search modifier '%c'"),
|
||||
argv[optind][n - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (argv[optind][n] == '/' || argv[optind][n] == '?') {
|
||||
if (argv[optind][n + 1]) {
|
||||
searchstring = mallocstrcpy(NULL, &argv[optind][n + 1]);
|
||||
if (argv[optind][n] == '?')
|
||||
SET(BACKWARDS_SEARCH);
|
||||
} else if (n == 1)
|
||||
statusline(ALERT, _("Empty search string"));
|
||||
optind++;
|
||||
} else
|
||||
#endif
|
||||
if (!parse_line_column(&argv[optind++][n], &givenline, &givencol))
|
||||
statusline(ALERT, _("Invalid line or column number"));
|
||||
}
|
||||
|
||||
@@ -2602,6 +2631,23 @@ int main(int argc, char **argv)
|
||||
/* If a position was given on the command line, go there. */
|
||||
if (givenline != 0 || givencol != 0)
|
||||
do_gotolinecolumn(givenline, givencol, FALSE, FALSE);
|
||||
#ifndef NANO_TINY
|
||||
else if (searchstring != NULL) {
|
||||
if (ISSET(USE_REGEXP))
|
||||
regexp_init(searchstring);
|
||||
if (!findnextstr(searchstring, FALSE, JUSTFIND, NULL,
|
||||
ISSET(BACKWARDS_SEARCH), openfile->filetop, 0))
|
||||
not_found_msg(searchstring);
|
||||
else if (lastmessage == HUSH)
|
||||
wipe_statusbar();
|
||||
openfile->placewewant = xplustabs();
|
||||
if (ISSET(USE_REGEXP))
|
||||
tidy_up_after_search();
|
||||
free(last_search);
|
||||
last_search = searchstring;
|
||||
searchstring = NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_HISTORIES
|
||||
else if (ISSET(POSITIONLOG) && openfile->filename[0] != '\0') {
|
||||
ssize_t savedline, savedcol;
|
||||
|
||||
67
src/nano.h
67
src/nano.h
@@ -59,11 +59,9 @@
|
||||
#define ISSET(flag) ((FLAGS(flag) & FLAGMASK(flag)) != 0)
|
||||
#define TOGGLE(flag) FLAGS(flag) ^= FLAGMASK(flag)
|
||||
|
||||
/* Macros for character allocation and more. */
|
||||
#define charalloc(howmuch) (char *)nmalloc((howmuch) * sizeof(char))
|
||||
#define charealloc(ptr, howmuch) (char *)nrealloc(ptr, (howmuch) * sizeof(char))
|
||||
#define charmove(dest, src, n) memmove(dest, src, (n) * sizeof(char))
|
||||
#define charset(dest, src, n) memset(dest, src, (n) * sizeof(char))
|
||||
/* Macros for allocation of character strings. */
|
||||
#define charalloc(howmuch) (char *)nmalloc(howmuch)
|
||||
#define charealloc(ptr, howmuch) (char *)nrealloc(ptr, howmuch)
|
||||
|
||||
/* In UTF-8 a character is at most six bytes long. */
|
||||
#ifdef ENABLE_UTF8
|
||||
@@ -149,7 +147,7 @@
|
||||
/* Enumeration types. */
|
||||
typedef enum {
|
||||
NIX_FILE, DOS_FILE, MAC_FILE
|
||||
} file_format;
|
||||
} format_type;
|
||||
|
||||
typedef enum {
|
||||
HUSH, NOTICE, MILD, ALERT
|
||||
@@ -236,6 +234,8 @@ typedef struct syntaxtype {
|
||||
/* The list of libmagic results that this syntax applies to. */
|
||||
char *linter;
|
||||
/* The command with which to lint this type of file. */
|
||||
char *tab;
|
||||
/* What the Tab key should produce; NULL for default behavior. */
|
||||
#ifdef ENABLE_COMMENT
|
||||
char *comment;
|
||||
/* The line comment prefix (and postfix) for this type of file. */
|
||||
@@ -295,41 +295,43 @@ typedef struct linestruct {
|
||||
} linestruct;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct undo_group {
|
||||
typedef struct groupstruct {
|
||||
ssize_t top_line;
|
||||
/* First line of group. */
|
||||
ssize_t bottom_line;
|
||||
/* Last line of group. */
|
||||
char **indentations;
|
||||
/* String data used to restore the affected lines; one per line. */
|
||||
struct undo_group *next;
|
||||
} undo_group;
|
||||
struct groupstruct *next;
|
||||
/* The next group, if any. */
|
||||
} groupstruct;
|
||||
|
||||
typedef struct undo {
|
||||
ssize_t lineno;
|
||||
typedef struct undostruct {
|
||||
undo_type type;
|
||||
/* What type of undo this was. */
|
||||
/* The operation type that this undo item is for. */
|
||||
int xflags;
|
||||
/* Some flag data to mark certain corner cases. */
|
||||
ssize_t lineno;
|
||||
/* The line number where the operation began or ended. */
|
||||
size_t begin;
|
||||
/* Where did this action begin or end. */
|
||||
/* The x position where the operation began or ended. */
|
||||
char *strdata;
|
||||
/* String type data we will use for copying the affected line back. */
|
||||
/* String data to help restore the affected line. */
|
||||
size_t wassize;
|
||||
/* The file size before the action. */
|
||||
size_t newsize;
|
||||
/* The file size after the action. */
|
||||
int xflags;
|
||||
/* Some flag data we need. */
|
||||
undo_group *grouping;
|
||||
groupstruct *grouping;
|
||||
/* Undo info specific to groups of lines. */
|
||||
linestruct *cutbuffer;
|
||||
/* Copy of the cutbuffer. */
|
||||
/* A copy of the cutbuffer. */
|
||||
ssize_t mark_begin_lineno;
|
||||
/* Mostly the line number of the current line; sometimes something else. */
|
||||
size_t mark_begin_x;
|
||||
/* The x position corresponding to the above line number. */
|
||||
struct undo *next;
|
||||
struct undostruct *next;
|
||||
/* A pointer to the undo item of the preceding action. */
|
||||
} undo;
|
||||
} undostruct;
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifdef ENABLE_HISTORIES
|
||||
@@ -339,8 +341,9 @@ typedef struct poshiststruct {
|
||||
ssize_t lineno;
|
||||
/* Line number we left off on. */
|
||||
ssize_t xno;
|
||||
/* x position in the file we left off on. */
|
||||
/* The x position in the file we left off on. */
|
||||
struct poshiststruct *next;
|
||||
/* The next item of position history. */
|
||||
} poshiststruct;
|
||||
#endif
|
||||
|
||||
@@ -366,8 +369,6 @@ typedef struct openfilestruct {
|
||||
/* The file's x position we would like. */
|
||||
ssize_t current_y;
|
||||
/* The file's y-coordinate position. */
|
||||
bool modified;
|
||||
/* Whether the file has been modified. */
|
||||
struct stat *current_stat;
|
||||
/* The file's current stat information. */
|
||||
#ifdef ENABLE_WRAPPING
|
||||
@@ -381,19 +382,21 @@ typedef struct openfilestruct {
|
||||
/* The mark's x position in the above line. */
|
||||
mark_type kind_of_mark;
|
||||
/* Whether it is a soft (with Shift) or a hard mark. */
|
||||
file_format fmt;
|
||||
format_type fmt;
|
||||
/* The file's format -- Unix or DOS or Mac or mixed. */
|
||||
undo *undotop;
|
||||
char *lock_filename;
|
||||
/* The path of the lockfile, if we created one. */
|
||||
undostruct *undotop;
|
||||
/* The top of the undo list. */
|
||||
undo *current_undo;
|
||||
undostruct *current_undo;
|
||||
/* The current (i.e. next) level of undo. */
|
||||
undo *last_saved;
|
||||
undostruct *last_saved;
|
||||
/* The undo item at which the file was last saved. */
|
||||
undo_type last_action;
|
||||
/* The type of the last action the user performed. */
|
||||
char *lock_filename;
|
||||
/* The path of the lockfile, if we created one. */
|
||||
#endif
|
||||
bool modified;
|
||||
/* Whether the file has been modified. */
|
||||
#ifdef ENABLE_COLOR
|
||||
syntaxtype *syntax;
|
||||
/* The syntax struct for this file, if any. */
|
||||
@@ -605,6 +608,9 @@ enum
|
||||
#define SHIFT_DELETE 0x45D
|
||||
#define SHIFT_TAB 0x45F
|
||||
|
||||
/* A special keycode for when <Tab> is pressed while the mark is on. */
|
||||
#define INDENT_KEY 0x4F1
|
||||
|
||||
#ifdef USE_SLANG
|
||||
#ifdef ENABLE_UTF8
|
||||
#define KEY_BAD 0xFF /* Clipped error code. */
|
||||
@@ -626,9 +632,6 @@ enum
|
||||
#define WAS_MARKED_FORWARD (1<<5)
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* The maximum number of entries displayed in the main shortcut list. */
|
||||
#define MAIN_VISIBLE (((COLS + 40) / 20) * 2)
|
||||
|
||||
/* The default number of columns from end of line where wrapping occurs. */
|
||||
#define COLUMNS_FROM_EOL 8
|
||||
|
||||
|
||||
14
src/prompt.c
14
src/prompt.c
@@ -213,7 +213,7 @@ void do_statusbar_output(int *the_input, size_t input_len,
|
||||
|
||||
/* Insert the typed character into the existing answer string. */
|
||||
answer = charealloc(answer, strlen(answer) + charlen + 1);
|
||||
charmove(answer + typing_x + charlen, answer + typing_x,
|
||||
memmove(answer + typing_x + charlen, answer + typing_x,
|
||||
strlen(answer) - typing_x + 1);
|
||||
strncpy(answer + typing_x, onechar, charlen);
|
||||
|
||||
@@ -255,7 +255,7 @@ void do_statusbar_delete(void)
|
||||
if (answer[typing_x] != '\0') {
|
||||
int charlen = char_length(answer + typing_x);
|
||||
|
||||
charmove(answer + typing_x, answer + typing_x + charlen,
|
||||
memmove(answer + typing_x, answer + typing_x + charlen,
|
||||
strlen(answer) - typing_x - charlen + 1);
|
||||
}
|
||||
}
|
||||
@@ -394,7 +394,7 @@ void draw_the_promptbar(void)
|
||||
|
||||
/* Color the promptbar over its full width. */
|
||||
wattron(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
blank_statusbar();
|
||||
mvwprintw(bottomwin, 0, 0, "%*s", COLS, " ");
|
||||
|
||||
mvwaddstr(bottomwin, 0, 0, prompt);
|
||||
waddch(bottomwin, ':');
|
||||
@@ -424,12 +424,12 @@ void draw_the_promptbar(void)
|
||||
void add_or_remove_pipe_symbol_from_answer(void)
|
||||
{
|
||||
if (answer[0] == '|') {
|
||||
charmove(answer, answer + 1, strlen(answer) + 1);
|
||||
memmove(answer, answer + 1, strlen(answer) + 1);
|
||||
if (typing_x > 0)
|
||||
typing_x--;
|
||||
} else {
|
||||
answer = charealloc(answer, strlen(answer) + 2);
|
||||
charmove(answer + 1, answer, strlen(answer) + 1);
|
||||
memmove(answer + 1, answer, strlen(answer) + 1);
|
||||
answer[0] = '|';
|
||||
typing_x++;
|
||||
}
|
||||
@@ -695,9 +695,9 @@ int do_yesno_prompt(bool all, const char *msg)
|
||||
post_one_key(cancelshortcut->keystr, _("Cancel"), width);
|
||||
}
|
||||
|
||||
/* Color the statusbar over its full width and display the question. */
|
||||
/* Color the promptbar over its full width and display the question. */
|
||||
wattron(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
blank_statusbar();
|
||||
mvwprintw(bottomwin, 0, 0, "%*s", COLS, " ");
|
||||
mvwaddnstr(bottomwin, 0, 0, msg, actual_x(msg, COLS - 1));
|
||||
wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
|
||||
wnoutrefresh(bottomwin);
|
||||
|
||||
33
src/proto.h
33
src/proto.h
@@ -55,6 +55,8 @@ extern bool more_than_one;
|
||||
|
||||
extern bool also_the_last;
|
||||
|
||||
extern bool is_shorter;
|
||||
|
||||
extern int didfind;
|
||||
|
||||
extern int controlleft, controlright;
|
||||
@@ -75,7 +77,8 @@ extern int shiftaltup, shiftaltdown;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLED_WRAPORJUSTIFY
|
||||
extern ssize_t fill, wrap_at;
|
||||
extern ssize_t fill;
|
||||
extern size_t wrap_at;
|
||||
#endif
|
||||
|
||||
extern char *last_search;
|
||||
@@ -210,9 +213,12 @@ bool is_ascii_cntrl_char(int c);
|
||||
bool is_cntrl_mbchar(const char *c);
|
||||
bool is_word_mbchar(const char *c, bool allow_punct);
|
||||
char control_mbrep(const char *c, bool isdata);
|
||||
#ifdef ENABLE_UTF8
|
||||
int mbwidth(const char *c);
|
||||
#endif
|
||||
char *make_mbchar(long chr, int *chr_mb_len);
|
||||
int char_length(const char *pointer);
|
||||
size_t mbstrlen(const char *s);
|
||||
int parse_mbchar(const char *buf, char *chr, size_t *col);
|
||||
size_t step_left(const char *buf, size_t pos);
|
||||
size_t step_right(const char *buf, size_t pos);
|
||||
@@ -221,7 +227,6 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n);
|
||||
char *mbstrcasestr(const char *haystack, const char *needle);
|
||||
char *revstrstr(const char *haystack, const char *needle, const char *index);
|
||||
char *mbrevstrcasestr(const char *haystack, const char *needle, const char *index);
|
||||
size_t mbstrlen(const char *s);
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
|
||||
char *mbstrchr(const char *s, const char *c);
|
||||
#endif
|
||||
@@ -233,6 +238,7 @@ char *mbrevstrpbrk(const char *head, const char *accept, const char *index);
|
||||
#if defined(ENABLE_NANORC) && (!defined(NANO_TINY) || defined(ENABLE_JUSTIFY))
|
||||
bool has_blank_char(const char *s);
|
||||
#endif
|
||||
bool white_string(const char *s);
|
||||
#ifdef ENABLE_UTF8
|
||||
bool is_valid_unicode(wchar_t wc);
|
||||
#endif
|
||||
@@ -242,8 +248,8 @@ bool is_valid_unicode(wchar_t wc);
|
||||
void set_colorpairs(void);
|
||||
void color_init(void);
|
||||
void color_update(void);
|
||||
void set_up_multicache(linestruct *line);
|
||||
void check_the_multis(linestruct *line);
|
||||
void alloc_multidata_if_needed(linestruct *fileptr);
|
||||
void precalc_multicolorinfo(void);
|
||||
#endif
|
||||
|
||||
@@ -255,7 +261,7 @@ void chop_previous_word(void);
|
||||
void chop_next_word(void);
|
||||
void cut_marked(bool *right_side_up);
|
||||
#endif
|
||||
void do_cut_text(bool copying, bool marked, bool until_eof, bool append);
|
||||
void do_snip(bool copying, bool marked, bool until_eof, bool append);
|
||||
bool is_cuttable(bool test_cliff);
|
||||
void cut_text(void);
|
||||
#ifndef NANO_TINY
|
||||
@@ -314,9 +320,10 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
||||
#endif
|
||||
|
||||
/* Some functions in global.c. */
|
||||
size_t length_of_list(int menu);
|
||||
const keystruct *first_sc_for(int menu, void (*func)(void));
|
||||
int the_code_for(void (*func)(void), int defaultval);
|
||||
size_t shown_entries_for(int menu);
|
||||
const keystruct *get_shortcut(int *kbinput);
|
||||
functionptrtype func_from_key(int *kbinput);
|
||||
int keycode_from_string(const char *keystring);
|
||||
void assign_keyinfo(keystruct *s, const char *keystring, const int keycode);
|
||||
@@ -330,7 +337,7 @@ char *menu_to_name(int menu);
|
||||
|
||||
/* All functions in help.c. */
|
||||
#ifdef ENABLE_HELP
|
||||
void wrap_help_text_into_buffer();
|
||||
void wrap_help_text_into_buffer(void);
|
||||
void do_help(void);
|
||||
void help_init(void);
|
||||
functionptrtype parse_help_input(int *kbinput);
|
||||
@@ -396,7 +403,7 @@ void free_lines(linestruct *src);
|
||||
void renumber_from(linestruct *line);
|
||||
void partition_buffer(linestruct *top, size_t top_x,
|
||||
linestruct *bot, size_t bot_x);
|
||||
void unpartition_buffer();
|
||||
void unpartition_buffer(void);
|
||||
void extract(linestruct *top, size_t top_x, linestruct *bot, size_t bot_x);
|
||||
void ingraft_buffer(linestruct *somebuffer);
|
||||
void copy_from_buffer(linestruct *somebuffer);
|
||||
@@ -465,7 +472,7 @@ int do_yesno_prompt(bool all, const char *msg);
|
||||
|
||||
/* Most functions in rcfile.c. */
|
||||
#ifdef ENABLE_NANORC
|
||||
void display_rcfile_errors();
|
||||
void display_rcfile_errors(void);
|
||||
#ifdef ENABLE_COLOR
|
||||
void parse_one_include(char *file, syntaxtype *syntax);
|
||||
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage);
|
||||
@@ -476,6 +483,8 @@ void do_rcfiles(void);
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
/* Most functions in search.c. */
|
||||
bool regexp_init(const char *regexp);
|
||||
void tidy_up_after_search(void);
|
||||
int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
size_t *match_len, bool skipone, const linestruct *begin, size_t begin_x);
|
||||
void do_search(void);
|
||||
@@ -506,7 +515,6 @@ void do_tab(void);
|
||||
void do_indent(void);
|
||||
void do_unindent(void);
|
||||
#endif
|
||||
bool white_string(const char *s);
|
||||
#ifdef ENABLE_COMMENT
|
||||
void do_comment(void);
|
||||
#endif
|
||||
@@ -516,7 +524,7 @@ void do_enter(void);
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE cancel_command(int signal);
|
||||
bool execute_command(const char *command);
|
||||
void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep);
|
||||
void discard_until(const undostruct *thisitem, openfilestruct *thefile, bool keep);
|
||||
void add_undo(undo_type action);
|
||||
void update_multiline_undo(ssize_t lineno, char *indentation);
|
||||
void update_undo(undo_type action);
|
||||
@@ -531,6 +539,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl);
|
||||
size_t indent_length(const char *line);
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
size_t quote_length(const char *line);
|
||||
bool begpar(const linestruct *const foo, int depth);
|
||||
bool inpar(const linestruct *const foo);
|
||||
void do_justify(bool full_justify);
|
||||
@@ -612,8 +621,6 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count);
|
||||
#ifdef ENABLE_MOUSE
|
||||
int get_mouseinput(int *mouse_row, int *mouse_col, bool allow_shortcuts);
|
||||
#endif
|
||||
const keystruct *get_shortcut(int *kbinput);
|
||||
void blank_row(WINDOW *win, int y, int x, int n);
|
||||
void blank_edit(void);
|
||||
void blank_statusbar(void);
|
||||
void wipe_statusbar(void);
|
||||
@@ -628,8 +635,6 @@ void statusline(message_type importance, const char *msg, ...);
|
||||
void bottombars(int menu);
|
||||
void post_one_key(const char *keystroke, const char *tag, int width);
|
||||
void place_the_cursor(void);
|
||||
void edit_draw(linestruct *fileptr, const char *converted,
|
||||
int line, size_t from_col);
|
||||
int update_line(linestruct *fileptr, size_t index);
|
||||
#ifndef NANO_TINY
|
||||
int update_softwrapped_line(linestruct *fileptr);
|
||||
|
||||
41
src/rcfile.c
41
src/rcfile.c
@@ -152,7 +152,7 @@ static linestruct *errors_tail = NULL;
|
||||
/* Beginning and end of a list of errors in rcfiles, if any. */
|
||||
|
||||
/* Send the gathered error messages (if any) to the terminal. */
|
||||
void display_rcfile_errors()
|
||||
void display_rcfile_errors(void)
|
||||
{
|
||||
for (linestruct *error = errors_head; error != NULL; error = error->next)
|
||||
fprintf(stderr, "%s\n", error->data);
|
||||
@@ -333,6 +333,7 @@ void begin_new_syntax(char *ptr)
|
||||
live_syntax->headers = NULL;
|
||||
live_syntax->magics = NULL;
|
||||
live_syntax->linter = NULL;
|
||||
live_syntax->tab = NULL;
|
||||
#ifdef ENABLE_COMMENT
|
||||
live_syntax->comment = mallocstrcpy(NULL, GENERAL_COMMENT_CHARACTER);
|
||||
#endif
|
||||
@@ -362,8 +363,13 @@ void begin_new_syntax(char *ptr)
|
||||
void check_for_nonempty_syntax(void)
|
||||
{
|
||||
#ifdef ENABLE_COLOR
|
||||
if (opensyntax && !seen_color_command)
|
||||
if (opensyntax && !seen_color_command) {
|
||||
size_t current_lineno = lineno;
|
||||
|
||||
lineno = live_syntax->lineno;
|
||||
jot_error(N_("Syntax \"%s\" has no color commands"), live_syntax->name);
|
||||
lineno = current_lineno;
|
||||
}
|
||||
|
||||
opensyntax = FALSE;
|
||||
#endif
|
||||
@@ -557,9 +563,12 @@ bool is_good_file(char *file)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
/* Read and parse one included syntax file. */
|
||||
/* Partially parse the syntaxes in the given file, or (when syntax
|
||||
* is not NULL) fully parse one specific syntax from the file . */
|
||||
void parse_one_include(char *file, syntaxtype *syntax)
|
||||
{
|
||||
char *was_nanorc = nanorc;
|
||||
size_t was_lineno = lineno;
|
||||
augmentstruct *extra;
|
||||
FILE *rcstream;
|
||||
|
||||
@@ -567,7 +576,6 @@ void parse_one_include(char *file, syntaxtype *syntax)
|
||||
if (!is_good_file(file))
|
||||
return;
|
||||
|
||||
/* Open the included syntax file. */
|
||||
rcstream = fopen(file, "rb");
|
||||
|
||||
if (rcstream == NULL) {
|
||||
@@ -583,6 +591,8 @@ void parse_one_include(char *file, syntaxtype *syntax)
|
||||
/* If this is the first pass, parse only the prologue. */
|
||||
if (syntax == NULL) {
|
||||
parse_rcfile(rcstream, TRUE, TRUE);
|
||||
nanorc = was_nanorc;
|
||||
lineno = was_lineno;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -610,17 +620,20 @@ void parse_one_include(char *file, syntaxtype *syntax)
|
||||
|
||||
free(syntax->filename);
|
||||
syntax->filename = NULL;
|
||||
|
||||
nanorc = was_nanorc;
|
||||
lineno = was_lineno;
|
||||
}
|
||||
|
||||
/* Expand globs in the passed name, and parse the resultant files. */
|
||||
void parse_includes(char *ptr)
|
||||
{
|
||||
char *pattern, *expanded;
|
||||
char *was_nanorc = nanorc;
|
||||
size_t was_lineno = lineno;
|
||||
glob_t files;
|
||||
int result;
|
||||
|
||||
check_for_nonempty_syntax();
|
||||
|
||||
pattern = ptr;
|
||||
if (*pattern == '"')
|
||||
pattern++;
|
||||
@@ -640,11 +653,6 @@ void parse_includes(char *ptr)
|
||||
|
||||
globfree(&files);
|
||||
free(expanded);
|
||||
|
||||
/* We're done with the included file(s). Restore the original
|
||||
* filename and line number position. */
|
||||
nanorc = was_nanorc;
|
||||
lineno = was_lineno;
|
||||
}
|
||||
|
||||
/* Return the short value corresponding to the color named in colorname,
|
||||
@@ -940,6 +948,10 @@ bool parse_syntax_commands(char *keyword, char *ptr)
|
||||
else if (strcasecmp(keyword, "comment") == 0) {
|
||||
#ifdef ENABLE_COMMENT
|
||||
pick_up_name("comment", ptr, &live_syntax->comment);
|
||||
#endif
|
||||
} else if (strcasecmp(keyword, "tabgives") == 0) {
|
||||
#ifdef ENABLE_COLOR
|
||||
pick_up_name("tabgives", ptr, &live_syntax->tab);
|
||||
#endif
|
||||
} else if (strcasecmp(keyword, "linter") == 0)
|
||||
pick_up_name("linter", ptr, &live_syntax->linter);
|
||||
@@ -1083,6 +1095,7 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
} else if (intros_only && (strcasecmp(keyword, "color") == 0 ||
|
||||
strcasecmp(keyword, "icolor") == 0 ||
|
||||
strcasecmp(keyword, "comment") == 0 ||
|
||||
strcasecmp(keyword, "tabgives") == 0 ||
|
||||
strcasecmp(keyword, "linter") == 0)) {
|
||||
if (!opensyntax)
|
||||
jot_error(N_("A '%s' command requires a preceding "
|
||||
@@ -1156,8 +1169,6 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
option++;
|
||||
ptr = parse_argument(ptr);
|
||||
|
||||
option = mallocstrcpy(NULL, option);
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
/* When in a UTF-8 locale, ignore arguments with invalid sequences. */
|
||||
if (using_utf8() && mbstowcs(NULL, option, 0) == (size_t)-1) {
|
||||
@@ -1165,6 +1176,8 @@ void parse_rcfile(FILE *rcstream, bool just_syntax, bool intros_only)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
option = mallocstrcpy(NULL, option);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (strcasecmp(rcopts[i].name, "titlecolor") == 0)
|
||||
color_combo[TITLE_BAR] = parse_interface_color(option);
|
||||
@@ -1287,7 +1300,7 @@ void parse_one_nanorc(void)
|
||||
jot_error(N_("Error reading %s: %s"), nanorc, strerror(errno));
|
||||
}
|
||||
|
||||
bool have_nanorc(const char *path, char *name)
|
||||
bool have_nanorc(const char *path, const char *name)
|
||||
{
|
||||
if (path == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -98,7 +98,7 @@ void search_init(bool replacing, bool keep_the_answer)
|
||||
answer, &search_history, edit_refresh,
|
||||
/* TRANSLATORS: This is the main search prompt. */
|
||||
"%s%s%s%s%s%s", _("Search"),
|
||||
/* TRANSLATORS: The next five modify the search prompt. */
|
||||
/* TRANSLATORS: The next four modify the search prompt. */
|
||||
ISSET(CASE_SENSITIVE) ? _(" [Case Sensitive]") : "",
|
||||
ISSET(USE_REGEXP) ? _(" [Regexp]") : "",
|
||||
ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") : "",
|
||||
@@ -359,6 +359,8 @@ void do_research(void)
|
||||
/* Use the search-menu key bindings, to allow cancelling. */
|
||||
currmenu = MWHEREIS;
|
||||
|
||||
wipe_statusbar();
|
||||
|
||||
go_looking();
|
||||
|
||||
tidy_up_after_search();
|
||||
|
||||
165
src/text.c
165
src/text.c
@@ -76,12 +76,17 @@ const char *invocation_error(const char *name)
|
||||
* of spaces that a tab would normally take up. */
|
||||
void do_tab(void)
|
||||
{
|
||||
#ifdef ENABLE_COLOR
|
||||
if (openfile->syntax && openfile->syntax->tab)
|
||||
do_output(openfile->syntax->tab, strlen(openfile->syntax->tab), TRUE);
|
||||
else
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(TABS_TO_SPACES)) {
|
||||
char *spaces = charalloc(tabsize + 1);
|
||||
size_t length = tabsize - (xplustabs() % tabsize);
|
||||
|
||||
charset(spaces, ' ', length);
|
||||
memset(spaces, ' ', length);
|
||||
spaces[length] = '\0';
|
||||
|
||||
do_output(spaces, length, TRUE);
|
||||
@@ -105,7 +110,7 @@ void indent_a_line(linestruct *line, char *indentation)
|
||||
|
||||
/* Add the fabricated indentation to the beginning of the line. */
|
||||
line->data = charealloc(line->data, length + indent_len + 1);
|
||||
charmove(line->data + indent_len, line->data, length + 1);
|
||||
memmove(line->data + indent_len, line->data, length + 1);
|
||||
strncpy(line->data, indentation, indent_len);
|
||||
|
||||
openfile->totsize += indent_len;
|
||||
@@ -141,8 +146,13 @@ void do_indent(void)
|
||||
indentation = charalloc(tabsize + 1);
|
||||
|
||||
/* Set the indentation to either a bunch of spaces or a single tab. */
|
||||
#ifdef ENABLE_COLOR
|
||||
if (openfile->syntax && openfile->syntax->tab)
|
||||
indentation = mallocstrcpy(indentation, openfile->syntax->tab);
|
||||
else
|
||||
#endif
|
||||
if (ISSET(TABS_TO_SPACES)) {
|
||||
charset(indentation, ' ', tabsize);
|
||||
memset(indentation, ' ', tabsize);
|
||||
indentation[tabsize] = '\0';
|
||||
} else {
|
||||
indentation[0] = '\t';
|
||||
@@ -172,16 +182,28 @@ void do_indent(void)
|
||||
* but at most a tab's worth. */
|
||||
size_t length_of_white(const char *text)
|
||||
{
|
||||
size_t bytes_of_white = 0;
|
||||
size_t white_count = 0;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (openfile->syntax && openfile->syntax->tab) {
|
||||
size_t thelength = strlen(openfile->syntax->tab);
|
||||
|
||||
while (text[white_count] == openfile->syntax->tab[white_count])
|
||||
if (++white_count == thelength)
|
||||
return thelength;
|
||||
|
||||
white_count = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (TRUE) {
|
||||
if (*text == '\t')
|
||||
return ++bytes_of_white;
|
||||
return ++white_count;
|
||||
|
||||
if (*text != ' ')
|
||||
return bytes_of_white;
|
||||
return white_count;
|
||||
|
||||
if (++bytes_of_white == tabsize)
|
||||
if (++white_count == tabsize)
|
||||
return tabsize;
|
||||
|
||||
text++;
|
||||
@@ -217,7 +239,7 @@ void unindent_a_line(linestruct *line, size_t indent_len)
|
||||
return;
|
||||
|
||||
/* Remove the first tab's worth of whitespace from this line. */
|
||||
charmove(line->data, line->data + indent_len, length - indent_len + 1);
|
||||
memmove(line->data, line->data + indent_len, length - indent_len + 1);
|
||||
|
||||
openfile->totsize -= indent_len;
|
||||
|
||||
@@ -265,9 +287,9 @@ void do_unindent(void)
|
||||
}
|
||||
|
||||
/* Perform an undo or redo for an indent or unindent action. */
|
||||
void handle_indent_action(undo *u, bool undoing, bool add_indent)
|
||||
void handle_indent_action(undostruct *u, bool undoing, bool add_indent)
|
||||
{
|
||||
undo_group *group = u->grouping;
|
||||
groupstruct *group = u->grouping;
|
||||
linestruct *line = line_from_number(group->top_line);
|
||||
|
||||
if (group->next != NULL)
|
||||
@@ -297,15 +319,6 @@ void handle_indent_action(undo *u, bool undoing, bool add_indent)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Return TRUE when the given string is empty or consists of only blanks. */
|
||||
bool white_string(const char *s)
|
||||
{
|
||||
while (*s != '\0' && (is_blank_mbchar(s) || *s == '\r'))
|
||||
s += char_length(s);
|
||||
|
||||
return !*s;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COMMENT
|
||||
/* Test whether the given line can be uncommented, or add or remove a comment,
|
||||
* depending on action. Return TRUE if the line is uncommentable, or when
|
||||
@@ -328,10 +341,10 @@ bool comment_line(undo_type action, linestruct *line, const char *comment_seq)
|
||||
/* Make room for the comment sequence(s), move the text right and
|
||||
* copy them in. */
|
||||
line->data = charealloc(line->data, line_len + pre_len + post_len + 1);
|
||||
charmove(line->data + pre_len, line->data, line_len + 1);
|
||||
charmove(line->data, comment_seq, pre_len);
|
||||
memmove(line->data + pre_len, line->data, line_len + 1);
|
||||
memmove(line->data, comment_seq, pre_len);
|
||||
if (post_len > 0)
|
||||
charmove(line->data + pre_len + line_len, post_seq, post_len + 1);
|
||||
memmove(line->data + pre_len + line_len, post_seq, post_len + 1);
|
||||
|
||||
openfile->totsize += pre_len + post_len;
|
||||
|
||||
@@ -354,7 +367,7 @@ bool comment_line(undo_type action, linestruct *line, const char *comment_seq)
|
||||
return TRUE;
|
||||
|
||||
/* Erase the comment prefix by moving the non-comment part. */
|
||||
charmove(line->data, line->data + pre_len, line_len - pre_len);
|
||||
memmove(line->data, line->data + pre_len, line_len - pre_len);
|
||||
/* Truncate the postfix if there was one. */
|
||||
line->data[line_len - pre_len - post_len] = '\0';
|
||||
|
||||
@@ -431,9 +444,9 @@ void do_comment(void)
|
||||
}
|
||||
|
||||
/* Perform an undo or redo for a comment or uncomment action. */
|
||||
void handle_comment_action(undo *u, bool undoing, bool add_comment)
|
||||
void handle_comment_action(undostruct *u, bool undoing, bool add_comment)
|
||||
{
|
||||
undo_group *group = u->grouping;
|
||||
groupstruct *group = u->grouping;
|
||||
|
||||
/* When redoing, reposition the cursor and let the commenter adjust it. */
|
||||
if (!undoing)
|
||||
@@ -463,10 +476,9 @@ void handle_comment_action(undo *u, bool undoing, bool add_comment)
|
||||
#define redo_paste undo_cut
|
||||
#define undo_paste redo_cut
|
||||
|
||||
/* Undo a cut, or redo an uncut. */
|
||||
void undo_cut(undo *u)
|
||||
/* Undo a cut, or redo a paste. */
|
||||
void undo_cut(undostruct *u)
|
||||
{
|
||||
/* Get to where we need to uncut from. */
|
||||
if (u->xflags & WAS_WHOLE_LINE)
|
||||
goto_line_posx(u->mark_begin_lineno, 0);
|
||||
else
|
||||
@@ -487,8 +499,8 @@ void undo_cut(undo *u)
|
||||
goto_line_posx(u->mark_begin_lineno, u->mark_begin_x);
|
||||
}
|
||||
|
||||
/* Redo a cut, or undo an uncut. */
|
||||
void redo_cut(undo *u)
|
||||
/* Redo a cut, or undo a paste. */
|
||||
void redo_cut(undostruct *u)
|
||||
{
|
||||
linestruct *oldcutbuffer = cutbuffer;
|
||||
|
||||
@@ -503,7 +515,7 @@ void redo_cut(undo *u)
|
||||
openfile->mark = line_from_number(u->mark_begin_lineno);
|
||||
openfile->mark_x = (u->xflags & WAS_WHOLE_LINE) ? 0 : u->mark_begin_x;
|
||||
|
||||
do_cut_text(FALSE, TRUE, FALSE, u->type == ZAP);
|
||||
do_snip(FALSE, TRUE, FALSE, u->type == ZAP);
|
||||
|
||||
free_lines(cutbuffer);
|
||||
cutbuffer = oldcutbuffer;
|
||||
@@ -512,7 +524,7 @@ void redo_cut(undo *u)
|
||||
/* Undo the last thing(s) we did. */
|
||||
void do_undo(void)
|
||||
{
|
||||
undo *u = openfile->current_undo;
|
||||
undostruct *u = openfile->current_undo;
|
||||
linestruct *f = NULL, *t = NULL;
|
||||
linestruct *oldcutbuffer;
|
||||
char *data, *undidmsg = NULL;
|
||||
@@ -527,6 +539,7 @@ void do_undo(void)
|
||||
f = line_from_number(u->mark_begin_lineno);
|
||||
|
||||
openfile->current_x = u->begin;
|
||||
|
||||
switch (u->type) {
|
||||
case ADD:
|
||||
/* TRANSLATORS: The next thirteen strings describe actions
|
||||
@@ -681,7 +694,7 @@ void do_redo(void)
|
||||
{
|
||||
linestruct *f = NULL, *shoveline;
|
||||
char *data, *redidmsg = NULL;
|
||||
undo *u = openfile->undotop;
|
||||
undostruct *u = openfile->undotop;
|
||||
|
||||
if (u == NULL || u == openfile->current_undo) {
|
||||
statusbar(_("Nothing to redo"));
|
||||
@@ -1001,7 +1014,7 @@ bool execute_command(const char *command)
|
||||
if (ISSET(MULTIBUFFER)) {
|
||||
openfile = openfile->prev;
|
||||
if (openfile->mark)
|
||||
do_cut_text(TRUE, TRUE, FALSE, FALSE);
|
||||
do_snip(TRUE, TRUE, FALSE, FALSE);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@@ -1012,7 +1025,7 @@ bool execute_command(const char *command)
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
add_undo(CUT);
|
||||
do_cut_text(FALSE, openfile->mark != NULL, openfile->mark == NULL, FALSE);
|
||||
do_snip(FALSE, openfile->mark != NULL, openfile->mark == NULL, FALSE);
|
||||
update_undo(CUT);
|
||||
}
|
||||
|
||||
@@ -1071,10 +1084,10 @@ bool execute_command(const char *command)
|
||||
|
||||
/* Discard undo items that are newer than the given one, or all if NULL.
|
||||
* When keep is TRUE, do not touch the last_saved pointer. */
|
||||
void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep)
|
||||
void discard_until(const undostruct *thisitem, openfilestruct *thefile, bool keep)
|
||||
{
|
||||
undo *dropit = thefile->undotop;
|
||||
undo_group *group;
|
||||
undostruct *dropit = thefile->undotop;
|
||||
groupstruct *group;
|
||||
|
||||
while (dropit != NULL && dropit != thisitem) {
|
||||
thefile->undotop = dropit->next;
|
||||
@@ -1082,7 +1095,7 @@ void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep)
|
||||
free_lines(dropit->cutbuffer);
|
||||
group = dropit->grouping;
|
||||
while (group != NULL) {
|
||||
undo_group *next = group->next;
|
||||
groupstruct *next = group->next;
|
||||
free_chararray(group->indentations,
|
||||
group->bottom_line - group->top_line);
|
||||
free(group);
|
||||
@@ -1093,7 +1106,7 @@ void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep)
|
||||
}
|
||||
|
||||
/* Adjust the pointer to the top of the undo stack. */
|
||||
thefile->current_undo = (undo *)thisitem;
|
||||
thefile->current_undo = (undostruct *)thisitem;
|
||||
|
||||
/* Prevent a chain of editing actions from continuing. */
|
||||
thefile->last_action = OTHER;
|
||||
@@ -1101,20 +1114,15 @@ void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep)
|
||||
/* When requested, record that the undo stack was chopped, and
|
||||
* that thus there is no point at which the file was last saved. */
|
||||
if (!keep)
|
||||
thefile->last_saved = (undo *)0xbeeb;
|
||||
thefile->last_saved = (undostruct *)0xbeeb;
|
||||
}
|
||||
|
||||
/* Add a new undo item of the given type to the top of the current pile. */
|
||||
void add_undo(undo_type action)
|
||||
{
|
||||
undo *u = openfile->current_undo;
|
||||
/* The thing we did previously. */
|
||||
undostruct *u = nmalloc(sizeof(undostruct));
|
||||
|
||||
/* Blow away newer undo items if we add somewhere in the middle. */
|
||||
discard_until(u, openfile, TRUE);
|
||||
|
||||
/* Allocate and initialize a new undo item. */
|
||||
u = (undo *) nmalloc(sizeof(undo));
|
||||
/* Initialize the newly allocated undo item. */
|
||||
u->type = action;
|
||||
u->strdata = NULL;
|
||||
u->cutbuffer = NULL;
|
||||
@@ -1124,8 +1132,11 @@ void add_undo(undo_type action)
|
||||
u->mark_begin_x = openfile->current_x;
|
||||
u->wassize = openfile->totsize;
|
||||
u->newsize = openfile->totsize;
|
||||
u->xflags = 0;
|
||||
u->grouping = NULL;
|
||||
u->xflags = 0;
|
||||
|
||||
/* Blow away any undone items. */
|
||||
discard_until(openfile->current_undo, openfile, TRUE);
|
||||
|
||||
#ifdef ENABLE_WRAPPING
|
||||
/* If some action caused automatic long-line wrapping, insert the
|
||||
@@ -1237,7 +1248,7 @@ void add_undo(undo_type action)
|
||||
* added or removed is saved separately for each line in the undo item. */
|
||||
void update_multiline_undo(ssize_t lineno, char *indentation)
|
||||
{
|
||||
undo *u = openfile->current_undo;
|
||||
undostruct *u = openfile->current_undo;
|
||||
|
||||
/* If there already is a group and the current line is contiguous with it,
|
||||
* extend the group; otherwise, create a new group. */
|
||||
@@ -1252,7 +1263,7 @@ void update_multiline_undo(ssize_t lineno, char *indentation)
|
||||
u->grouping->indentations[number_of_lines - 1] = mallocstrcpy(NULL,
|
||||
indentation);
|
||||
} else {
|
||||
undo_group *born = (undo_group *)nmalloc(sizeof(undo_group));
|
||||
groupstruct *born = nmalloc(sizeof(groupstruct));
|
||||
|
||||
born->next = u->grouping;
|
||||
u->grouping = born;
|
||||
@@ -1271,7 +1282,7 @@ void update_multiline_undo(ssize_t lineno, char *indentation)
|
||||
* cursor position after the given action. */
|
||||
void update_undo(undo_type action)
|
||||
{
|
||||
undo *u = openfile->undotop;
|
||||
undostruct *u = openfile->undotop;
|
||||
char *char_buf;
|
||||
int charlen;
|
||||
|
||||
@@ -1426,6 +1437,13 @@ bool do_wrap(void)
|
||||
|
||||
add_undo(SPLIT_BEGIN);
|
||||
#endif
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
bool autowhite = ISSET(AUTOINDENT);
|
||||
size_t lead_len = quote_length(line->data);
|
||||
|
||||
if (lead_len > 0)
|
||||
UNSET(AUTOINDENT);
|
||||
#endif
|
||||
|
||||
/* The remainder is the text that will be wrapped to the next line. */
|
||||
remainder = line->data + wrap_loc;
|
||||
@@ -1455,10 +1473,19 @@ bool do_wrap(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Join the next line to this one, and delete any extra blanks. */
|
||||
do {
|
||||
/* Join the next line to this one. */
|
||||
do_delete();
|
||||
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
/* If the quoting part of the current line equals the quoting part of
|
||||
* what was the next line, then strip this second quoting part. */
|
||||
if (strncmp(line->data, line->data + openfile->current_x, lead_len) == 0)
|
||||
for (size_t i = lead_len; i > 0; i--)
|
||||
do_delete();
|
||||
#endif
|
||||
/* Remove any extra blanks. */
|
||||
while (is_blank_mbchar(&line->data[openfile->current_x]))
|
||||
do_delete();
|
||||
} while (is_blank_mbchar(&line->data[openfile->current_x]));
|
||||
}
|
||||
|
||||
/* Go to the wrap location. */
|
||||
@@ -1480,6 +1507,27 @@ bool do_wrap(void)
|
||||
/* Now split the line. */
|
||||
do_enter();
|
||||
|
||||
#ifdef ENABLE_JUSTIFY
|
||||
/* If the original line has quoting, copy it to the spillage line. */
|
||||
if (lead_len > 0) {
|
||||
lead_len += indent_length(line->data + lead_len);
|
||||
|
||||
line = line->next;
|
||||
line_len = strlen(line->data);
|
||||
line->data = charealloc(line->data, lead_len + line_len + 1);
|
||||
|
||||
memmove(line->data + lead_len, line->data, line_len + 1);
|
||||
strncpy(line->data, line->prev->data, lead_len);
|
||||
|
||||
openfile->current_x += lead_len;
|
||||
#ifndef NANO_TINY
|
||||
update_undo(ENTER);
|
||||
#endif
|
||||
if (autowhite)
|
||||
SET(AUTOINDENT);
|
||||
}
|
||||
#endif
|
||||
|
||||
openfile->spillage_line = openfile->current;
|
||||
|
||||
if (cursor_x < wrap_loc) {
|
||||
@@ -2019,7 +2067,7 @@ void do_justify(bool full_justify)
|
||||
if (needed_top_extra > 0) {
|
||||
cutbuffer->data = charealloc(cutbuffer->data,
|
||||
line_len + needed_top_extra + 1);
|
||||
charmove(cutbuffer->data + needed_top_extra, cutbuffer->data,
|
||||
memmove(cutbuffer->data + needed_top_extra, cutbuffer->data,
|
||||
line_len + 1);
|
||||
strncpy(cutbuffer->data, the_lead, needed_top_extra);
|
||||
line_len += needed_top_extra;
|
||||
@@ -2033,7 +2081,7 @@ void do_justify(bool full_justify)
|
||||
|
||||
/* Remove extra whitespace after the leading part. */
|
||||
if (indent_len > 0)
|
||||
charmove(cutbuffer->data + lead_len,
|
||||
memmove(cutbuffer->data + lead_len,
|
||||
cutbuffer->data + lead_len + indent_len,
|
||||
line_len - indent_len + 1);
|
||||
|
||||
@@ -2060,7 +2108,7 @@ void do_justify(bool full_justify)
|
||||
* remove the (now-redundant) addition we made earlier. */
|
||||
if (top_x > 0) {
|
||||
if (needed_top_extra > 0)
|
||||
charmove(cutbuffer->data, cutbuffer->data + needed_top_extra,
|
||||
memmove(cutbuffer->data, cutbuffer->data + needed_top_extra,
|
||||
strlen(cutbuffer->data) - needed_top_extra + 1);
|
||||
else {
|
||||
cutbuffer->prev = make_new_node(NULL);
|
||||
@@ -3154,6 +3202,7 @@ void complete_a_word(void)
|
||||
|
||||
/* If there is no word fragment before the cursor, do nothing. */
|
||||
if (start_of_shard == openfile->current_x) {
|
||||
/* TRANSLATORS: Shown when no text is directly left of the cursor. */
|
||||
statusbar(_("No word fragment"));
|
||||
pletion_line = NULL;
|
||||
return;
|
||||
|
||||
291
src/winio.c
291
src/winio.c
@@ -658,12 +658,8 @@ int parse_kbinput(WINDOW *win)
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When <Tab> is pressed while the mark is on, do an indent. */
|
||||
if (retval == TAB_CODE && openfile->mark && currmenu == MMAIN) {
|
||||
const keystruct *command = first_sc_for(MMAIN, do_indent);
|
||||
|
||||
meta_key = command->meta;
|
||||
return command->keycode;
|
||||
}
|
||||
if (retval == TAB_CODE && openfile->mark && currmenu == MMAIN)
|
||||
return INDENT_KEY;
|
||||
#endif
|
||||
|
||||
switch (retval) {
|
||||
@@ -1695,17 +1691,14 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Determine how many shortcuts will be shown. */
|
||||
number = length_of_list(currmenu);
|
||||
if (number > MAIN_VISIBLE)
|
||||
number = MAIN_VISIBLE;
|
||||
/* Determine how many shortcuts are being shown. */
|
||||
number = shown_entries_for(currmenu);
|
||||
|
||||
/* Calculate the width of each non-rightmost shortcut item;
|
||||
* the rightmost ones will "absorb" any remaining slack. */
|
||||
if (number < 2)
|
||||
width = COLS / (MAIN_VISIBLE / 2);
|
||||
/* Calculate the clickable width of each menu item. */
|
||||
if (number < 5)
|
||||
width = COLS / 2;
|
||||
else
|
||||
width = COLS / ((number / 2) + (number % 2));
|
||||
width = COLS / ((number + 1) / 2);
|
||||
|
||||
/* Calculate the one-based index in the shortcut list. */
|
||||
index = (*mouse_x / width) * 2 + *mouse_y;
|
||||
@@ -1768,74 +1761,45 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
|
||||
}
|
||||
#endif /* ENABLE_MOUSE */
|
||||
|
||||
/* Return the shortcut that corresponds to the values of kbinput (the
|
||||
* key itself) and meta_key (whether the key is a meta sequence). The
|
||||
* returned shortcut will be the first in the list that corresponds to
|
||||
* the given sequence. */
|
||||
const keystruct *get_shortcut(int *kbinput)
|
||||
/* Move (in the given window) to the given row and wipe it clean. */
|
||||
void blank_row(WINDOW *window, int row)
|
||||
{
|
||||
keystruct *s;
|
||||
|
||||
/* Plain characters cannot be shortcuts, so just skip those. */
|
||||
if (!meta_key && ((*kbinput >= 0x20 && *kbinput < 0x7F) ||
|
||||
(*kbinput >= 0xA0 && *kbinput <= 0xFF)))
|
||||
return NULL;
|
||||
|
||||
for (s = sclist; s != NULL; s = s->next) {
|
||||
if ((s->menus & currmenu) && *kbinput == s->keycode &&
|
||||
meta_key == s->meta)
|
||||
return s;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
wmove(window, row, 0);
|
||||
wclrtoeol(window);
|
||||
}
|
||||
|
||||
/* Move to (x, y) in win, and display a line of n spaces with the
|
||||
* current attributes. */
|
||||
void blank_row(WINDOW *win, int y, int x, int n)
|
||||
{
|
||||
wmove(win, y, x);
|
||||
|
||||
for (; n > 0; n--)
|
||||
waddch(win, ' ');
|
||||
}
|
||||
|
||||
/* Blank the first line of the top portion of the window. */
|
||||
/* Blank the first line of the top portion of the screen. */
|
||||
void blank_titlebar(void)
|
||||
{
|
||||
blank_row(topwin, 0, 0, COLS);
|
||||
mvwprintw(topwin, 0, 0, "%*s", COLS, " ");
|
||||
}
|
||||
|
||||
/* Blank all the lines of the middle portion of the window, i.e. the
|
||||
* edit window. */
|
||||
/* Blank all lines of the middle portion of the screen (the edit window). */
|
||||
void blank_edit(void)
|
||||
{
|
||||
int row;
|
||||
|
||||
for (row = 0; row < editwinrows; row++)
|
||||
blank_row(edit, row, 0, COLS);
|
||||
for (int row = 0; row < editwinrows; row++)
|
||||
blank_row(edit, row);
|
||||
}
|
||||
|
||||
/* Blank the first line of the bottom portion of the window. */
|
||||
/* Blank the first line of the bottom portion of the screen. */
|
||||
void blank_statusbar(void)
|
||||
{
|
||||
blank_row(bottomwin, 0, 0, COLS);
|
||||
blank_row(bottomwin, 0);
|
||||
}
|
||||
|
||||
/* Wipe the status bar clean and include this in the next screen update. */
|
||||
void wipe_statusbar(void)
|
||||
{
|
||||
blank_row(bottomwin, 0, 0, COLS);
|
||||
blank_row(bottomwin, 0);
|
||||
wnoutrefresh(bottomwin);
|
||||
}
|
||||
|
||||
/* If the NO_HELP flag isn't set, blank the last two lines of the bottom
|
||||
* portion of the window. */
|
||||
/* Blank out the two help lines (when they are present). */
|
||||
void blank_bottombars(void)
|
||||
{
|
||||
if (!ISSET(NO_HELP) && LINES > 4) {
|
||||
blank_row(bottomwin, 1, 0, COLS);
|
||||
blank_row(bottomwin, 2, 0, COLS);
|
||||
blank_row(bottomwin, 1);
|
||||
blank_row(bottomwin, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1926,11 +1890,13 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
#define ISO8859_CHAR FALSE
|
||||
#define ZEROWIDTH_CHAR (mbwidth(buf) == 0)
|
||||
#else
|
||||
#define ISO8859_CHAR ((unsigned char)*buf > 0x9F)
|
||||
#define ZEROWIDTH_CHAR FALSE
|
||||
#endif
|
||||
|
||||
while (*buf != '\0' && (column < beyond || mbwidth(buf) == 0)) {
|
||||
while (*buf != '\0' && (column < beyond || ZEROWIDTH_CHAR)) {
|
||||
/* A plain printable ASCII character is one byte, one column. */
|
||||
if (((signed char)*buf > 0x20 && *buf != DEL_CODE) || ISO8859_CHAR) {
|
||||
converted[index++] = *(buf++);
|
||||
@@ -2018,18 +1984,22 @@ char *display_string(const char *buf, size_t column, size_t span,
|
||||
|
||||
/* If there is more text than can be shown, make room for the ">". */
|
||||
if (column > beyond || (*buf != '\0' && (isprompt ||
|
||||
(isdata && !ISSET(SOFTWRAP))))) {
|
||||
(isdata && !ISSET(SOFTWRAP))))) {
|
||||
#ifdef ENABLE_UTF8
|
||||
do {
|
||||
index = step_left(converted, index);
|
||||
} while (mbwidth(converted + index) == 0);
|
||||
|
||||
#ifdef ENABLE_UTF8
|
||||
/* Display the left half of a two-column character as '['. */
|
||||
if (mbwidth(converted + index) == 2)
|
||||
converted[index++] = '[';
|
||||
#else
|
||||
index--;
|
||||
#endif
|
||||
}
|
||||
|
||||
is_shorter = (column < beyond);
|
||||
|
||||
/* Null-terminate the converted string. */
|
||||
converted[index] = '\0';
|
||||
|
||||
@@ -2321,14 +2291,11 @@ void bottombars(int menu)
|
||||
if (ISSET(NO_HELP) || LINES < 5)
|
||||
return;
|
||||
|
||||
/* Determine how many shortcuts there are to show. */
|
||||
number = length_of_list(menu);
|
||||
|
||||
if (number > MAIN_VISIBLE)
|
||||
number = MAIN_VISIBLE;
|
||||
/* Determine how many shortcuts must be shown. */
|
||||
number = shown_entries_for(menu);
|
||||
|
||||
/* Compute the width of each keyname-plus-explanation pair. */
|
||||
itemwidth = COLS / ((number / 2) + (number % 2));
|
||||
itemwidth = COLS / ((number + 1) / 2);
|
||||
|
||||
/* If there is no room, don't print anything. */
|
||||
if (itemwidth == 0)
|
||||
@@ -2413,24 +2380,19 @@ void place_the_cursor(void)
|
||||
openfile->current_y = row;
|
||||
}
|
||||
|
||||
/* edit_draw() takes care of the job of actually painting a line into
|
||||
* the edit window. fileptr is the line to be painted, at row row of
|
||||
* the window. converted is the actual string to be written to the
|
||||
* window, with tabs and control characters replaced by strings of
|
||||
* regular characters. from_col is the column number of the first
|
||||
* character of this page. That is, the first character of converted
|
||||
* corresponds to character number actual_x(fileptr->data, from_col) of the
|
||||
* line. */
|
||||
void edit_draw(linestruct *fileptr, const char *converted,
|
||||
int row, size_t from_col)
|
||||
/* Draw the given text on the given row of the edit window. line is the
|
||||
* line to be drawn, and converted is the actual string to be written with
|
||||
* tabs and control characters replaced by strings of regular characters.
|
||||
* from_col is the column number of the first character of this "page". */
|
||||
void draw_row(int row, const char *converted, linestruct *line, size_t from_col)
|
||||
{
|
||||
#if !defined(NANO_TINY) || defined(ENABLE_COLOR)
|
||||
size_t from_x = actual_x(fileptr->data, from_col);
|
||||
/* The position in fileptr->data of the leftmost character
|
||||
size_t from_x = actual_x(line->data, from_col);
|
||||
/* The position in the line's data of the leftmost character
|
||||
* that displays at least partially on the window. */
|
||||
size_t till_x = actual_x(fileptr->data, from_col + editwincols - 1) + 1;
|
||||
/* The position in fileptr->data of the first character that is
|
||||
* completely off the window to the right. Note that till_x
|
||||
size_t till_x = actual_x(line->data, from_col + editwincols - 1) + 1;
|
||||
/* The position in the line's data of the first character that
|
||||
* is completely off the window to the right. Note that till_x
|
||||
* might be beyond the null terminator of the string. */
|
||||
#endif
|
||||
|
||||
@@ -2441,10 +2403,10 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
wattron(edit, interface_color_pair[LINE_NUMBER]);
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP) && from_col != 0)
|
||||
mvwprintw(edit, row, 0, "%*s", margin - 1, " ");
|
||||
mvwprintw(edit, row, 0, "%*s", margin, " ");
|
||||
else
|
||||
#endif
|
||||
mvwprintw(edit, row, 0, "%*zd", margin - 1, fileptr->lineno);
|
||||
mvwprintw(edit, row, 0, "%*zd ", margin - 1, line->lineno);
|
||||
wattroff(edit, interface_color_pair[LINE_NUMBER]);
|
||||
}
|
||||
#endif
|
||||
@@ -2453,6 +2415,10 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
* and the marking highlight on just the pieces that need it. */
|
||||
mvwaddstr(edit, row, margin, converted);
|
||||
|
||||
/* When needed, clear the remainder of the row. */
|
||||
if (is_shorter || ISSET(SOFTWRAP))
|
||||
wclrtoeol(edit);
|
||||
|
||||
#ifdef USING_OLD_NCURSES
|
||||
/* Tell ncurses to really redraw the line without trying to optimize
|
||||
* for what it thinks is already there, because it gets it wrong in
|
||||
@@ -2467,8 +2433,8 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
const colortype *varnish = openfile->colorstrings;
|
||||
|
||||
/* If there are multiline regexes, make sure there is a cache. */
|
||||
if (openfile->syntax->nmultis > 0)
|
||||
alloc_multidata_if_needed(fileptr);
|
||||
if (openfile->syntax->nmultis > 0 && line->multidata == NULL)
|
||||
set_up_multicache(line);
|
||||
|
||||
/* Iterate through all the coloring regexes. */
|
||||
for (; varnish != NULL; varnish = varnish->next) {
|
||||
@@ -2482,9 +2448,9 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
/* The place in converted from where painting starts. */
|
||||
regmatch_t match;
|
||||
/* The match positions of a single-line regex. */
|
||||
const linestruct *start_line = fileptr->prev;
|
||||
/* The first line before fileptr that matches 'start'. */
|
||||
const linestruct *end_line = fileptr;
|
||||
const linestruct *start_line = line->prev;
|
||||
/* The first line before line that matches 'start'. */
|
||||
const linestruct *end_line = line;
|
||||
/* The line that matches 'end'. */
|
||||
regmatch_t startmatch, endmatch;
|
||||
/* The match positions of the start and end regexes. */
|
||||
@@ -2507,13 +2473,13 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
* unless index is zero. If regexec() returns
|
||||
* REG_NOMATCH, there are no more matches in the
|
||||
* line. */
|
||||
if (regexec(varnish->start, &fileptr->data[index], 1,
|
||||
if (regexec(varnish->start, &line->data[index], 1,
|
||||
&match, (index == 0) ? 0 : REG_NOTBOL) != 0)
|
||||
break;
|
||||
|
||||
/* If the match is of length zero, skip it. */
|
||||
if (match.rm_so == match.rm_eo) {
|
||||
index = step_right(fileptr->data, index + match.rm_eo);
|
||||
index = step_right(line->data, index + match.rm_eo);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2527,12 +2493,12 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
continue;
|
||||
|
||||
start_col = (match.rm_so <= from_x) ?
|
||||
0 : wideness(fileptr->data,
|
||||
0 : wideness(line->data,
|
||||
match.rm_so) - from_col;
|
||||
|
||||
thetext = converted + actual_x(converted, start_col);
|
||||
|
||||
paintlen = actual_x(thetext, wideness(fileptr->data,
|
||||
paintlen = actual_x(thetext, wideness(line->data,
|
||||
match.rm_eo) - from_col - start_col);
|
||||
|
||||
mvwaddnstr(edit, row, margin + start_col, thetext, paintlen);
|
||||
@@ -2543,7 +2509,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
/* Second case: varnish is a multiline expression. */
|
||||
|
||||
/* Assume nothing gets painted until proven otherwise below. */
|
||||
fileptr->multidata[varnish->id] = CNONE;
|
||||
line->multidata[varnish->id] = CNONE;
|
||||
|
||||
/* First check the multidata of the preceding line -- it tells
|
||||
* us about the situation so far, and thus what to do here. */
|
||||
@@ -2617,31 +2583,31 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
|
||||
/* If there is no end, there is nothing to paint. */
|
||||
if (end_line == NULL) {
|
||||
fileptr->multidata[varnish->id] = CWOULDBE;
|
||||
line->multidata[varnish->id] = CWOULDBE;
|
||||
goto tail_of_loop;
|
||||
}
|
||||
|
||||
/* If the end is on a later line, paint whole line, and be done. */
|
||||
if (end_line != fileptr) {
|
||||
if (end_line != line) {
|
||||
mvwaddnstr(edit, row, margin, converted, -1);
|
||||
fileptr->multidata[varnish->id] = CWHOLELINE;
|
||||
line->multidata[varnish->id] = CWHOLELINE;
|
||||
goto tail_of_loop;
|
||||
}
|
||||
|
||||
/* Only if it is visible, paint the part to be coloured. */
|
||||
if (endmatch.rm_eo > from_x) {
|
||||
paintlen = actual_x(converted, wideness(fileptr->data,
|
||||
paintlen = actual_x(converted, wideness(line->data,
|
||||
endmatch.rm_eo) - from_col);
|
||||
mvwaddnstr(edit, row, margin, converted, paintlen);
|
||||
}
|
||||
fileptr->multidata[varnish->id] = CBEGINBEFORE;
|
||||
line->multidata[varnish->id] = CBEGINBEFORE;
|
||||
|
||||
step_two:
|
||||
/* Second step: look for starts on this line, but begin
|
||||
* looking only after an end match, if there is one. */
|
||||
index = (paintlen == 0) ? 0 : endmatch.rm_eo;
|
||||
|
||||
while (regexec(varnish->start, fileptr->data + index,
|
||||
while (regexec(varnish->start, line->data + index,
|
||||
1, &startmatch, (index == 0) ?
|
||||
0 : REG_NOTBOL) == 0) {
|
||||
/* Translate the match to be relative to the
|
||||
@@ -2650,12 +2616,12 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
startmatch.rm_eo += index;
|
||||
|
||||
start_col = (startmatch.rm_so <= from_x) ?
|
||||
0 : wideness(fileptr->data,
|
||||
0 : wideness(line->data,
|
||||
startmatch.rm_so) - from_col;
|
||||
|
||||
thetext = converted + actual_x(converted, start_col);
|
||||
|
||||
if (regexec(varnish->end, fileptr->data + startmatch.rm_eo,
|
||||
if (regexec(varnish->end, line->data + startmatch.rm_eo,
|
||||
1, &endmatch, (startmatch.rm_eo == 0) ?
|
||||
0 : REG_NOTBOL) == 0) {
|
||||
/* Translate the end match to be relative to
|
||||
@@ -2666,27 +2632,27 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
* it is more than zero characters long. */
|
||||
if (endmatch.rm_eo > from_x &&
|
||||
endmatch.rm_eo > startmatch.rm_so) {
|
||||
paintlen = actual_x(thetext, wideness(fileptr->data,
|
||||
paintlen = actual_x(thetext, wideness(line->data,
|
||||
endmatch.rm_eo) - from_col - start_col);
|
||||
|
||||
mvwaddnstr(edit, row, margin + start_col,
|
||||
thetext, paintlen);
|
||||
|
||||
fileptr->multidata[varnish->id] = CSTARTENDHERE;
|
||||
line->multidata[varnish->id] = CSTARTENDHERE;
|
||||
}
|
||||
index = endmatch.rm_eo;
|
||||
/* If both start and end match are anchors, advance. */
|
||||
if (startmatch.rm_so == startmatch.rm_eo &&
|
||||
endmatch.rm_so == endmatch.rm_eo) {
|
||||
if (fileptr->data[index] == '\0')
|
||||
if (line->data[index] == '\0')
|
||||
break;
|
||||
index = step_right(fileptr->data, index);
|
||||
index = step_right(line->data, index);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* There is no end on this line. But maybe on later lines? */
|
||||
end_line = fileptr->next;
|
||||
end_line = line->next;
|
||||
|
||||
while (end_line != NULL && regexec(varnish->end, end_line->data,
|
||||
0, NULL, 0) == REG_NOMATCH)
|
||||
@@ -2694,13 +2660,13 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
|
||||
/* If there is no end, we're done with this regex. */
|
||||
if (end_line == NULL) {
|
||||
fileptr->multidata[varnish->id] = CWOULDBE;
|
||||
line->multidata[varnish->id] = CWOULDBE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Paint the rest of the line, and we're done. */
|
||||
mvwaddnstr(edit, row, margin + start_col, thetext, -1);
|
||||
fileptr->multidata[varnish->id] = CENDAFTER;
|
||||
line->multidata[varnish->id] = CENDAFTER;
|
||||
break;
|
||||
}
|
||||
tail_of_loop:
|
||||
@@ -2738,13 +2704,11 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
wattroff(edit, interface_color_pair[GUIDE_STRIPE]);
|
||||
}
|
||||
|
||||
/* If the mark is on, and fileptr is at least partially selected, we
|
||||
* need to paint it. */
|
||||
if (openfile->mark &&
|
||||
(fileptr->lineno <= openfile->mark->lineno ||
|
||||
fileptr->lineno <= openfile->current->lineno) &&
|
||||
(fileptr->lineno >= openfile->mark->lineno ||
|
||||
fileptr->lineno >= openfile->current->lineno)) {
|
||||
/* If the line is at least partially selected, paint the marked part. */
|
||||
if (openfile->mark && ((line->lineno >= openfile->mark->lineno &&
|
||||
line->lineno <= openfile->current->lineno) ||
|
||||
(line->lineno <= openfile->mark->lineno &&
|
||||
line->lineno >= openfile->current->lineno))) {
|
||||
const linestruct *top, *bot;
|
||||
/* The lines where the marked region begins and ends. */
|
||||
size_t top_x, bot_x;
|
||||
@@ -2758,15 +2722,15 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
|
||||
get_region(&top, &top_x, &bot, &bot_x, NULL);
|
||||
|
||||
if (top->lineno < fileptr->lineno || top_x < from_x)
|
||||
if (top->lineno < line->lineno || top_x < from_x)
|
||||
top_x = from_x;
|
||||
if (bot->lineno > fileptr->lineno || bot_x > till_x)
|
||||
if (bot->lineno > line->lineno || bot_x > till_x)
|
||||
bot_x = till_x;
|
||||
|
||||
/* Only paint if the marked part of the line is on this page. */
|
||||
if (top_x < till_x && bot_x > from_x) {
|
||||
/* Compute on which screen column to start painting. */
|
||||
start_col = wideness(fileptr->data, top_x) - from_col;
|
||||
start_col = wideness(line->data, top_x) - from_col;
|
||||
|
||||
if (start_col < 0)
|
||||
start_col = 0;
|
||||
@@ -2776,7 +2740,7 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
/* If the end of the mark is onscreen, compute how many
|
||||
* characters to paint. Otherwise, just paint all. */
|
||||
if (bot_x < till_x) {
|
||||
size_t end_col = wideness(fileptr->data, bot_x) - from_col;
|
||||
size_t end_col = wideness(line->data, bot_x) - from_col;
|
||||
paintlen = actual_x(thetext, end_col - start_col);
|
||||
}
|
||||
|
||||
@@ -2788,40 +2752,29 @@ void edit_draw(linestruct *fileptr, const char *converted,
|
||||
#endif /* !NANO_TINY */
|
||||
}
|
||||
|
||||
/* Redraw the line at fileptr. The line will be displayed so that the
|
||||
* character with the given index is visible -- if necessary, the line
|
||||
* will be horizontally scrolled. In softwrap mode, however, the entire
|
||||
* line will be passed to update_softwrapped_line(). Likely values of
|
||||
* index are current_x or zero. Return the number of additional rows
|
||||
* consumed (when softwrapping). */
|
||||
int update_line(linestruct *fileptr, size_t index)
|
||||
/* Redraw the given line so that the character at the given index is visible
|
||||
* -- if necessary, scroll the line horizontally (when not softwrapping).
|
||||
* Return the number of rows "consumed" (relevant when softwrapping). */
|
||||
int update_line(linestruct *line, size_t index)
|
||||
{
|
||||
int row = 0;
|
||||
int row;
|
||||
/* The row in the edit window we will be updating. */
|
||||
char *converted;
|
||||
/* The data of the line with tabs and control characters expanded. */
|
||||
size_t from_col = 0;
|
||||
size_t from_col;
|
||||
/* From which column a horizontally scrolled line is displayed. */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP))
|
||||
return update_softwrapped_line(fileptr);
|
||||
return update_softwrapped_line(line);
|
||||
#endif
|
||||
|
||||
row = fileptr->lineno - openfile->edittop->lineno;
|
||||
row = line->lineno - openfile->edittop->lineno;
|
||||
from_col = get_page_start(wideness(line->data, index));
|
||||
|
||||
/* First, blank out the row. */
|
||||
blank_row(edit, row, 0, COLS);
|
||||
|
||||
/* Next, find out from which column to start displaying the line. */
|
||||
from_col = get_page_start(wideness(fileptr->data, index));
|
||||
|
||||
/* Expand the line, replacing tabs with spaces, and control
|
||||
* characters with their displayed forms. */
|
||||
converted = display_string(fileptr->data, from_col, editwincols, TRUE, FALSE);
|
||||
|
||||
/* Draw the line. */
|
||||
edit_draw(fileptr, converted, row, from_col);
|
||||
/* Expand the piece to be drawn to its representable form, and draw it. */
|
||||
converted = display_string(line->data, from_col, editwincols, TRUE, FALSE);
|
||||
draw_row(row, converted, line, from_col);
|
||||
free(converted);
|
||||
|
||||
if (from_col > 0) {
|
||||
@@ -2829,7 +2782,7 @@ int update_line(linestruct *fileptr, size_t index)
|
||||
mvwaddch(edit, row, margin, '<');
|
||||
wattroff(edit, hilite_attribute);
|
||||
}
|
||||
if (breadth(fileptr->data) > from_col + editwincols) {
|
||||
if (breadth(line->data) > from_col + editwincols) {
|
||||
wattron(edit, hilite_attribute);
|
||||
mvwaddch(edit, row, COLS - 1, '>');
|
||||
wattroff(edit, hilite_attribute);
|
||||
@@ -2844,31 +2797,31 @@ int update_line(linestruct *fileptr, size_t index)
|
||||
#ifndef NANO_TINY
|
||||
/* Redraw all the chunks of the given line (as far as they fit onscreen),
|
||||
* unless it's edittop, which will be displayed from column firstcolumn.
|
||||
* Return the number of additional rows consumed. */
|
||||
int update_softwrapped_line(linestruct *fileptr)
|
||||
* Return the number of rows that were "consumed". */
|
||||
int update_softwrapped_line(linestruct *line)
|
||||
{
|
||||
int row = 0;
|
||||
/* The row in the edit window we will write to. */
|
||||
linestruct *line = openfile->edittop;
|
||||
linestruct *someline = openfile->edittop;
|
||||
/* An iterator needed to find the relevant row. */
|
||||
int starting_row;
|
||||
/* The first row in the edit window that gets updated. */
|
||||
size_t from_col = 0;
|
||||
/* The starting column of the current chunk. */
|
||||
size_t to_col = 0;
|
||||
/* To which column a line is displayed. */
|
||||
/* The end column of the current chunk. */
|
||||
char *converted;
|
||||
/* The data of the chunk with tabs and control characters expanded. */
|
||||
|
||||
if (fileptr == openfile->edittop)
|
||||
if (line == openfile->edittop)
|
||||
from_col = openfile->firstcolumn;
|
||||
else
|
||||
row -= chunk_for(openfile->firstcolumn, openfile->edittop);
|
||||
|
||||
/* Find out on which screen row the target line should be shown. */
|
||||
while (line != fileptr && line != NULL) {
|
||||
row += number_of_chunks_in(line) + 1;
|
||||
line = line->next;
|
||||
while (someline != line && someline != NULL) {
|
||||
row += number_of_chunks_in(someline) + 1;
|
||||
someline = someline->next;
|
||||
}
|
||||
|
||||
/* If the first chunk is offscreen, don't even try to display it. */
|
||||
@@ -2883,14 +2836,12 @@ int update_softwrapped_line(linestruct *fileptr)
|
||||
while (row < editwinrows) {
|
||||
bool end_of_line = FALSE;
|
||||
|
||||
to_col = get_softwrap_breakpoint(fileptr->data, from_col, &end_of_line);
|
||||
|
||||
blank_row(edit, row, 0, COLS);
|
||||
to_col = get_softwrap_breakpoint(line->data, from_col, &end_of_line);
|
||||
|
||||
/* Convert the chunk to its displayable form and draw it. */
|
||||
converted = display_string(fileptr->data, from_col, to_col - from_col,
|
||||
converted = display_string(line->data, from_col, to_col - from_col,
|
||||
TRUE, FALSE);
|
||||
edit_draw(fileptr, converted, row++, from_col);
|
||||
draw_row(row++, converted, line, from_col);
|
||||
free(converted);
|
||||
|
||||
if (end_of_line)
|
||||
@@ -2905,7 +2856,7 @@ int update_softwrapped_line(linestruct *fileptr)
|
||||
}
|
||||
|
||||
if (spotlighted && !inhelp)
|
||||
spotlight(light_from_col, light_to_col);
|
||||
spotlight_softwrapped(light_from_col, light_to_col);
|
||||
|
||||
return (row - starting_row);
|
||||
}
|
||||
@@ -3337,7 +3288,7 @@ void edit_refresh(void)
|
||||
}
|
||||
|
||||
while (row < editwinrows)
|
||||
blank_row(edit, row++, 0, COLS);
|
||||
blank_row(edit, row++);
|
||||
|
||||
place_the_cursor();
|
||||
wnoutrefresh(edit);
|
||||
@@ -3466,21 +3417,12 @@ void enable_waiting(void)
|
||||
/* Highlight the text between from_col and to_col. */
|
||||
void spotlight(size_t from_col, size_t to_col)
|
||||
{
|
||||
size_t right_edge;
|
||||
size_t right_edge = get_page_start(from_col) + editwincols;
|
||||
bool overshoots = FALSE;
|
||||
char *word;
|
||||
|
||||
place_the_cursor();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SOFTWRAP)) {
|
||||
spotlight_softwrapped(from_col, to_col);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
right_edge = get_page_start(from_col) + editwincols;
|
||||
|
||||
/* Limit the end column to the edge of the screen. */
|
||||
if (to_col > right_edge) {
|
||||
to_col = right_edge;
|
||||
@@ -3496,12 +3438,9 @@ void spotlight(size_t from_col, size_t to_col)
|
||||
to_col - from_col, FALSE, overshoots);
|
||||
|
||||
wattron(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
|
||||
waddnstr(edit, word, actual_x(word, to_col));
|
||||
|
||||
if (overshoots)
|
||||
mvwaddch(edit, openfile->current_y, COLS - 1, '>');
|
||||
|
||||
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
|
||||
free(word);
|
||||
@@ -3520,6 +3459,8 @@ void spotlight_softwrapped(size_t from_col, size_t to_col)
|
||||
bool end_of_line = FALSE;
|
||||
char *word;
|
||||
|
||||
place_the_cursor();
|
||||
|
||||
while (row < editwinrows) {
|
||||
break_col = get_softwrap_breakpoint(openfile->current->data,
|
||||
leftedge, &end_of_line);
|
||||
@@ -3540,9 +3481,7 @@ void spotlight_softwrapped(size_t from_col, size_t to_col)
|
||||
break_col - from_col, FALSE, FALSE);
|
||||
|
||||
wattron(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
|
||||
waddnstr(edit, word, actual_x(word, break_col));
|
||||
|
||||
wattroff(edit, interface_color_pair[SELECTED_TEXT]);
|
||||
|
||||
free(word);
|
||||
@@ -3550,7 +3489,7 @@ void spotlight_softwrapped(size_t from_col, size_t to_col)
|
||||
if (end_of_line)
|
||||
break;
|
||||
|
||||
wmove(edit, ++row, 0);
|
||||
wmove(edit, ++row, margin);
|
||||
|
||||
leftedge = break_col;
|
||||
from_col = break_col;
|
||||
|
||||
@@ -8,7 +8,7 @@ color red "\<[A-Z_]{2,}\>"
|
||||
color brightgreen "\.(data|subsection|text)"
|
||||
color green "\.(align|file|globl|global|hidden|section|size|type|weak)"
|
||||
color brightyellow "\.(ascii|asciz|byte|double|float|hword|int|long|short|single|struct|word)"
|
||||
icolor brightred "^[[:space:]]*[.0-9A-Z_]*:"
|
||||
color brightred "^[[:space:]]*[.0-9A-Za-z_]*:"
|
||||
color brightcyan "^[[:space:]]*#[[:space:]]*(define|undef|include|ifn?def|endif|elif|else|if|warning|error)"
|
||||
|
||||
# Strings.
|
||||
|
||||
@@ -6,7 +6,7 @@ magic "awk script"
|
||||
comment "#"
|
||||
|
||||
# Records.
|
||||
icolor brightred "\$[0-9A-Z_!@#$*?-]+"
|
||||
color brightred "\$[0-9A-Za-z_!@#$*?-]+"
|
||||
# Awk-set variables.
|
||||
color red "\<(ARGC|ARGIND|ARGV|BINMODE|CONVFMT|ENVIRON|ERRNO|FIELDWIDTHS)\>"
|
||||
color red "\<(FILENAME|FNR|FS|IGNORECASE|LINT|NF|NR|OFMT|OFS|ORS)\>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for C/C++.
|
||||
|
||||
syntax c "\.([ch](pp|xx)?|C|cc|c\+\+|H|hh|ii?)$"
|
||||
syntax c "\.([ch](pp|xx)?|C|cc|c\+\+|cu|H|hh|ii?)$"
|
||||
magic "^(C|C\+\+) (source|program)"
|
||||
comment "//"
|
||||
|
||||
@@ -10,7 +10,7 @@ color brightred "\<[A-Z_][0-9A-Z_]+\>"
|
||||
color brightmagenta "^[[:space:]]*[A-Z_a-z]+:[[:space:]]*$"
|
||||
|
||||
color green "\<(float|double|bool|char|int|short|long|sizeof|enum|void|auto|static|const|struct|union|typedef|extern|(un)?signed|inline)\>"
|
||||
color green "\<([[:lower:]]+|(u_?)?int(8|16|32|64|ptr))_t\>"
|
||||
color green "\<([[:lower:]][[:lower:]_]*|(u_?)?int(8|16|32|64))_t\>"
|
||||
color green "\<(class|namespace|template|public|protected|private|typename|this|friend|virtual|override|using|mutable|volatile|register|explicit)\>"
|
||||
color brightyellow "\<(for|if|while|do|else|case|default|switch)\>"
|
||||
color brightyellow "\<(try|throw|catch|operator|new|delete)\>"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
syntax cmake "(CMakeLists\.txt|\.cmake)$"
|
||||
comment "#"
|
||||
|
||||
icolor green "^[[:space:]]*[A-Z0-9_]+"
|
||||
color green "^[[:space:]]*[0-9A-Za-z_]+"
|
||||
icolor brightyellow "^[[:space:]]*(include|include_directories|include_external_msproject)\>"
|
||||
|
||||
icolor brightgreen "^[[:space:]]*((else|end)?if|else|(end)?while|(end)?foreach|break)\>"
|
||||
@@ -12,7 +12,7 @@ color brightgreen "[[:space:]](OR|AND|IS_NEWER_THAN|MATCHES|(STR|VERSION_)?(LESS
|
||||
|
||||
icolor brightred "^[[:space:]]*((end)?(function|macro)|return)"
|
||||
|
||||
icolor cyan start="\$(\{|ENV\{)" end="\}"
|
||||
icolor cyan start="\$(ENV)?\{" end="\}"
|
||||
color magenta "\<(APPLE|UNIX|WIN32|CYGWIN|BORLAND|MINGW|MSVC(_IDE|60|71|80|90)?)\>"
|
||||
|
||||
color brightblue "(^|[[:space:]])#.*"
|
||||
|
||||
@@ -15,3 +15,6 @@ color brightred "(GNU )?[Nn]ano [1-4]\.[0-9][-.[:alnum:]]*\>"
|
||||
|
||||
# Email addresses.
|
||||
color magenta "<[[:alnum:].%_+-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}>"
|
||||
|
||||
# Bracketed captions in certain config files.
|
||||
color brightgreen "^\[.*\]$"
|
||||
|
||||
@@ -34,7 +34,7 @@ icolor yellow "\<(.or.|repeat|select case|then|where|while)\>"
|
||||
icolor magenta "\<(continue|cycle|exit|go?to|result|return)\>"
|
||||
|
||||
# Strings.
|
||||
icolor yellow "<[^= ]*>" ""(\\.|[^"])*""
|
||||
color yellow "<[^= ]*>" ""(\\.|[^"])*""
|
||||
|
||||
# Comments.
|
||||
icolor blue "!.*"
|
||||
color blue "!.*"
|
||||
|
||||
@@ -44,7 +44,7 @@ color brightmagenta "\<(false|nil|true)\>"
|
||||
|
||||
# Decimal and hexadecimal numbers
|
||||
color red "\<[0-9]+(\.[0-9]*)?([Ee][+-]?[0-9]+)?\>"
|
||||
icolor red "\<0x[0-9a-f]+(\.[0-9a-f]*)?(p[+-]?[0-9]+)?\>"
|
||||
color red "\<0x[0-9A-Fa-f]+(\.[0-9A-Fa-f]*)?([Pp][+-]?[0-9]+)?\>"
|
||||
|
||||
# Brackets
|
||||
color brightmagenta "\(|\)|\[|\]|\{|\}"
|
||||
|
||||
@@ -4,6 +4,6 @@ syntax mgp "\.mgp$"
|
||||
header "^%include.*"
|
||||
comment "#"
|
||||
|
||||
icolor green "^%[a-z].*"
|
||||
color green "^%[A-Za-z].*"
|
||||
color cyan "(^|[[:space:]])(#|%%).*"
|
||||
color ,green "[[:space:]]+$"
|
||||
|
||||
@@ -4,7 +4,7 @@ syntax nanorc "\.?nanorc$"
|
||||
comment "#"
|
||||
|
||||
# Possible errors and parameters
|
||||
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|i?color|extendsyntax).*"
|
||||
icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|tabgives|i?color|extendsyntax).*"
|
||||
|
||||
# Keywords
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|breaklonglines|casesensitive|constantshow|cutfromcursor|emptyline|finalnewline|historylog|jumpyscrolling|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabstospaces|tempfile|trimblanks|unix|view|wordbounds|zap)\>"
|
||||
@@ -13,9 +13,9 @@ icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|errorcolor|f
|
||||
icolor brightgreen "^[[:space:]]*set[[:space:]]+(fill[[:space:]]+-?[[:digit:]]+|(guidestripe|tabsize)[[:space:]]+[1-9][0-9]*)\>"
|
||||
icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]@\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+([[:alpha:]]+|".*")[[:space:]]+(all|main|search|replace(with)?|yesno|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)"
|
||||
icolor brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([[:alpha:]]|[]@\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|yesno|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)[[:space:]]+.*"
|
||||
icolor brightgreen "^[[:space:]]*extendsyntax[[:space:]]+[[:alpha:]]+[[:space:]]+(i?color|header|magic|comment|linter|tabgives)[[:space:]]+.*"
|
||||
icolor brightgreen "^[[:space:]]*(syntax|linter)[[:space:]]+[^[:blank:]]+"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|extendsyntax)\>"
|
||||
icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment|linter|tabgives|extendsyntax)\>"
|
||||
|
||||
# Strings
|
||||
color brightmagenta "([[:space:]]|(start|end)=)".+"([[:space:]]|$)"
|
||||
|
||||
@@ -7,9 +7,18 @@ comment "#"
|
||||
|
||||
color red "\<(accept|alarm|atan2|bin(d|mode)|c(aller|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork))\>" "\<(get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join)\>" "\<(keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek(dir)?)\>" "\<(se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr(y)?|truncate|umask)\>" "\<(un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\>"
|
||||
color magenta "\<(continue|else|elsif|do|for|foreach|if|unless|until|while|eq|ne|lt|gt|le|ge|cmp|x|my|sub|use|package|can|isa)\>"
|
||||
icolor cyan start="[$@%]" end="( |[^0-9A-Z_]|-)"
|
||||
|
||||
# Variable names.
|
||||
color cyan "[$%&@]([A-Za-z_][0-9A-Za-z_]*|\^[][A-Z?\^_]|[0-9]+)\>"
|
||||
color cyan "[$%&@]\{(\^?[A-Za-z_][0-9A-Za-z_]*|\^[][?\^][0-9]+)\}"
|
||||
color cyan "[$%&@]([][!"#'()*+,.:;<=>?`|~-]|\{[][!-/:-@\`|~]\})|\$[$%&@]"
|
||||
color cyan "(^|[[:space:]])[$%@][/\]"
|
||||
|
||||
color yellow "".*"|qq\|.*\|"
|
||||
color white "[sm]/.*/"
|
||||
color white start="(^use| = new)" end=";"
|
||||
color green "#.*"
|
||||
|
||||
# Comments.
|
||||
color green "(^|[[:space:]])#.*"
|
||||
|
||||
color yellow start="<< 'STOP'" end="STOP"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Here is an example for PHP.
|
||||
|
||||
syntax php "\.ph(p[23457s~]?|tml)$"
|
||||
syntax php "\.(php[23457s~]?|phtml|ctp)$"
|
||||
magic "PHP script"
|
||||
comment "//"
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ color brightmagenta "\<(Project\-Id\-Version|Report\-Msgid\-Bugs\-To|Last\-Trans
|
||||
color cyan "\<(POT\-Creation\-Date|PO\-Revision\-Date|MIME\-Version|Content\-Type|Content\-Transfer\-Encoding)\>"
|
||||
# Encodings and numbers.
|
||||
color yellow "\<(UTF|ISO|Windows|Mac|IBM)-[0-9]+"
|
||||
color yellow "[0-9]|pre[0-9]|[0-9]bit"
|
||||
color yellow "\<((pre|rc)?[0-9]+|[0-9]bit)\>"
|
||||
# Msgids.
|
||||
color brightblue "^(msgid|msgid_plural|msgstr)\>"
|
||||
# Tags.
|
||||
|
||||
@@ -7,7 +7,7 @@ linter pyflakes
|
||||
comment "#"
|
||||
|
||||
# Function definitions.
|
||||
icolor brightblue "def [0-9A-Z_]+"
|
||||
color brightblue "def [0-9A-Za-z_]+"
|
||||
# Keywords.
|
||||
color brightcyan "\<(and|as|assert|async|await|break|class|continue)\>"
|
||||
color brightcyan "\<(def|del|elif|else|except|finally|for|from)\>"
|
||||
|
||||
@@ -12,7 +12,7 @@ color yellow "\<(next|nil|not|or|redo|rescue|retry|return|self|super|then|true|u
|
||||
# Constants.
|
||||
color brightblue "(\$|@|@@)?\<[A-Z]+[0-9A-Z_a-z]*"
|
||||
# Ruby "symbols".
|
||||
icolor magenta "([ ]|^):[0-9A-Z_]+\>"
|
||||
color magenta "([ ]|^):[0-9A-Za-z_]+\>"
|
||||
# Some unique things we want to stand out.
|
||||
color brightyellow "\<(__FILE__|__LINE__)\>"
|
||||
# Regular expressions.
|
||||
|
||||
@@ -11,7 +11,7 @@ comment "//"
|
||||
color magenta "fn [a-z_0-9]+"
|
||||
|
||||
# Reserved words
|
||||
color yellow "\<(abstract|alignof|as|become|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|pub|pure|ref|return|sizeof|static|self|struct|super|true|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\>"
|
||||
color yellow "\<(abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|true|try|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\>"
|
||||
|
||||
# Macros
|
||||
color red "[a-z_]+!"
|
||||
|
||||
@@ -5,6 +5,6 @@ magic "(La)?TeX document"
|
||||
linter chktex -v0 -q -I
|
||||
comment "%"
|
||||
|
||||
icolor green "\\.|\\[A-Z]*"
|
||||
color green "\\.|\\[A-Za-z]*"
|
||||
color magenta "[{}]"
|
||||
color blue "(^|[^\])%.*"
|
||||
|
||||
Reference in New Issue
Block a user