DLR and DB's latest fixes

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1345 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2003-01-13 01:35:15 +00:00
parent 3f1b6851cb
commit 7662c86dbf
13 changed files with 526 additions and 366 deletions

113
ChangeLog
View File

@ -1,21 +1,27 @@
CVS code - CVS code -
Changes Changes
- General: - General:
- Completely removed PICO_MODE, as with the search/replace history - Completely removed PICO_MODE, as with the search/replace
patch we should have the extended functionality we can without history patch we should have the extended functionality we can
being incompatible with pico. Removed all code for different without being incompatible with Pico. Removed all code for
search/replace string editing and alternate shortcut list. I'm sure different search/replace string editing and alternate shortcut
I won't even have to ask for feedback on this one :-) list. I'm sure I won't even have to ask for feedback on this
- Add in Pico's -p flag, (-p, --preserve). To preserve the XON and XOFF one :-)
keys (^Q and ^S). Add warning if we invoke -p and add checks for - Add in Pico's -p flag, (-p, --preserve). To preserve the XON
using --preserve (to skip warning) and --pico (to force showing it). and XOFF keys (^Q and ^S). Add warning if we invoke -p and
New flag PRESERVE, function do_preserve_msg(), changes to main(), add checks for using --preserve (to skip warning) and --pico
signal_init(). (to force showing it). New flag PRESERVE, function
- Search history and replace history up/down cursor arrows, w/history do_preserve_msg(), changes to main(), signal_init().
tab completion, not available w/NANO_SMALL. Changes to - Search history and replace history up/down cursor arrows,
statusq, others (Ken Tyler). Added shortcut to search/replace w/history tab completion, not available w/NANO_SMALL. Changes
shortcuts so people will know it's there, forced KEY_UP and KEY_DOWN to statusq(), others (Ken Tyler). Added shortcut to
defs in nano.h (Chris, in case blame needs to be placed later). search/replace shortcuts so people will know it's there,
forced KEY_UP and KEY_DOWN defs in nano.h (Chris, in case
blame needs to be placed later). Minor fixes by DLR: allow ^P
and ^N as alternatives to the up and down arrows, make sure
the "Up" shortcut is displayed properly in the help menu,
remove a few bits of unneeded and/or warning-generating code,
and fix some missing statusq() prompts with --enable-tiny.
- Translation updates (see po/ChangeLog for details). - Translation updates (see po/ChangeLog for details).
- Forward-ported Chris' --disable-wrapping-as-root option from - Forward-ported Chris' --disable-wrapping-as-root option from
1.0.9. Per Jordi's suggestions, have it override 1.0.9. Per Jordi's suggestions, have it override
@ -38,6 +44,12 @@ Changes
- Define KEY_IC properly (and KEY_DC more portably) when slang - Define KEY_IC properly (and KEY_DC more portably) when slang
support is enabled, and remove the hack to work around the support is enabled, and remove the hack to work around the
former's not being defined. (David Benbennick and DLR) former's not being defined. (David Benbennick and DLR)
- Miscellaneous tweaks to update_color() calls, to make sure
they're called at the right times and that refreshes are done
afterwards only when needed. (David Benbennick)
- Renamed [have_]past_editbuff [have_]search_offscreen. (DLR)
- Add the "preserve" option to the nanorc file, to match
nanorc.sample. (DLR)
- configure.ac: - configure.ac:
- Added tr to ALL_LINGUAS (Jordi). - Added tr to ALL_LINGUAS (Jordi).
- Fix now inaccurate description of --enable-tiny's effects; it - Fix now inaccurate description of --enable-tiny's effects; it
@ -45,6 +57,10 @@ Changes
- Fix typo. (David Benbennick) - Fix typo. (David Benbennick)
- Check for strcasecmp() and strncasecmp(), since they are - Check for strcasecmp() and strncasecmp(), since they are
apparently only standard under BSD. (DLR) apparently only standard under BSD. (DLR)
- color.c:
update_color():
- Remove an unneeded edit_refresh() call after do_colorinit().
(David Benbennick)
- cut.c: - cut.c:
do_cut_text() do_cut_text()
- Fix a memory corruption problem caused by accessing edittop - Fix a memory corruption problem caused by accessing edittop
@ -54,32 +70,56 @@ Changes
- If uncutting more than one line of unmarked text at editbot, - If uncutting more than one line of unmarked text at editbot,
don't center the screen, since Pico doesn't. (DLR) don't center the screen, since Pico doesn't. (DLR)
- files.c: - files.c:
load_file()
- Remove unneeded wmove() call. (David Benbennick)
read_line() read_line()
- Miscellaneous cleanups. (David Benbennick) - Miscellaneous cleanups. (David Benbennick)
open_file()
- If we're in multibuffer mode and there's an error opening the
file in read-only mode, display the error message on the
statusbar regardless of the value of quiet. (DLR)
read_file() read_file()
- Miscellaneous cleanups. (David Benbennick) - Miscellaneous cleanups. (David Benbennick)
- Fix len's being off by one when reading in Mac-format files, - Fix len's being off by one when reading in Mac-format files,
exposed by one of David Benbennick's cleanups. (DLR) exposed by one of David Benbennick's cleanups. (DLR)
- If NO_CONVERT isn't set when we first enter, and it gets set - If NO_CONVERT isn't set when we first enter, and it gets set
while reading in the file, unset it again afterwards. (DLR) while reading in the file, unset it again afterwards. (DLR)
do_insertfile()
- If we're in multibuffer mode and there's an error opening the
file that we're trying to insert, close the new buffer that we
made to hold it and reload the buffer we had open before.
(DLR)
add_open_file() add_open_file()
- Fix minor logic error when determining when to resave fileage - Fix minor logic error when determining when to resave fileage
and filebot. (DLR) and filebot. (DLR)
load_open_file()
- If switching between files when CONSTUPDATE is set, only force
a cursor position display update if DISABLE_CURPOS isn't set.
This will ensure that the "Switching to [file]" messages are
shown. (DLR)
write_file() write_file()
- Change lineswritten from a long to an int, to match - Change lineswritten from a long to an int, to match
filestruct->lineno. (DLR; mismatch found by David Benbennick) filestruct->lineno. (DLR; mismatch found by David Benbennick)
real_dir_from_tilde()
- Since this is needed for proper interpretation of paths
containing tildes and not just for tab completion, include and
use it regardless of whether tab completion is disabled.
(David Benbennick and DLR)
input_tab() input_tab()
- Variable name change: matchBuf -> matchbuf. (DLR) - Variable name change: matchBuf -> matchbuf. (DLR)
diralphasort() diralphasort()
- Remove the HAVE_STRCASECMP #ifdef block; see the changes to - Remove the HAVE_STRCASECMP #ifdef block; see the changes to
configure.ac and nano.h for why. (DLR) configure.ac and nano.h for why. (DLR)
- global.c:
thanks_for_all_the_fish()
- Miscellaneous cleanups. (David Benbennick)
- move.c: - move.c:
do_page_down() do_page_down()
- If there's a page or less of text, do an edit_update() if the - If there's a page or less of text, do an edit_update() if the
mark is on; otherwise, the highlight won't be displayed. (DLR) mark is on; otherwise, the highlight won't be displayed. (DLR)
- nano.c: - nano.c:
- Added free_history list calls clean up, added init of list headers - Added free_history() list calls clean up, added init of list
modified statusq calls (Ken Tyler). headers, and modified statusq() calls (Ken Tyler).
do_prev_word() do_prev_word()
- Make the assert match that in do_next_word(). (DLR) - Make the assert match that in do_next_word(). (DLR)
do_enter() do_enter()
@ -108,12 +148,44 @@ Changes
more useful feedback to the user when spell checking fails. more useful feedback to the user when spell checking fails.
ABCD() ABCD()
- Renamed abcd(). (DLR) - Renamed abcd(). (DLR)
main()
- Remove an unneeded do_colorinit() call, do major cleanups, and
allow loading of multiple files on the command line when
multibuffers are used. (David Benbennick)
- nano.h: - nano.h:
- Make sure NO_RCFILE and COLOR_SYNTAX aren't set to the same - Make sure NO_RCFILE and COLOR_SYNTAX aren't set to the same
value. (DLR; discovered by Ken Tyler) value. (DLR; discovered by Ken Tyler)
- If strcasecmp() and/or strncasecmp() aren't available, use - If strcasecmp() and/or strncasecmp() aren't available, use
strcmp() and/or strncmp instead. (DLR) strcmp() and/or strncmp() instead. (DLR)
- proto.h:
- Fix the #ifdef block for DISABLE_TABCOMP's being undefined
so that functions only used with tab completion are properly
#ifdef'ed out. (DLR)
- search.c:
print_replaced()
- Remove and replace with an equivalent ngettext() call. (DLR)
do_replace_loop()
- Fix bug where if text on the magicline was replaced (which can
be done via a regexp replace of "^$" with something other than
""), a new magicline wouldn't be created. (DLR)
do_replace()
- For greater Pico compatibility, when an attempt to replace a
string results in 0 replacements due to the string's not being
found, display "[string] not found" instead of "Replaced 0
occurrences". (DLR)
- utils.c: - utils.c:
align()
- Don't just assert that the string passed in isn't NULL; check
that it isn't and only do the alignment when it isn't. (David
Benbennick)
nmalloc(), nrealloc()
- If the size passed to nmalloc() or nrealloc() is zero, don't
die with an erroneous out-of-memory error. Also, change
their dying messages to "nano is out of memory!". (David
Benbennick)
charalloc()
- Removed and redefined as a macro that calls nmalloc(). (David
Benbennick)
is_cntrl_char() is_cntrl_char()
- Rework to fix a problem with displaying certain high-bit - Rework to fix a problem with displaying certain high-bit
characters. (David Benbennick; reported by Andrzej Marecki) characters. (David Benbennick; reported by Andrzej Marecki)
@ -133,8 +205,9 @@ Changes
- Added double hash marks to comment lines, so people who - Added double hash marks to comment lines, so people who
uncomment the beginning of every line won't get syntax errors. uncomment the beginning of every line won't get syntax errors.
- faq.html: - faq.html:
- Miscellaneous fixes and updates for typos and broken links. - Miscellaneous fixes and updates for typos, broken links, and
It is now fully compliant with HTML 4.01 Transitional. (DLR) slashes at the end of directories. It is now fully compliant
with HTML 4.01 Transitional. (DLR and David Benbennick)
- nano.texi: - nano.texi:
- Typo fixes and updates. (David Benbennick) - Typo fixes and updates. (David Benbennick)
- TODO - TODO

4
TODO
View File

@ -6,7 +6,7 @@ For version 1.2:
- Color syntax highlighting? (certainly seems like there's a demand for it.) - Color syntax highlighting? (certainly seems like there's a demand for it.)
- .nanorc [DONE] - .nanorc [DONE]
- Backup making (filename~)? [DONE] - Backup making (filename~)? [DONE]
- Search (etc) string history [1.2] - Search (etc.) string history [DONE]
- Implement Pico's -j and -g flags, as they are pretty easy to do. [DONE] - Implement Pico's -j and -g flags, as they are pretty easy to do. [DONE]
- Make mouse support work with clicking on the shortcuts (-m). Must - Make mouse support work with clicking on the shortcuts (-m). Must
make global variable pointing to current shortcut list to determine what make global variable pointing to current shortcut list to determine what
@ -20,7 +20,7 @@ For version 1.4:
- Support for Pico's paragraph searching ability. - Support for Pico's paragraph searching ability.
- Undo/Redo key? - Undo/Redo key?
- Remindable keys? - Remindable keys?
- Keystroke to implement "Add next sequence as raw" like vi's ^V - Keystroke to implement "Add next sequence as raw" like vi's ^V?
Old requests: Old requests:

View File

@ -84,20 +84,21 @@ void do_colorinit(void)
if (background == -1) if (background == -1)
#ifdef HAVE_USE_DEFAULT_COLORS #ifdef HAVE_USE_DEFAULT_COLORS
if (defok == 0) if (!defok)
#endif #endif
background = COLOR_BLACK; background = COLOR_BLACK;
init_pair(tmpcolor->pairnum, tmpcolor->fg, background); init_pair(tmpcolor->pairnum, tmpcolor->fg, background);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, _("Running init_pair with fg = %d and bg = %d\n"), tmpcolor->fg, tmpcolor->bg); fprintf(stderr, _("Running init_pair() with fg = %d and bg = %d\n"),
tmpcolor->fg, tmpcolor->bg);
#endif #endif
} }
} }
} }
/* Update the color information based on the current filename */ /* Update the color information based on the current filename. */
void update_color(void) void update_color(void)
{ {
const syntaxtype *tmpsyntax; const syntaxtype *tmpsyntax;
@ -130,7 +131,6 @@ void update_color(void)
} }
} }
do_colorinit(); do_colorinit();
edit_refresh();
} }
#endif /* ENABLE_COLOR */ #endif /* ENABLE_COLOR */

View File

@ -31,7 +31,7 @@
<a href="#3.7">3.7. Tell me more about this multibuffer stuff!</a><br> <a href="#3.7">3.7. Tell me more about this multibuffer stuff!</a><br>
<a href="#3.8">3.8. How do I make a .nanorc file that nano will read when I start it?</a></p></blockquote> <a href="#3.8">3.8. How do I make a .nanorc file that nano will read when I start it?</a></p></blockquote>
<h2><a href="#4">4. Running</a></h2> <h2><a href="#4">4. Running</a></h2>
<blockquote><p><a href="#4.1">4.1. Ack!&nbsp; My backspace/delete/enter/double bucky/meta key doesn't seem to work!&nbsp; What can I do?</a><br> <blockquote><p><a href="#4.1">4.1. Ack! My backspace/delete/enter/double bucky/meta key doesn't seem to work! What can I do?</a><br>
<a href="#4.2">4.2. Nano crashes when I type &lt;insert keystroke here&gt;!</a><br> <a href="#4.2">4.2. Nano crashes when I type &lt;insert keystroke here&gt;!</a><br>
<a href="#4.3">4.3. Nano crashes when I resize my window. How can I fix that?</a><br> <a href="#4.3">4.3. Nano crashes when I resize my window. How can I fix that?</a><br>
<a href="#4.4">4.4. Why does nano show ^\ in the shortcut list instead of ^J?</a><br> <a href="#4.4">4.4. Why does nano show ^\ in the shortcut list instead of ^J?</a><br>
@ -62,13 +62,13 @@
<h2><a name="1.2"></a>1.2. How do I contribute to it?</h2> <h2><a name="1.2"></a>1.2. How do I contribute to it?</h2>
<blockquote><p>Your best bet is to send it to the nano email address, <a href="mailto:nano@nano-editor.org">nano@nano-editor.org</a> and if it is useful enough it will be included in future versions.</p></blockquote> <blockquote><p>Your best bet is to send it to the nano email address, <a href="mailto:nano@nano-editor.org">nano@nano-editor.org</a> and if it is useful enough it will be included in future versions.</p></blockquote>
<h2><a name="1.3"></a>1.3. What is GNU nano?</h2> <h2><a name="1.3"></a>1.3. What is GNU nano?</h2>
<blockquote><p>GNU nano is designed to be a free replacement for the Pico text editor, part of the Pine email suite from <a href="http://www.washington.edu/pine">The University of Washington</a>. It aims to &quot;emulate Pico as closely as possible and perhaps include extra functionality&quot;.</p></blockquote> <blockquote><p>GNU nano is designed to be a free replacement for the Pico text editor, part of the Pine email suite from <a href="http://www.washington.edu/pine/">The University of Washington</a>. It aims to &quot;emulate Pico as closely as possible and perhaps include extra functionality&quot;.</p></blockquote>
<h2><a name="1.4"></a>1.4. What is the history behind nano?</h2> <h2><a name="1.4"></a>1.4. What is the history behind nano?</h2>
<blockquote><p>Funny you should ask!</p> <blockquote><p>Funny you should ask!</p>
<p><b>In the beginning...</b></p> <p><b>In the beginning...</b></p>
<p>For years Pine was THE program used to read email on a Unix system. The Pico text editor is the portion of the program one would use to compose his or her mail messages. Many beginners to Unix flocked to Pico and Pine because of their well organized, easy to use interfaces. With the proliferation of GNU/Linux in the mid to late 90's, many University students became intimately familiar with the strengths (and weaknesses) of Pine and Pico.</p> <p>For years Pine was THE program used to read email on a Unix system. The Pico text editor is the portion of the program one would use to compose his or her mail messages. Many beginners to Unix flocked to Pico and Pine because of their well organized, easy to use interfaces. With the proliferation of GNU/Linux in the mid to late 90's, many University students became intimately familiar with the strengths (and weaknesses) of Pine and Pico.</p>
<p><b>Then came Debian...</b></p> <p><b>Then came Debian...</b></p>
<p>The <a href="http://www.debian.org">Debian GNU/Linux</a> distribution, known for its strict standards in distributing truly &quot;free&quot; software (i.e. software with no restrictions on redistribution), would not include a binary package for Pine or Pico. Many people had a serious dilemma: they loved these programs, but they were not truly free software in the <a href="http://www.gnu.org/philosophy/free-sw.html">GNU</a> sense of the word.</p> <p>The <a href="http://www.debian.org/">Debian GNU/Linux</a> distribution, known for its strict standards in distributing truly &quot;free&quot; software (i.e. software with no restrictions on redistribution), would not include a binary package for Pine or Pico. Many people had a serious dilemma: they loved these programs, but they were not truly free software in the <a href="http://www.gnu.org/philosophy/free-sw.html">GNU</a> sense of the word.</p>
<p><b>The event...</b></p> <p><b>The event...</b></p>
<p>It was in late 1999 when Chris Allegretta (our hero) was yet again complaining to himself about the less-than-perfect license Pico was distributed under, the 1000 makefiles that came with it and how just a few small improvements could make it the Best Editor in the World (TM). Having been a convert from Slackware to Debian, he missed having a simple binary package that included Pine and Pico, and had grown tired of downloading them himself.</p> <p>It was in late 1999 when Chris Allegretta (our hero) was yet again complaining to himself about the less-than-perfect license Pico was distributed under, the 1000 makefiles that came with it and how just a few small improvements could make it the Best Editor in the World (TM). Having been a convert from Slackware to Debian, he missed having a simple binary package that included Pine and Pico, and had grown tired of downloading them himself.</p>
<p>Finally something snapped inside and Chris coded and hacked like a madman for many hours straight one weekend to make a (barely usable) Pico clone, at the time called TIP (Tip Isn't Pico). The program could not be invoked without a filename, could not save files, had no help menu, spell checker, and so forth. But over time it improved, and with the help of a few great coders it matured to the (hopefully) stable state it is today.</p> <p>Finally something snapped inside and Chris coded and hacked like a madman for many hours straight one weekend to make a (barely usable) Pico clone, at the time called TIP (Tip Isn't Pico). The program could not be invoked without a filename, could not save files, had no help menu, spell checker, and so forth. But over time it improved, and with the help of a few great coders it matured to the (hopefully) stable state it is today.</p>
@ -84,31 +84,31 @@
<h2><a name="2.1"></a>2.1. FTP and WWW sites that carry nano.</h2> <h2><a name="2.1"></a>2.1. FTP and WWW sites that carry nano.</h2>
<blockquote><p>The nano distribution can be downloaded at the following fine web and ftp sites:</p> <blockquote><p>The nano distribution can be downloaded at the following fine web and ftp sites:</p>
<ul> <ul>
<li><a href="http://www.nano-editor.org/dist">http://www.nano-editor.org/dist</a></li> <li><a href="http://www.nano-editor.org/dist/">http://www.nano-editor.org/dist/</a></li>
<li><a href="http://www.ewtoo.org/~astyanax/nano/dist">http://www.ewtoo.org/~astyanax/nano/dist</a></li> <li><a href="http://www.ewtoo.org/~astyanax/nano/dist/">http://www.ewtoo.org/~astyanax/nano/dist/</a></li>
<li><a href="ftp://ftp.gnu.org/pub/gnu/nano">ftp://ftp.gnu.org/pub/gnu/nano</a></li> <li><a href="ftp://ftp.gnu.org/pub/gnu/nano/">ftp://ftp.gnu.org/pub/gnu/nano/</a></li>
</ul> </ul>
</blockquote> </blockquote>
<h2><a name="2.2"></a>2.2. RedHat and derivatives (.rpm) packages.</h2> <h2><a name="2.2"></a>2.2. RedHat and derivatives (.rpm) packages.</h2>
<blockquote> <blockquote>
<ul> <ul>
<li><a href="http://www.nano-editor.org/dist/v1.0/RPMS">http://www.nano-editor.org/dist/v1.0/RPMS</a></li> <li><a href="http://www.nano-editor.org/dist/v1.0/RPMS/">http://www.nano-editor.org/dist/v1.0/RPMS/</a></li>
<li><a href="http://www.ewtoo.org/~astyanax/nano/dist/v1.0/RPMS">http://www.ewtoo.org/~astyanax/nano/dist/v1.0/RPMS</a></li> <li><a href="http://www.ewtoo.org/~astyanax/nano/dist/v1.0/RPMS/">http://www.ewtoo.org/~astyanax/nano/dist/v1.0/RPMS/</a></li>
</ul> </ul>
<p>Additionally, check out the RedHat contribs section at:</p> <p>Additionally, check out the RedHat contribs section at:</p>
<ul> <ul>
<li><a href="http://distro.ibiblio.org/pub/Linux/distributions/redhat/contrib/libc6/i386">http://distro.ibiblio.org/pub/Linux/distributions/redhat/contrib/libc6/i386</a></li> <li><a href="http://distro.ibiblio.org/pub/Linux/distributions/redhat/contrib/libc6/i386/">http://distro.ibiblio.org/pub/Linux/distributions/redhat/contrib/libc6/i386/</a></li>
<li><a href="ftp://distro.ibiblio.org/pub/Linux/distributions/redhat/contrib/libc6/i386">ftp://distro.ibiblio.org/pub/Linux/distributions/redhat/contrib/libc6/i386</a></li> <li><a href="ftp://distro.ibiblio.org/pub/Linux/distributions/redhat/contrib/libc6/i386/">ftp://distro.ibiblio.org/pub/Linux/distributions/redhat/contrib/libc6/i386/</a></li>
</ul> </ul>
</blockquote> </blockquote>
<h2><a name="2.3"></a>2.3. Debian (.deb) packages.</h2> <h2><a name="2.3"></a>2.3. Debian (.deb) packages.</h2>
<blockquote><p>Debian users can check out the current nano packages for:</p> <blockquote><p>Debian users can check out the current nano packages for:</p>
<ul> <ul>
<li><a href="http://www.debian.org/Packages/stable/editors/nano.html">stable</a></li> <li><a href="http://packages.debian.org/stable/editors/nano.html">stable</a></li>
<li><a href="http://www.debian.org/Packages/testing/editors/nano.html">testing</a></li> <li><a href="http://packages.debian.org/testing/editors/nano.html">testing</a></li>
<li><a href="http://www.debian.org/Packages/unstable/editors/nano.html">unstable</a></li> <li><a href="http://packages.debian.org/unstable/editors/nano.html">unstable</a></li>
</ul> </ul>
<p>You can also have a look at the <a href="ftp://ftp.debian.org/debian/pool/main/n/nano">Package Pool</a> to see all the available binary and source packages.</p> <p>You can also have a look at the <a href="ftp://ftp.debian.org/debian/pool/main/n/nano/">Package Pool</a> to see all the available binary and source packages.</p>
<p>Note that versions &lt; 0.9.10 are probably not for those wanting to get serious work done, so if you are using Debian 2.2, check that you have updated to 2.2r3, which comes with nano 0.9.23. If you're tracking unstable, you probably have the newest version already.</p></blockquote> <p>Note that versions &lt; 0.9.10 are probably not for those wanting to get serious work done, so if you are using Debian 2.2, check that you have updated to 2.2r3, which comes with nano 0.9.23. If you're tracking unstable, you probably have the newest version already.</p></blockquote>
<h2><a name="2.4"></a>2.4. By CVS (for the brave).</h2> <h2><a name="2.4"></a>2.4. By CVS (for the brave).</h2>
<blockquote><p>For the 'bleeding edge' current version of nano, you can use CVS to download the current source code. <b>Note:</b> believe it or not, by downloading code that has not yet stabilized into an official release, there could quite possibly be bugs, in fact the code may not even compile! Anyway, see <a href="http://savannah.gnu.org/cvs/?group_id=1025">the nano CVS page</a> for info on anonymous CVS access to the nano source.</p></blockquote> <blockquote><p>For the 'bleeding edge' current version of nano, you can use CVS to download the current source code. <b>Note:</b> believe it or not, by downloading code that has not yet stabilized into an official release, there could quite possibly be bugs, in fact the code may not even compile! Anyway, see <a href="http://savannah.gnu.org/cvs/?group_id=1025">the nano CVS page</a> for info on anonymous CVS access to the nano source.</p></blockquote>
@ -191,7 +191,7 @@
<hr width="100%"> <hr width="100%">
<h1><a name="5"></a>5. Internationalization</h1> <h1><a name="5"></a>5. Internationalization</h1>
<h2><a name="5.1"></a>5.1. There's no translation for my language!</h2> <h2><a name="5.1"></a>5.1. There's no translation for my language!</h2>
<blockquote><p>On June of 2001, GNU nano entered the <a href="http://www.iro.umontreal.ca/contrib/po/HTML">Free Translation Project</a> and since then, translations should be managed from there.</p> <blockquote><p>On June of 2001, GNU nano entered the <a href="http://www.iro.umontreal.ca/contrib/po/HTML/">Free Translation Project</a> and since then, translations should be managed from there.</p>
<p>If there isn't a translation for your language, you could ask <a href="http://www.iro.umontreal.ca/contrib/po/HTML/teams.html">your language team</a> to translate nano, or better still, join your team and do it yourself. Joining a team is easy. You just need to ask the <a href="mailto:translation@iro.umontreal.ca">TP coordinator</a> to add you to your team, and send a <a href="http://www.iro.umontreal.ca/contrib/po/HTML/disclaim.html">translation disclaimer to the FSF</a> (this is necessary as nano is an official GNU package, but it does <b>not</b> mean that you transfer the rights of your work to the FSF, it's just so the FSF can legally manage them).</p> <p>If there isn't a translation for your language, you could ask <a href="http://www.iro.umontreal.ca/contrib/po/HTML/teams.html">your language team</a> to translate nano, or better still, join your team and do it yourself. Joining a team is easy. You just need to ask the <a href="mailto:translation@iro.umontreal.ca">TP coordinator</a> to add you to your team, and send a <a href="http://www.iro.umontreal.ca/contrib/po/HTML/disclaim.html">translation disclaimer to the FSF</a> (this is necessary as nano is an official GNU package, but it does <b>not</b> mean that you transfer the rights of your work to the FSF, it's just so the FSF can legally manage them).</p>
<p>In any case, translating nano is very easy. Just grab the <b>nano.pot</b> file from the latest and greatest nano distribution (it's in the <b>po/</b> directory) and translate each line into your native language on the <b>msgstr</b> line. When you're done, you should send it to the TP's central po repository.</p></blockquote> <p>In any case, translating nano is very easy. Just grab the <b>nano.pot</b> file from the latest and greatest nano distribution (it's in the <b>po/</b> directory) and translate each line into your native language on the <b>msgstr</b> line. When you're done, you should send it to the TP's central po repository.</p></blockquote>
<h2><a name="5.2"></a>5.2. I don't like the translation for &lt;x&gt; in my language. How can I fix it?</h2> <h2><a name="5.2"></a>5.2. I don't like the translation for &lt;x&gt; in my language. How can I fix it?</h2>
@ -199,13 +199,13 @@
<hr width="100%"> <hr width="100%">
<h1><a name="6"></a>6. Advocacy and Licensing</h1> <h1><a name="6"></a>6. Advocacy and Licensing</h1>
<h2><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h2> <h2><a name="6.1"></a>6.1. Why should I use nano instead of Pico?</h2>
<blockquote><p>There are many reasons to use nano instead of Pico, a more complete list can be found at the <a href="http://www.nano-editor.org">nano homepage</a>.</p></blockquote> <blockquote><p>There are many reasons to use nano instead of Pico, a more complete list can be found at the <a href="http://www.nano-editor.org/">nano homepage</a>.</p></blockquote>
<h2><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h2> <h2><a name="6.2"></a>6.2. Why should I use Pico instead of nano?</h2>
<blockquote><p>Again, check out the <a href="http://www.nano-editor.org">nano homepage</a> for a good summary of reasons. It really is a matter of personal preference as to which editor you should use. If you're the type of person who likes using the original version of a program, then Pico is the editor for you. If you're looking for a few more features and a 'better' license as far as adding your own changes (sacrificing mailer integration with Pine), nano is the way to go.</p></blockquote> <blockquote><p>Again, check out the <a href="http://www.nano-editor.org/">nano homepage</a> for a good summary of reasons. It really is a matter of personal preference as to which editor you should use. If you're the type of person who likes using the original version of a program, then Pico is the editor for you. If you're looking for a few more features and a 'better' license as far as adding your own changes (sacrificing mailer integration with Pine), nano is the way to go.</p></blockquote>
<h2><a name="6.3"></a>6.3. What is so bad about the Pine license?</h2> <h2><a name="6.3"></a>6.3. What is so bad about the Pine license?</h2>
<blockquote><p>The U of W license for Pine and Pico is not considered truly Free Software according to both the Free Software Foundation and the <a href="http://www.debian.org/social_contract#guidelines">Debian Free Software Guidelines</a>. The main problem regards the limitations on distributing derived works: according to UW, you can distribute their software, and you can modify it, but you can not do both, i.e. distribute modified binaries.</p></blockquote> <blockquote><p>The U of W license for Pine and Pico is not considered truly Free Software according to both the Free Software Foundation and the <a href="http://www.debian.org/social_contract#guidelines">Debian Free Software Guidelines</a>. The main problem regards the limitations on distributing derived works: according to UW, you can distribute their software, and you can modify it, but you can not do both, i.e. distribute modified binaries.</p></blockquote>
<h2><a name="6.4"></a>6.4. Okay, well what mail program should I use then?</h2> <h2><a name="6.4"></a>6.4. Okay, well what mail program should I use then?</h2>
<blockquote><p>If you are looking to use a Free Software program similar to Pine and emacs is not your thing, you should definitely take a look at <a href="http://www.mutt.org">mutt</a>. It is a full-screen, console based mail program that actually has a lot more flexibility than Pine, but has a keymap included in the distribution that allows you to use the same keystrokes as Pine would to send and receive mail. It's also licensed under the GPL.</p></blockquote> <blockquote><p>If you are looking to use a Free Software program similar to Pine and emacs is not your thing, you should definitely take a look at <a href="http://www.mutt.org/">mutt</a>. It is a full-screen, console based mail program that actually has a lot more flexibility than Pine, but has a keymap included in the distribution that allows you to use the same keystrokes as Pine would to send and receive mail. It's also licensed under the GPL.</p></blockquote>
<h2><a name="6.5"></a>6.5. Why doesn't UW simply change their license?</h2> <h2><a name="6.5"></a>6.5. Why doesn't UW simply change their license?</h2>
<blockquote><p>You're really not asking the right person here. I (Chris) waited a long time to see if UW would change their license because of the amount of high quality software being released and developed under the GPL without being taken advantage of by malicious corporate entities or other baddies, but no such luck so far.</p></blockquote> <blockquote><p>You're really not asking the right person here. I (Chris) waited a long time to see if UW would change their license because of the amount of high quality software being released and developed under the GPL without being taken advantage of by malicious corporate entities or other baddies, but no such luck so far.</p></blockquote>
<h2><a name="6.6"></a>6.6. What if tomorrow UW changes the license to be truly Free Software?</h2> <h2><a name="6.6"></a>6.6. What if tomorrow UW changes the license to be truly Free Software?</h2>
@ -213,10 +213,10 @@
<hr width="100%"> <hr width="100%">
<h1><a name="7"></a>7. Miscellaneous</h1> <h1><a name="7"></a>7. Miscellaneous</h1>
<h2><a name="7.1"></a>7.1. Nano related mailing lists.</h2> <h2><a name="7.1"></a>7.1. Nano related mailing lists.</h2>
<blockquote><p>There are three mailing lists for nano hosted at <a href="http://savannah.gnu.org">Savannah</a>, info-nano, help-nano and nano-devel. Info-nano is a very low traffic list where new versions of nano are announced (surprise!) Help-nano is for getting help with the editor without needing to hear all of the development issues surrounding it. Nano-devel is a normally low, sometimes high traffic list for discussing the present and future development of nano. Here are links to where you can sign up for a given list:</p> <blockquote><p>There are three mailing lists for nano hosted at <a href="http://savannah.gnu.org/">Savannah</a>, info-nano, help-nano and nano-devel. Info-nano is a very low traffic list where new versions of nano are announced (surprise!) Help-nano is for getting help with the editor without needing to hear all of the development issues surrounding it. Nano-devel is a normally low, sometimes high traffic list for discussing the present and future development of nano. Here are links to where you can sign up for a given list:</p>
<p>info-nano - <a href="http://mail.gnu.org/mailman/listinfo/info-nano">http://mail.gnu.org/mailman/listinfo/info-nano</a><br> <p>info-nano - <a href="http://mail.gnu.org/mailman/listinfo/info-nano/">http://mail.gnu.org/mailman/listinfo/info-nano/</a><br>
help-nano - <a href="http://mail.gnu.org/mailman/listinfo/help-nano">http://mail.gnu.org/mailman/listinfo/help-nano</a><br> help-nano - <a href="http://mail.gnu.org/mailman/listinfo/help-nano/">http://mail.gnu.org/mailman/listinfo/help-nano/</a><br>
nano-devel - <a href="http://mail.gnu.org/mailman/listinfo/nano-devel">http://mail.gnu.org/mailman/listinfo/nano-devel</a></p></blockquote> nano-devel - <a href="http://mail.gnu.org/mailman/listinfo/nano-devel/">http://mail.gnu.org/mailman/listinfo/nano-devel/</a></p></blockquote>
<h2><a name="7.2"></a>7.2. I want to send the development team a big load of cash (or just a thank you).</h2> <h2><a name="7.2"></a>7.2. I want to send the development team a big load of cash (or just a thank you).</h2>
<blockquote><p>That's fine. Send it <a href="mailto:nano-devel@gnu.org">our way</a>! Better yet, fix a <a href="http://www.nano-editor.org/dist/v1.1/BUGS">bug</a> in the program or implement a <a href="http://www.nano-editor.org/dist/v1.1/TODO">cool feature</a> and send us that instead (though cash is fine too).</p></blockquote> <blockquote><p>That's fine. Send it <a href="mailto:nano-devel@gnu.org">our way</a>! Better yet, fix a <a href="http://www.nano-editor.org/dist/v1.1/BUGS">bug</a> in the program or implement a <a href="http://www.nano-editor.org/dist/v1.1/TODO">cool feature</a> and send us that instead (though cash is fine too).</p></blockquote>
<h2><a name="7.3"></a>7.3. How do I submit a patch?</h2> <h2><a name="7.3"></a>7.3. How do I submit a patch?</h2>
@ -226,7 +226,8 @@
<h2><a name="7.5"></a>7.5. Can I have CVS write access?</h2> <h2><a name="7.5"></a>7.5. Can I have CVS write access?</h2>
<blockquote><p>Re-read Section <a href="#7.4">7.4</a> and you should know the answer.</p></blockquote> <blockquote><p>Re-read Section <a href="#7.4">7.4</a> and you should know the answer.</p></blockquote>
<h2><a name="8"></a>8. ChangeLog</h2> <h2><a name="8"></a>8. ChangeLog</h2>
<blockquote><p>2002/10/25 - Misc. fixes and link updates (DLR).<br> <blockquote><p>2002/12/28 - More misc. fixes (David Benbennick, DLR).<br>
2002/10/25 - Misc. fixes and link updates (DLR).<br>
2002/09/10 - Another typo fix (DLR).<br> 2002/09/10 - Another typo fix (DLR).<br>
2002/05/15 - Typo fix (DLR).<br> 2002/05/15 - Typo fix (DLR).<br>
2001/12/26 - Misc. fixes (Aaron S. Hawley, DLR).<br> 2001/12/26 - Misc. fixes (Aaron S. Hawley, DLR).<br>

144
files.c
View File

@ -33,8 +33,8 @@
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#include <dirent.h> #include <dirent.h>
#include <assert.h>
#include <pwd.h> #include <pwd.h>
#include <assert.h>
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
@ -42,7 +42,7 @@
static int fileformat = 0; /* 0 = *nix, 1 = DOS, 2 = Mac */ static int fileformat = 0; /* 0 = *nix, 1 = DOS, 2 = Mac */
#endif #endif
/* Load file into edit buffer - takes data from file struct */ /* Load file into edit buffer - takes data from file struct. */
void load_file(int update) void load_file(int update)
{ {
current = fileage; current = fileage;
@ -56,9 +56,8 @@ void load_file(int update)
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
update_color(); update_color();
edit_refresh();
#endif #endif
wmove(edit, current_y, current_x);
} }
/* What happens when there is no file to open? aiee! */ /* What happens when there is no file to open? aiee! */
@ -95,6 +94,7 @@ void new_file(void)
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
update_color(); update_color();
edit_refresh();
#endif #endif
} }
@ -171,10 +171,10 @@ int read_file(FILE *f, const char *filename, int quiet)
} }
/* For the assertion in read_line(), it must be true that if current is /* For the assertion in read_line(), it must be true that if current is
NULL then so is fileage. */ * NULL then so is fileage. */
assert(current != NULL || fileage == NULL); assert(current != NULL || fileage == NULL);
/* Read the entire file into file struct */ /* Read the entire file into file struct. */
while ((input_int = getc(f)) != EOF) { while ((input_int = getc(f)) != EOF) {
input = (char)input_int; input = (char)input_int;
#ifndef NANO_SMALL #ifndef NANO_SMALL
@ -323,7 +323,7 @@ int read_file(FILE *f, const char *filename, int quiet)
return 1; return 1;
} }
/* Open the file (and decide if it exists) */ /* Open the file (and decide if it exists). */
int open_file(const char *filename, int insert, int quiet) int open_file(const char *filename, int insert, int quiet)
{ {
int fd; int fd;
@ -340,7 +340,13 @@ int open_file(const char *filename, int insert, int quiet)
new_file(); new_file();
} }
} else if ((fd = open(filename, O_RDONLY)) == -1) { } else if ((fd = open(filename, O_RDONLY)) == -1) {
if (!quiet) /* If we're in multibuffer mode, don't be quiet when an error
occurs while opening a file */
if (!quiet
#ifdef ENABLE_MULTIBUFFER
|| ISSET(MULTIBUFFER)
#endif
)
statusbar("%s: %s", strerror(errno), filename); statusbar("%s: %s", strerror(errno), filename);
if (!insert) if (!insert)
new_file(); new_file();
@ -375,9 +381,9 @@ int open_file(const char *filename, int insert, int quiet)
} }
/* This function will return the name of the first available extension /* This function will return the name of the first available extension
of a filename (starting with the filename, then filename.1, etc). * of a filename (starting with the filename, then filename.1, etc).
Memory is allocated for the return value. If no writable extension * Memory is allocated for the return value. If no writable extension
exists, we return "". */ * exists, we return "". */
char *get_next_filename(const char *name) char *get_next_filename(const char *name)
{ {
int i = 0; int i = 0;
@ -426,21 +432,37 @@ int do_insertfile(int loading_file)
if (operating_dir != NULL && strcmp(operating_dir, ".") != 0) if (operating_dir != NULL && strcmp(operating_dir, ".") != 0)
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (ISSET(MULTIBUFFER)) if (ISSET(MULTIBUFFER))
i = statusq(1, insertfile_list, inspath, 0, _("File to insert into new buffer [from %s] "), i = statusq(1, insertfile_list, inspath,
#ifndef NANO_SMALL
0,
#endif
_("File to insert into new buffer [from %s] "),
operating_dir); operating_dir);
else else
#endif #endif
i = statusq(1, insertfile_list, inspath, 0, _("File to insert [from %s] "), i = statusq(1, insertfile_list, inspath,
#ifndef NANO_SMALL
0,
#endif
_("File to insert [from %s] "),
operating_dir); operating_dir);
else else
#endif #endif
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (ISSET(MULTIBUFFER)) if (ISSET(MULTIBUFFER))
i = statusq(1, insertfile_list, inspath, 0, _("File to insert into new buffer [from ./] ")); i = statusq(1, insertfile_list, inspath,
else #ifndef NANO_SMALL
0,
#endif #endif
i = statusq(1, insertfile_list, inspath, 0, _("File to insert [from ./] ")); _("File to insert into new buffer [from ./] "));
else
#endif /* ENABLE_MULTIBUFFER */
i = statusq(1, insertfile_list, inspath,
#ifndef NANO_SMALL
0,
#endif
_("File to insert [from ./] "));
if (i != -1) { if (i != -1) {
inspath = mallocstrcpy(inspath, answer); inspath = mallocstrcpy(inspath, answer);
@ -448,11 +470,7 @@ int do_insertfile(int loading_file)
fprintf(stderr, _("filename is %s\n"), answer); fprintf(stderr, _("filename is %s\n"), answer);
#endif #endif
#ifndef DISABLE_TABCOMP
realname = real_dir_from_tilde(answer); realname = real_dir_from_tilde(answer);
#else
realname = mallocstrcpy(realname, answer);
#endif
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
if (i == NANO_TOFILES_KEY) { if (i == NANO_TOFILES_KEY) {
@ -522,8 +540,20 @@ int do_insertfile(int loading_file)
i = open_file(realname, 1, loading_file); i = open_file(realname, 1, loading_file);
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (loading_file) if (loading_file) {
/* if there was an error opening the file, free() realname,
free() fileage (which now points to the new buffer we
created to hold the file), reload the buffer we had open
before, and skip the insertion; otherwise, save realname
in filename and continue the insertion */
if (i == -1) {
free(realname);
free(fileage);
load_open_file();
goto skip_insert;
} else
filename = mallocstrcpy(filename, realname); filename = mallocstrcpy(filename, realname);
}
#endif #endif
free(realname); free(realname);
@ -570,15 +600,15 @@ int do_insertfile(int loading_file)
else else
edit_refresh(); edit_refresh();
#ifdef ENABLE_COLOR
update_color();
#endif
} else { } else {
statusbar(_("Cancelled")); statusbar(_("Cancelled"));
i = 0; i = 0;
} }
#ifdef ENABLE_MULTIBUFFER
skip_insert:
#endif
free(inspath); free(inspath);
inspath = NULL; inspath = NULL;
@ -801,6 +831,10 @@ int load_open_file(void)
UNSET(MARK_ISSET); UNSET(MARK_ISSET);
#endif #endif
#ifdef ENABLE_COLOR
update_color();
#endif
/* restore full file position: line number, x-coordinate, y- /* restore full file position: line number, x-coordinate, y-
coordinate, place we want */ coordinate, place we want */
do_gotopos(open_files->file_lineno, open_files->file_current_x, open_files->file_current_y, open_files->file_placewewant); do_gotopos(open_files->file_lineno, open_files->file_current_x, open_files->file_current_y, open_files->file_placewewant);
@ -809,16 +843,13 @@ int load_open_file(void)
clearok(topwin, FALSE); clearok(topwin, FALSE);
titlebar(NULL); titlebar(NULL);
/* if we're constantly displaying the cursor position, update it (and do so /* if we're constantly displaying the cursor position and
unconditionally, in the rare case that the character count is the same DISABLE_CURPOS isn't set, update it (and do so unconditionally,
but the line count isn't) */ in the rare case that the character count is the same but the
if (ISSET(CONSTUPDATE)) line count isn't) */
if (ISSET(CONSTUPDATE) && !ISSET(DISABLE_CURPOS))
do_cursorpos(0); do_cursorpos(0);
#ifdef ENABLE_COLOR
update_color();
#endif
/* now we're done */ /* now we're done */
return 0; return 0;
} }
@ -1316,11 +1347,7 @@ int write_file(const char *name, int tmp, int append, int nonamechange)
titlebar(NULL); titlebar(NULL);
fileptr = fileage; fileptr = fileage;
#ifndef DISABLE_TABCOMP
realname = real_dir_from_tilde(name); realname = real_dir_from_tilde(name);
#else
realname = mallocstrcpy(realname, name);
#endif
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
/* If we're writing a temporary file, we're probably going outside /* If we're writing a temporary file, we're probably going outside
@ -1608,9 +1635,10 @@ int write_file(const char *name, int tmp, int append, int nonamechange)
umask(mask); umask(mask);
if (tmp) /* We don't want anyone reading our temporary file! */ if (tmp) /* We don't want anyone reading our temporary file! */
mask = 0600; mask = S_IRUSR | S_IWUSR;
else else
mask = 0666 & ~mask; mask = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |
S_IWOTH) & ~mask;
} else } else
/* Use permissions from file we are overwriting. */ /* Use permissions from file we are overwriting. */
mask = st.st_mode; mask = st.st_mode;
@ -1644,8 +1672,13 @@ int write_file(const char *name, int tmp, int append, int nonamechange)
mask, realname, strerror(errno)); mask, realname, strerror(errno));
if (!tmp && append == 0) { if (!tmp && append == 0) {
if (!nonamechange) if (!nonamechange) {
filename = mallocstrcpy(filename, realname); filename = mallocstrcpy(filename, realname);
#ifdef ENABLE_COLOR
update_color();
edit_refresh();
#endif
}
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* Update originalfilestat to reference the file as it is now. */ /* Update originalfilestat to reference the file as it is now. */
@ -1713,7 +1746,7 @@ int do_writeout(const char *path, int exiting, int append)
if (append == 2) if (append == 2)
i = statusq(1, writefile_list, "", 0, i = statusq(1, writefile_list, "", 0,
"%s%s%s", _("Prepend Selection to File"), formatstr, backupstr); "%s%s%s", _("Prepend Selection to File"), formatstr, backupstr);
else if (append) else if (append == 1)
i = statusq(1, writefile_list, "", 0, i = statusq(1, writefile_list, "", 0,
"%s%s%s", _("Append Selection to File"), formatstr, backupstr); "%s%s%s", _("Append Selection to File"), formatstr, backupstr);
else else
@ -1723,7 +1756,7 @@ int do_writeout(const char *path, int exiting, int append)
if (append == 2) if (append == 2)
i = statusq(1, writefile_list, answer, 0, i = statusq(1, writefile_list, answer, 0,
"%s%s%s", _("File Name to Prepend to"), formatstr, backupstr); "%s%s%s", _("File Name to Prepend to"), formatstr, backupstr);
else if (append) else if (append == 1)
i = statusq(1, writefile_list, answer, 0, i = statusq(1, writefile_list, answer, 0,
"%s%s%s", _("File Name to Append to"), formatstr, backupstr); "%s%s%s", _("File Name to Append to"), formatstr, backupstr);
else else
@ -1732,13 +1765,13 @@ int do_writeout(const char *path, int exiting, int append)
} }
#else #else
if (append == 2) if (append == 2)
i = statusq(1, writefile_list, answer, 0, i = statusq(1, writefile_list, answer,
"%s", _("File Name to Prepend to")); "%s", _("File Name to Prepend to"));
else if (append) else if (append == 1)
i = statusq(1, writefile_list, answer, 0, i = statusq(1, writefile_list, answer,
"%s", _("File Name to Append to")); "%s", _("File Name to Append to"));
else else
i = statusq(1, writefile_list, answer, 0, i = statusq(1, writefile_list, answer,
"%s", _("File Name to Write")); "%s", _("File Name to Write"));
#endif /* !NANO_SMALL */ #endif /* !NANO_SMALL */
@ -1852,8 +1885,6 @@ int do_writeout_void(void)
return do_writeout(filename, 0, 0); return do_writeout(filename, 0, 0);
} }
#ifndef DISABLE_TABCOMP
/* Return a malloc()ed string containing the actual directory, used /* Return a malloc()ed string containing the actual directory, used
* to convert ~user and ~/ notation... */ * to convert ~user and ~/ notation... */
char *real_dir_from_tilde(const char *buf) char *real_dir_from_tilde(const char *buf)
@ -1896,6 +1927,7 @@ char *real_dir_from_tilde(const char *buf)
return dirtmp; return dirtmp;
} }
#ifndef DISABLE_TABCOMP
/* Tack a slash onto the string we're completing if it's a directory. We /* Tack a slash onto the string we're completing if it's a directory. We
* assume there is room for one more character on the end of buf. The * assume there is room for one more character on the end of buf. The
* return value says whether buf is a directory. */ * return value says whether buf is a directory. */
@ -1920,8 +1952,8 @@ int append_slash_if_dir(char *buf, int *lastwastab, int *place)
} }
/* /*
* These functions (username_tab_completion, cwd_tab_completion, and * These functions (username_tab_completion(), cwd_tab_completion(), and
* input_tab) were taken from busybox 0.46 (cmdedit.c). Here is the * input_tab()) were taken from busybox 0.46 (cmdedit.c). Here is the
* notice from that file: * notice from that file:
* *
* Termios command line History and Editting, originally * Termios command line History and Editting, originally
@ -2093,9 +2125,8 @@ char **cwd_tab_completion(char *buf, int *num_matches)
return matches; return matches;
} }
/* This function now has an arg which refers to how much the /* This function now has an arg which refers to how much the statusbar
* statusbar (place) should be advanced, i.e. the new cursor pos. * (place) should be advanced, i.e. the new cursor pos. */
*/
char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list) char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
{ {
/* Do TAB completion */ /* Do TAB completion */
@ -2313,7 +2344,6 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
#endif /* !DISABLE_TABCOMP */ #endif /* !DISABLE_TABCOMP */
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
/* Return the stat of the file pointed to by path */ /* Return the stat of the file pointed to by path */
struct stat filestat(const char *path) struct stat filestat(const char *path)
{ {
@ -2650,7 +2680,11 @@ char *do_browser(const char *inpath)
case NANO_GOTO_KEY: case NANO_GOTO_KEY:
curs_set(1); curs_set(1);
j = statusq(0, gotodir_list, "", 0, _("Goto Directory")); j = statusq(0, gotodir_list, "",
#ifndef NANO_SMALL
0,
#endif
_("Goto Directory"));
bottombars(browser_list); bottombars(browser_list);
curs_set(0); curs_set(0);

View File

@ -27,16 +27,14 @@
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
/* /* Global variables */
* Global variables
*/
/* wrap_at might be set in rcfile.c or nano.c */ /* wrap_at might be set in rcfile.c or nano.c */
int wrap_at = -CHARS_FROM_EOL;/* Right justified fill value, allows resize */ int wrap_at = -CHARS_FROM_EOL;/* Right justified fill value, allows resize */
char *last_search = NULL; /* Last string we searched for */ char *last_search = NULL; /* Last string we searched for */
char *last_replace = NULL; /* Last replacement string */ char *last_replace = NULL; /* Last replacement string */
int search_last_line; /* Is this the last search line? */ int search_last_line; /* Is this the last search line? */
int past_editbuff; /* search lines not displayed */ int search_offscreen; /* Search lines not displayed */
int flags = 0; /* Our new flag containing many options */ int flags = 0; /* Our new flag containing many options */
WINDOW *edit; /* The file portion of the editor */ WINDOW *edit; /* The file portion of the editor */
@ -67,11 +65,8 @@ openfilestruct *open_files = NULL; /* The list of open files */
#endif #endif
#ifndef DISABLE_JUSTIFY #ifndef DISABLE_JUSTIFY
#ifdef HAVE_REGEX_H char *quotestr = NULL; /* Quote string. The default value is
char *quotestr = "^([ \t]*[|>:}#])+"; set in main(). */
#else
char *quotestr = "> "; /* Quote string */
#endif
#endif #endif
char *answer = NULL; /* Answer str to many questions */ char *answer = NULL; /* Answer str to many questions */
@ -81,17 +76,20 @@ int placewewant = 0; /* The column we'd like the cursor
to jump to when we go to the to jump to when we go to the
next or previous line */ next or previous line */
int tabsize = 8; /* Our internal tabsize variable */ int tabsize = -1; /* Our internal tabsize variable. The
default value 8 is set in main(). */
char *hblank; /* A horizontal blank line */ char *hblank = NULL; /* A horizontal blank line */
#ifndef DISABLE_HELP #ifndef DISABLE_HELP
char *help_text; /* The text in the help window */ char *help_text; /* The text in the help window */
#endif #endif
/* More stuff for the marker select */ /* More stuff for the marker select */
#ifndef NANO_SMALL
filestruct *mark_beginbuf; /* the begin marker buffer */ filestruct *mark_beginbuf; /* the begin marker buffer */
int mark_beginx; /* X value in the string to start */ int mark_beginx; /* X value in the string to start */
#endif
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
char *operating_dir = NULL; /* Operating directory, which we can't */ char *operating_dir = NULL; /* Operating directory, which we can't */
@ -110,17 +108,18 @@ shortcut *goto_list = NULL;
shortcut *gotodir_list = NULL; shortcut *gotodir_list = NULL;
shortcut *writefile_list = NULL; shortcut *writefile_list = NULL;
shortcut *insertfile_list = NULL; shortcut *insertfile_list = NULL;
#ifndef DISABLE_HELP
shortcut *help_list = NULL; shortcut *help_list = NULL;
#endif
#ifndef DISABLE_SPELLER
shortcut *spell_list = NULL; shortcut *spell_list = NULL;
#endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
shortcut *extcmd_list = NULL; shortcut *extcmd_list = NULL;
#endif #endif
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
shortcut *browser_list = NULL; shortcut *browser_list = NULL;
#endif #endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
const colortype *colorstrings = NULL; const colortype *colorstrings = NULL;
syntaxtype *syntaxes = NULL; syntaxtype *syntaxes = NULL;
@ -232,9 +231,7 @@ void toggle_init(void)
#endif #endif
/* There is no need to reinitialize the toggles. They can't /* There is no need to reinitialize the toggles. They can't
change. In fact, reinitializing them causes a segfault in change. */
nano.c:do_toggle() when it is called with the Pico-mode
toggle. */
if (toggles != NULL) if (toggles != NULL)
return; return;
@ -591,11 +588,9 @@ void shortcut_init(int unjustify)
#ifndef NANO_SMALL #ifndef NANO_SMALL
sc_init_one(&whereis_list, KEY_UP, _("History"), sc_init_one(&whereis_list, KEY_UP, _("History"),
IFHELP(nano_editstr_msg, 0), 0, 0, VIEW, 0); IFHELP(nano_editstr_msg, 0), NANO_UP_KEY, 0, VIEW, 0);
#endif #endif
#endif /* !NANO_SMALL */ #endif /* !NANO_SMALL */
free_shortcutage(&replace_list); free_shortcutage(&replace_list);
@ -630,11 +625,8 @@ void shortcut_init(int unjustify)
IFHELP(nano_regexp_msg, 0), 0, 0, VIEW, 0); IFHELP(nano_regexp_msg, 0), 0, 0, VIEW, 0);
#endif #endif
#ifndef NANO_SMALL
sc_init_one(&replace_list, KEY_UP, _("History"), sc_init_one(&replace_list, KEY_UP, _("History"),
IFHELP(nano_editstr_msg, 0), 0, 0, VIEW, 0); IFHELP(nano_editstr_msg, 0), NANO_UP_KEY, 0, VIEW, 0);
#endif
#endif /* !NANO_SMALL */ #endif /* !NANO_SMALL */
free_shortcutage(&replace_list_2); free_shortcutage(&replace_list_2);
@ -653,7 +645,7 @@ void shortcut_init(int unjustify)
#ifndef NANO_SMALL #ifndef NANO_SMALL
sc_init_one(&replace_list_2, KEY_UP, _("History"), sc_init_one(&replace_list_2, KEY_UP, _("History"),
IFHELP(nano_editstr_msg, 0), 0, 0, VIEW, 0); IFHELP(nano_editstr_msg, 0), NANO_UP_KEY, 0, VIEW, 0);
#endif #endif
free_shortcutage(&goto_list); free_shortcutage(&goto_list);
@ -670,6 +662,7 @@ void shortcut_init(int unjustify)
sc_init_one(&goto_list, NANO_LASTLINE_KEY, _("Last Line"), sc_init_one(&goto_list, NANO_LASTLINE_KEY, _("Last Line"),
IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line); IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line);
#ifndef DISABLE_HELP
free_shortcutage(&help_list); free_shortcutage(&help_list);
sc_init_one(&help_list, NANO_PREVPAGE_KEY, _("Prev Page"), sc_init_one(&help_list, NANO_PREVPAGE_KEY, _("Prev Page"),
@ -683,6 +676,7 @@ void shortcut_init(int unjustify)
sc_init_one(&help_list, NANO_EXIT_KEY, _("Exit"), sc_init_one(&help_list, NANO_EXIT_KEY, _("Exit"),
IFHELP(nano_exit_msg, 0), NANO_EXIT_FKEY, 0, VIEW, IFHELP(nano_exit_msg, 0), NANO_EXIT_FKEY, 0, VIEW,
do_exit); do_exit);
#endif
free_shortcutage(&writefile_list); free_shortcutage(&writefile_list);
@ -737,6 +731,7 @@ void shortcut_init(int unjustify)
#endif #endif
#endif #endif
#ifndef DISABLE_SPELLER
free_shortcutage(&spell_list); free_shortcutage(&spell_list);
sc_init_one(&spell_list, NANO_HELP_KEY, _("Get Help"), sc_init_one(&spell_list, NANO_HELP_KEY, _("Get Help"),
@ -744,6 +739,7 @@ void shortcut_init(int unjustify)
sc_init_one(&spell_list, NANO_CANCEL_KEY, _("Cancel"), sc_init_one(&spell_list, NANO_CANCEL_KEY, _("Cancel"),
IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0); IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
#endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
free_shortcutage(&extcmd_list); free_shortcutage(&extcmd_list);
@ -801,6 +797,10 @@ void shortcut_init(int unjustify)
/* added by SPK for memory cleanup, gracefully return our malloc()s */ /* added by SPK for memory cleanup, gracefully return our malloc()s */
void thanks_for_all_the_fish(void) void thanks_for_all_the_fish(void)
{ {
#ifndef DISABLE_JUSTIFY
if (quotestr != NULL)
free(quotestr);
#endif
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
if (operating_dir != NULL) if (operating_dir != NULL)
free(operating_dir); free(operating_dir);
@ -833,16 +833,20 @@ void thanks_for_all_the_fish(void)
free_shortcutage(&replace_list); free_shortcutage(&replace_list);
free_shortcutage(&replace_list_2); free_shortcutage(&replace_list_2);
free_shortcutage(&goto_list); free_shortcutage(&goto_list);
free_shortcutage(&gotodir_list);
free_shortcutage(&writefile_list); free_shortcutage(&writefile_list);
free_shortcutage(&insertfile_list); free_shortcutage(&insertfile_list);
#ifndef DISABLE_HELP
free_shortcutage(&help_list); free_shortcutage(&help_list);
#endif
#ifndef DISABLE_SPELLER
free_shortcutage(&spell_list); free_shortcutage(&spell_list);
#endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
free_shortcutage(&extcmd_list); free_shortcutage(&extcmd_list);
#endif #endif
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
free_shortcutage(&browser_list); free_shortcutage(&browser_list);
free_shortcutage(&gotodir_list);
#endif #endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
@ -852,10 +856,7 @@ void thanks_for_all_the_fish(void)
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (open_files != NULL) { if (open_files != NULL) {
/* We free the memory associated with each open file. */ /* We free the memory associated with each open file. */
while (open_files->prev != NULL)
open_files = open_files->prev;
free_openfilestruct(open_files); free_openfilestruct(open_files);
}
#else #else
if (fileage != NULL) if (fileage != NULL)
free_filestruct(fileage); free_filestruct(fileage);
@ -871,15 +872,16 @@ void thanks_for_all_the_fish(void)
exttype *bob = syntaxes->extensions; exttype *bob = syntaxes->extensions;
syntaxes->extensions = bob->next; syntaxes->extensions = bob->next;
free(bob->val); regfree(&bob->val);
free(bob); free(bob);
} }
while (syntaxes->color != NULL) { while (syntaxes->color != NULL) {
colortype *bob = syntaxes->color; colortype *bob = syntaxes->color;
syntaxes->color = bob->next; syntaxes->color = bob->next;
free(bob->start); regfree(&bob->start);
free(bob->end); if (bob->end != NULL)
regfree(&bob->end);
free(bob); free(bob);
} }
syntaxes = syntaxes->next; syntaxes = syntaxes->next;

259
nano.c
View File

@ -405,7 +405,8 @@ void help_init(void)
else if (s->altval == NANO_ALT_SPACE) { else if (s->altval == NANO_ALT_SPACE) {
meta_shortcut = 1; meta_shortcut = 1;
ptr += sprintf(ptr, "M-%.5s", _("Space")); ptr += sprintf(ptr, "M-%.5s", _("Space"));
} } else if (s->val == KEY_UP)
ptr += sprintf(ptr, "%.2s", _("Up"));
#endif #endif
else if (s->altval > 0) { else if (s->altval > 0) {
meta_shortcut = 1; meta_shortcut = 1;
@ -762,14 +763,13 @@ void nano_disabled_msg(void)
void do_preserve_msg(void) void do_preserve_msg(void)
{ {
fprintf(stderr, _("\nThe -p flag now invokes the Pico \"preserve\" flag. The Pico compatibility\n")); fprintf(stderr, _("\nThe -p flag now invokes the Pico \"preserve\" flag. The Pico\n"));
fprintf(stderr, _("flag been removed as nano is now fully Pico compatible. Please see the nano\n")); fprintf(stderr, _("compatibility flag has been removed as nano is now fully Pico\n"));
fprintf(stderr, _("FAQ for more info on this change...\n\n")); fprintf(stderr, _("compatible. Please see the nano FAQ for more info on this change...\n\n"));
fprintf(stderr, _("Press return to continue\n")); fprintf(stderr, _("Press return to continue\n"));
while (getchar() != '\n'); while (getchar() != '\n');
} }
#ifndef NANO_SMALL #ifndef NANO_SMALL
static int pid; /* This is the PID of the newly forked process static int pid; /* This is the PID of the newly forked process
* below. It must be global since the signal * below. It must be global since the signal
@ -1644,7 +1644,11 @@ int do_int_spell_fix(const char *word)
do_replace_highlight(TRUE, word); do_replace_highlight(TRUE, word);
/* allow replace word to be corrected */ /* allow replace word to be corrected */
i = statusq(0, spell_list, last_replace, 0, _("Edit a replacement")); i = statusq(0, spell_list, last_replace,
#ifndef NANO_SMALL
0,
#endif
_("Edit a replacement"));
do_replace_highlight(FALSE, word); do_replace_highlight(FALSE, word);
@ -2985,10 +2989,9 @@ int abcd(int input)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int optchr; int optchr;
int kbinput; /* Input from keyboard */
int startline = 0; /* Line to try and start at */ int startline = 0; /* Line to try and start at */
int keyhandled; /* Have we handled the keystroke yet? */
int modify_control_seq; int modify_control_seq;
int fill_flag_used = 0; /* Was the fill option used? */
const shortcut *s; const shortcut *s;
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
int preserveopt = 0; /* Did the cmdline include --preserve? */ int preserveopt = 0; /* Did the cmdline include --preserve? */
@ -2996,11 +2999,9 @@ int main(int argc, char *argv[])
#ifndef NANO_SMALL #ifndef NANO_SMALL
const toggle *t; const toggle *t;
#endif #endif
#ifdef _POSIX_VDISABLE #ifdef _POSIX_VDISABLE
struct termios term; struct termios term;
#endif #endif
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
int option_index = 0; int option_index = 0;
const struct option long_options[] = { const struct option long_options[] = {
@ -3064,56 +3065,37 @@ int main(int argc, char *argv[])
textdomain(PACKAGE); textdomain(PACKAGE);
#endif #endif
#ifdef ENABLE_NANORC #ifdef HAVE_GETOPT_LONG
{ {
/* scan through the options and handle -I/--ignorercfiles /* Check for the --preserve flag, and report error if people are
first, so that it's handled before we call do_rcfile() and still using --pico. */
read the other options; don't use getopt()/getopt_long()
here, because there's no way to reset it properly
afterward. Also check for the --preserve flag, and report
error if people are still using --pico. */
int i; int i;
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--")) if (!strcmp(argv[i], "--preserve"))
break;
else if (!strcmp(argv[i], "-I"))
SET(NO_RCFILE);
#ifdef HAVE_GETOPT_LONG
else if (!strcmp(argv[i], "--ignorercfiles"))
SET(NO_RCFILE);
else if (!strcmp(argv[i], "--preserve"))
preserveopt = 1; preserveopt = 1;
else if (!strcmp(argv[i], "--pico")) else if (!strcmp(argv[i], "--pico"))
do_preserve_msg(); do_preserve_msg();
}
}
#endif #endif
}
}
if (!ISSET(NO_RCFILE)) #if !defined(ENABLE_NANORC) && defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING)
do_rcfile();
#else
#if defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING)
/* if we don't have rcfile support, we're root, and /* if we don't have rcfile support, we're root, and
--disable-wrapping-as-root is used, turn wrapping off */ --disable-wrapping-as-root is used, turn wrapping off */
if (geteuid() == 0) if (geteuid() == 0)
SET(NO_WRAP); SET(NO_WRAP);
#endif #endif
#endif /* ENABLE_NANORC */
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
while ((optchr = getopt_long(argc, argv, "h?BDFIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz", while ((optchr = getopt_long(argc, argv, "h?BDFIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz",
long_options, &option_index)) != EOF) { long_options, &option_index)) != -1) {
#else #else
while ((optchr = while ((optchr =
getopt(argc, argv, "h?BDFIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz")) != EOF) { getopt(argc, argv, "h?BDFIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz")) != -1) {
#endif #endif
switch (optchr) { switch (optchr) {
case 'h':
case '?':
usage();
exit(0);
case 'a': case 'a':
case 'b': case 'b':
case 'e': case 'e':
@ -3137,6 +3119,7 @@ int main(int argc, char *argv[])
#endif #endif
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
case 'I': case 'I':
SET(NO_RCFILE);
break; break;
#endif #endif
case 'K': case 'K':
@ -3152,7 +3135,7 @@ int main(int argc, char *argv[])
#endif #endif
#ifndef DISABLE_JUSTIFY #ifndef DISABLE_JUSTIFY
case 'Q': case 'Q':
quotestr = optarg; quotestr = mallocstrcpy(quotestr, optarg);
break; break;
#endif #endif
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
@ -3170,13 +3153,12 @@ int main(int argc, char *argv[])
int i; int i;
char *first_error; char *first_error;
/* Using strtol instead of atoi lets us accept 0 while /* Using strtol() instead of atoi() lets us accept 0
* checking other errors. */ * while checking other errors. */
i = (int)strtol(optarg, &first_error, 10); i = (int)strtol(optarg, &first_error, 10);
if (errno == ERANGE || *optarg == '\0' || *first_error != '\0') { if (errno == ERANGE || *optarg == '\0' || *first_error != '\0')
usage(); usage();
exit(1); else
} else
tabsize = i; tabsize = i;
if (tabsize <= 0) { if (tabsize <= 0) {
fprintf(stderr, _("Tab size is too small for nano...\n")); fprintf(stderr, _("Tab size is too small for nano...\n"));
@ -3229,15 +3211,15 @@ int main(int argc, char *argv[])
int i; int i;
char *first_error; char *first_error;
/* Using strtol instead of atoi lets us accept 0 while /* Using strtol() instead of atoi() lets us accept 0
* checking other errors. */ * while checking other errors. */
i = (int)strtol(optarg, &first_error, 10); i = (int)strtol(optarg, &first_error, 10);
if (errno == ERANGE || *optarg == '\0' || *first_error != '\0') { if (errno == ERANGE || *optarg == '\0' || *first_error != '\0')
usage(); usage();
exit(1); else
} else
wrap_at = i; wrap_at = i;
} }
fill_flag_used = 1;
break; break;
#endif #endif
#ifndef DISABLE_SPELLER #ifndef DISABLE_SPELLER
@ -3264,20 +3246,95 @@ int main(int argc, char *argv[])
break; break;
default: default:
usage(); usage();
exit(0);
} }
} }
/* We've read through the command line options. Now back up the flags
and values that are set, and read the rcfile(s). If the values
haven't changed afterward, restore the backed-up values. */
#ifdef ENABLE_NANORC
if (!ISSET(NO_RCFILE)) {
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
/* Set up the operating directory. This entails chdir()ing there, so char *operating_dir_cpy = operating_dir;
that file reads and writes will be based there. */ #endif
#ifndef DISABLE_WRAPPING
int wrap_at_cpy = wrap_at;
#endif
#ifndef DISABLE_JUSTIFY
char *quotestr_cpy = quotestr;
#endif
#ifndef DISABLE_SPELLER
char *alt_speller_cpy = alt_speller;
#endif
int tabsize_cpy = tabsize;
long flags_cpy = flags;
operating_dir = NULL;
quotestr = NULL;
alt_speller = NULL;
do_rcfile();
#ifndef DISABLE_OPERATINGDIR
if (operating_dir_cpy != NULL) {
free(operating_dir);
operating_dir = operating_dir_cpy;
}
#endif
#ifndef DISABLE_WRAPPING
if (fill_flag_used)
wrap_at = wrap_at_cpy;
#endif
#ifndef DISABLE_JUSTIFY
if (quotestr_cpy != NULL) {
free(quotestr);
quotestr = quotestr_cpy;
}
#endif
#ifndef DISABLE_SPELLER
if (alt_speller_cpy != NULL) {
free(alt_speller);
alt_speller = alt_speller_cpy;
}
#endif
if (tabsize_cpy > 0)
tabsize = tabsize_cpy;
flags |= flags_cpy;
}
#if defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING)
else if (geteuid() == 0)
SET(NO_WRAP);
#endif
#endif /* ENABLE_NANORC */
#ifndef DISABLE_OPERATINGDIR
/* Set up the operating directory. This entails chdir()ing there,
so that file reads and writes will be based there. */
init_operating_dir(); init_operating_dir();
#endif #endif
#ifndef DISABLE_JUSTIFY
if (quotestr == NULL)
#ifdef HAVE_REGEX_H
quotestr = mallocstrcpy(NULL, "^([ \t]*[|>:}#])+");
#else
quotestr = mallocstrcpy(NULL, "> ");
#endif
#endif /* !DISABLE_JUSTIFY */
if (tabsize == -1)
tabsize = 8;
/* Clear the filename we'll be using */ /* Clear the filename we'll be using */
filename = charalloc(1); filename = charalloc(1);
filename[0] = '\0'; filename[0] = '\0';
/* If there's a +LINE flag, it is the first non-option argument. */
if (0 < optind && optind < argc && argv[optind][0] == '+') {
startline = atoi(&argv[optind][1]);
optind++;
}
if (0 < optind && optind < argc)
filename = mallocstrcpy(filename, argv[optind]);
/* See if there's a non-option in argv (first non-option is the /* See if there's a non-option in argv (first non-option is the
filename, if +LINE is not given) */ filename, if +LINE is not given) */
@ -3333,10 +3390,6 @@ int main(int argc, char *argv[])
history_init(); history_init();
#endif #endif
#ifdef ENABLE_COLOR
do_colorinit();
#endif /* ENABLE_COLOR */
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, _("Main: bottom win\n")); fprintf(stderr, _("Main: bottom win\n"));
#endif #endif
@ -3347,32 +3400,41 @@ int main(int argc, char *argv[])
fprintf(stderr, _("Main: open file\n")); fprintf(stderr, _("Main: open file\n"));
#endif #endif
/* Now we check to see if argv[optind] is non-null to determine if open_file(filename, 1, 1);
we're dealing with a new file or not, not argc == 1... */ #ifdef ENABLE_MULTIBUFFER
if (argv[optind] == NULL) /* If we're using multibuffers and more than one file is specified
on the command line, load them all and switch to the first one
afterward */
if (ISSET(MULTIBUFFER) && optind + 1 < argc) {
for (optind++; optind < argc; optind++) {
add_open_file(1);
new_file(); new_file();
else filename = mallocstrcpy(filename, argv[optind]);
open_file(filename, 0, 0); open_file(filename, 0, 0);
load_file(0);
}
open_nextfile_void();
}
#endif
titlebar(NULL); titlebar(NULL);
if (startline > 0) if (startline > 0)
do_gotoline(startline, 0); do_gotoline(startline, 0);
else
edit_update(fileage, CENTER);
/* return here after a sigwinch */ /* Return here after a sigwinch */
sigsetjmp(jmpbuf, 1); sigsetjmp(jmpbuf, 1);
/* Fix clobber-age */ /* This variable should be initialized after the sigsetjmp(), so we
kbinput = 0; can't do Esc-Esc then quickly resize and muck things up. */
keyhandled = 0;
modify_control_seq = 0; modify_control_seq = 0;
edit_refresh(); edit_refresh();
reset_cursor(); reset_cursor();
while (1) { while (1) {
int keyhandled = 0; /* Have we handled the keystroke yet? */
int kbinput; /* Input from keyboard */
#if !defined(DISABLE_BROWSER) || !defined(DISABLE_HELP) || (!defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION)) #if !defined(DISABLE_BROWSER) || !defined(DISABLE_HELP) || (!defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION))
currshortcut = main_list; currshortcut = main_list;
@ -3388,10 +3450,14 @@ int main(int argc, char *argv[])
fprintf(stderr, _("AHA! %c (%d)\n"), kbinput, kbinput); fprintf(stderr, _("AHA! %c (%d)\n"), kbinput, kbinput);
#endif #endif
if (kbinput == 27) { /* Grab Alt-key stuff first */ if (kbinput == 27) { /* Grab Alt-key stuff first */
switch (kbinput = wgetch(edit)) { kbinput = wgetch(edit);
switch (kbinput) {
/* Alt-O, suddenly very important ;) */ /* Alt-O, suddenly very important ;) */
case 'O': case 'O':
kbinput = wgetch(edit); kbinput = wgetch(edit);
/* Shift or Ctrl + Arrows are Alt-O-[2,5,6]-[A,B,C,D] on some terms */
if (kbinput == '2' || kbinput == '5' || kbinput == '6')
kbinput = wgetch(edit);
if ((kbinput <= 'D' && kbinput >= 'A') || if ((kbinput <= 'D' && kbinput >= 'A') ||
(kbinput <= 'd' && kbinput >= 'a')) (kbinput <= 'd' && kbinput >= 'a'))
kbinput = abcd(kbinput); kbinput = abcd(kbinput);
@ -3414,7 +3480,8 @@ int main(int argc, char *argv[])
keyhandled = 1; keyhandled = 1;
break; break;
case '[': case '[':
switch (kbinput = wgetch(edit)) { kbinput = wgetch(edit);
switch (kbinput) {
case '1': /* Alt-[-1-[0-5,7-9] = F1-F8 in X at least */ case '1': /* Alt-[-1-[0-5,7-9] = F1-F8 in X at least */
kbinput = wgetch(edit); kbinput = wgetch(edit);
if (kbinput >= '1' && kbinput <= '5') { if (kbinput >= '1' && kbinput <= '5') {
@ -3453,7 +3520,8 @@ int main(int argc, char *argv[])
wgetch(edit); wgetch(edit);
break; break;
case '~': case '~':
goto do_insertkey; kbinput = NANO_INSERTFILE_KEY;
break;
#ifdef DEBUG #ifdef DEBUG
default: default:
fprintf(stderr, _("I got Alt-[-2-%c! (%d)\n"), fprintf(stderr, _("I got Alt-[-2-%c! (%d)\n"),
@ -3499,7 +3567,8 @@ int main(int argc, char *argv[])
break; break;
case '@': /* Alt-[-@ = Insert in Hurd Console */ case '@': /* Alt-[-@ = Insert in Hurd Console */
case 'L': /* Alt-[-L = Insert - FreeBSD Console */ case 'L': /* Alt-[-L = Insert - FreeBSD Console */
goto do_insertkey; kbinput = NANO_INSERTFILE_KEY;
break;
case '[': /* Alt-[-[-[A-E], F1-F5 in Linux console */ case '[': /* Alt-[-[-[A-E], F1-F5 in Linux console */
kbinput = wgetch(edit); kbinput = wgetch(edit);
if (kbinput >= 'A' && kbinput <= 'E') if (kbinput >= 'A' && kbinput <= 'E')
@ -3530,7 +3599,6 @@ int main(int argc, char *argv[])
break; break;
} }
break; break;
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
case NANO_OPENPREV_KEY: case NANO_OPENPREV_KEY:
case NANO_OPENPREV_ALTKEY: case NANO_OPENPREV_ALTKEY:
@ -3546,8 +3614,8 @@ int main(int argc, char *argv[])
default: default:
/* Check for the altkey defs.... */ /* Check for the altkey defs.... */
for (s = main_list; s != NULL; s = s->next) for (s = main_list; s != NULL; s = s->next)
if (kbinput == s->altval || if (kbinput == s->altval || (kbinput >= 'A' &&
kbinput == s->altval - 32) { kbinput <= 'Z' && kbinput == s->altval - 32)) {
if (ISSET(VIEW_MODE) && !s->viewok) if (ISSET(VIEW_MODE) && !s->viewok)
print_view_warning(); print_view_warning();
else else
@ -3558,9 +3626,8 @@ int main(int argc, char *argv[])
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* And for toggle switches */ /* And for toggle switches */
for (t = toggles; t != NULL && !keyhandled; t = t->next) for (t = toggles; t != NULL && !keyhandled; t = t->next)
if (kbinput == t->val || if (kbinput == t->val || (t->val >= 'a' &&
(t->val > 'a' && t->val <= 'z' && kbinput == t->val - 32)) {
kbinput == t->val - 32)) {
do_toggle(t); do_toggle(t);
keyhandled = 1; keyhandled = 1;
break; break;
@ -3573,6 +3640,10 @@ int main(int argc, char *argv[])
break; break;
} }
} }
/* Hack, make insert key do something useful, like insert file */
else if (kbinput == KEY_IC)
kbinput = NANO_INSERTFILE_KEY;
/* If modify_control_seq is set, we received an Alt-Alt /* If modify_control_seq is set, we received an Alt-Alt
sequence before this, so we make this key a control sequence sequence before this, so we make this key a control sequence
by subtracting 32, 64, or 96, depending on its value. */ by subtracting 32, 64, or 96, depending on its value. */
@ -3603,7 +3674,7 @@ int main(int argc, char *argv[])
else else
s->func(); s->func();
keyhandled = 1; keyhandled = 1;
/* rarely, the value of s can change after s->func(), /* Rarely, the value of s can change after s->func(),
leading to problems; get around this by breaking out leading to problems; get around this by breaking out
explicitly once we successfully handle a shortcut */ explicitly once we successfully handle a shortcut */
break; break;
@ -3630,25 +3701,6 @@ int main(int argc, char *argv[])
keyhandled = 1; keyhandled = 1;
} }
/* Hack, make insert key do something useful, like insert file */
if (kbinput == KEY_IC) {
do_insertkey:
#ifdef ENABLE_MULTIBUFFER
/* do_insertfile_void() contains the logic needed to
handle view mode with the view mode/multibuffer
exception, so use it here */
do_insertfile_void();
#else
if (!ISSET(VIEW_MODE))
do_insertfile_void();
else
print_view_warning();
#endif
keyhandled = 1;
}
/* Last gasp, stuff that's not in the main lists */ /* Last gasp, stuff that's not in the main lists */
if (!keyhandled) if (!keyhandled)
switch (kbinput) { switch (kbinput) {
@ -3659,9 +3711,9 @@ int main(int argc, char *argv[])
#endif #endif
case 0: /* Erg */ case 0: /* Erg */
case -1: /* Stuff that we don't want to do squat */
case 410: /* Must ignore this, it gets sent when we resize */
case 29: /* Ctrl-] */ case 29: /* Ctrl-] */
case -1: /* Stuff that we don't want to do squat */
case 410: /* Must ignore this, it's sent when we resize */
#ifdef PDCURSES #ifdef PDCURSES
case 541: /* ???? */ case 541: /* ???? */
case 542: /* Control and alt in Windows *shrug* */ case 542: /* Control and alt in Windows *shrug* */
@ -3678,12 +3730,12 @@ int main(int argc, char *argv[])
/* We no longer stop unhandled sequences so that people with /* We no longer stop unhandled sequences so that people with
odd character sets can type... */ odd character sets can type... */
if (ISSET(VIEW_MODE)) { if (ISSET(VIEW_MODE))
print_view_warning(); print_view_warning();
break; else
}
do_char(kbinput); do_char(kbinput);
} }
if (ISSET(DISABLE_CURPOS)) if (ISSET(DISABLE_CURPOS))
UNSET(DISABLE_CURPOS); UNSET(DISABLE_CURPOS);
else if (ISSET(CONSTUPDATE)) else if (ISSET(CONSTUPDATE))
@ -3691,9 +3743,6 @@ int main(int argc, char *argv[])
reset_cursor(); reset_cursor();
wrefresh(edit); wrefresh(edit);
keyhandled = 0;
} }
assert(0);
getchar();
finish(0);
} }

20
nano.h
View File

@ -32,6 +32,9 @@
#define ISSET(bit) (flags & bit) #define ISSET(bit) (flags & bit)
#define TOGGLE(bit) flags ^= bit #define TOGGLE(bit) flags ^= bit
/* Define charalloc as a macro rather than duplicating code */
#define charalloc(howmuch) (char *)nmalloc((howmuch) * sizeof(char))
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* For the backup file copy ... */ /* For the backup file copy ... */
# define COPYFILEBLOCKSIZE 1024 # define COPYFILEBLOCKSIZE 1024
@ -91,12 +94,11 @@
#endif /* KEY_END */ #endif /* KEY_END */
/* Snatch these out of the ncurses defs, so we can use them in search /* Snatch these out of the ncurses defs, so we can use them in search
history regardless of whethere we're using ncurses or not */ history regardless of whether we're using ncurses or not */
#ifndef KEY_UP #if !defined(KEY_UP) || !defined(KEY_DOWN)
#define KEY_UP 0403 #define KEY_UP 0403
#define KEY_DOWN 0402 #define KEY_DOWN 0402
#endif /* KEY_UP */ #endif /* !KEY_UP || !KEY_DOWN */
#define VERMSG "GNU nano " VERSION #define VERMSG "GNU nano " VERSION
@ -412,12 +414,16 @@ typedef enum {
/* Minimum editor window rows required for nano to work correctly */ /* Minimum editor window rows required for nano to work correctly */
#define MIN_EDITOR_ROWS 3 #define MIN_EDITOR_ROWS 3
/* Default number of characters from end-of-line where text wrapping occurs */ /* Default number of characters from end-of-line where text wrapping
occurs */
#define CHARS_FROM_EOL 8 #define CHARS_FROM_EOL 8
/* Minimum fill length (space available for text before wrapping occurs) */ /* Minimum fill length (space available for text before wrapping
occurs) */
#define MIN_FILL_LENGTH 10 #define MIN_FILL_LENGTH 10
/* Maximum number of search history strings saved, same value used for replace history */ /* Maximum number of search history strings saved, same value used for
replace history */
#define MAX_SEARCH_HISTORY 100 #define MAX_SEARCH_HISTORY 100
#endif /* !NANO_H */ #endif /* !NANO_H */

View File

@ -40,7 +40,7 @@ extern long totsize;
extern int temp_opt; extern int temp_opt;
extern int wrap_at, flags, tabsize; extern int wrap_at, flags, tabsize;
extern int search_last_line; extern int search_last_line;
extern int past_editbuff; extern int search_offscreen;
extern int currslen; extern int currslen;
#ifndef DISABLE_JUSTIFY #ifndef DISABLE_JUSTIFY
@ -169,13 +169,13 @@ int check_operating_dir(const char *currpath, int allow_tabcomp);
int write_file(const char *name, int tmp, int append, int nonamechange); int write_file(const char *name, int tmp, int append, int nonamechange);
int do_writeout(const char *path, int exiting, int append); int do_writeout(const char *path, int exiting, int append);
int do_writeout_void(void); int do_writeout_void(void);
#ifndef DISABLE_TABCOMP
char *real_dir_from_tilde(const char *buf); char *real_dir_from_tilde(const char *buf);
#endif #ifndef DISABLE_TABCOMP
int append_slash_if_dir(char *buf, int *lastwastab, int *place); int append_slash_if_dir(char *buf, int *lastwastab, int *place);
char **username_tab_completion(char *buf, int *num_matches); char **username_tab_completion(char *buf, int *num_matches);
char **cwd_tab_completion(char *buf, int *num_matches); char **cwd_tab_completion(char *buf, int *num_matches);
char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list); char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list);
#endif
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
struct stat filestat(const char *path); struct stat filestat(const char *path);
int diralphasort(const void *va, const void *vb); int diralphasort(const void *va, const void *vb);
@ -350,7 +350,6 @@ void replace_abort(void);
int replace_regexp(char *string, int create_flag); int replace_regexp(char *string, int create_flag);
#endif #endif
char *replace_line(void); char *replace_line(void);
void print_replaced(int num);
int do_replace_loop(const char *prevanswer, const filestruct *begin, int do_replace_loop(const char *prevanswer, const filestruct *begin,
int *beginx, int wholewords, int *i); int *beginx, int wholewords, int *i);
int do_replace(void); int do_replace(void);
@ -391,7 +390,6 @@ const char *strstrwrapper(const char *haystack, const char *needle,
const char *rev_start, int line_pos); const char *rev_start, int line_pos);
void nperror(const char *s); void nperror(const char *s);
void *nmalloc(size_t howmuch); void *nmalloc(size_t howmuch);
char *charalloc(size_t howmuch);
void *nrealloc(void *ptr, size_t howmuch); void *nrealloc(void *ptr, size_t howmuch);
char *mallocstrcpy(char *dest, const char *src); char *mallocstrcpy(char *dest, const char *src);
void new_magicline(void); void new_magicline(void);

View File

@ -27,10 +27,10 @@
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <pwd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h>
#include <assert.h> #include <assert.h>
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
@ -67,6 +67,7 @@ const static rcoption rcopts[] = {
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
{"operatingdir", 0}, {"operatingdir", 0},
#endif #endif
{"preserve", PRESERVE},
#ifndef DISABLE_JUSTIFY #ifndef DISABLE_JUSTIFY
{"quotestr", 0}, {"quotestr", 0},
#endif #endif
@ -521,8 +522,8 @@ void parse_rcfile(FILE *rcstream)
if (!strcasecmp(rcopts[i].name, "fill")) { if (!strcasecmp(rcopts[i].name, "fill")) {
char *first_error; char *first_error;
/* Using strtol instead of atoi lets us /* Using strtol() instead of atoi() lets
* accept 0 while checking other * us accept 0 while checking other
* errors. */ * errors. */
j = (int)strtol(option, &first_error, 10); j = (int)strtol(option, &first_error, 10);
if (errno == ERANGE || *option == '\0' || *first_error != '\0') if (errno == ERANGE || *option == '\0' || *first_error != '\0')
@ -608,7 +609,7 @@ void do_rcfile(void)
if (userage == NULL) { if (userage == NULL) {
rcfile_error(_("I can't find my home directory! Wah!")); rcfile_error(_("I can't find my home directory! Wah!"));
SET(NO_RCFILE); /* if no .nanorc, don't try to read .nano_history */ SET(NO_RCFILE);
} else { } else {
nanorc = nrealloc(nanorc, strlen(userage->pw_dir) + 9); nanorc = nrealloc(nanorc, strlen(userage->pw_dir) + 9);
sprintf(nanorc, "%s/.nanorc", userage->pw_dir); sprintf(nanorc, "%s/.nanorc", userage->pw_dir);

118
search.c
View File

@ -31,15 +31,6 @@
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
#ifndef NANO_SMALL
#ifdef ENABLE_NANORC
#include <pwd.h>
#endif
#endif
static int past_editbuff;
/* findnextstr() is now searching lines not displayed */
/* Regular expression helper functions */ /* Regular expression helper functions */
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
@ -95,13 +86,12 @@ void search_init_globals(void)
} }
} }
/* Set up the system variables for a search or replace. Returns -1 on /* Set up the system variables for a search or replace. Return -1 on
abort, 0 on success, and 1 on rerun calling program * abort, 0 on success, and 1 on rerun calling program. Return -2 to
Return -2 to run opposite program (search -> replace, replace -> * run opposite program (search -> replace, replace -> search).
search). *
* replacing = 1 if we call from do_replace, 0 if called from do_search
replacing = 1 if we call from do_replace, 0 if called from do_search * func. */
func. */
int search_init(int replacing) int search_init(int replacing)
{ {
int i = 0; int i = 0;
@ -113,8 +103,6 @@ int search_init(int replacing)
if (backupstring == NULL) if (backupstring == NULL)
backupstring = mallocstrcpy(backupstring, ""); backupstring = mallocstrcpy(backupstring, "");
/* NEW TEST */
#ifndef NANO_SMALL #ifndef NANO_SMALL
search_history.current = (historytype *)&search_history.next; search_history.current = (historytype *)&search_history.next;
#endif #endif
@ -209,7 +197,7 @@ int search_init(int replacing)
#ifndef NANO_SMALL #ifndef NANO_SMALL
search_history.current = search_history.next; search_history.current = search_history.next;
#endif #endif
i = (int)strtol(answer, &buf, 10); /* just testing answer here */ i = (int)strtol(answer, &buf, 10); /* Just testing answer here */
if (!(errno == ERANGE || *answer == '\0' || *buf != '\0')) if (!(errno == ERANGE || *answer == '\0' || *buf != '\0'))
do_gotoline(-1, 0); do_gotoline(-1, 0);
else else
@ -230,7 +218,7 @@ int is_whole_word(int curr_pos, const char *datastr, const char *searchword)
size_t sln = curr_pos + strlen(searchword); size_t sln = curr_pos + strlen(searchword);
/* start of line or previous character not a letter and end of line /* start of line or previous character not a letter and end of line
* or next character not a letter */ or next character not a letter */
return (curr_pos < 1 || !isalpha((int)datastr[curr_pos - 1])) && return (curr_pos < 1 || !isalpha((int)datastr[curr_pos - 1])) &&
(sln == strlen(datastr) || !isalpha((int)datastr[sln])); (sln == strlen(datastr) || !isalpha((int)datastr[sln]));
} }
@ -243,7 +231,7 @@ filestruct *findnextstr(int quiet, int bracket_mode,
const char *searchstr, *rev_start = NULL, *found = NULL; const char *searchstr, *rev_start = NULL, *found = NULL;
int current_x_find = 0; int current_x_find = 0;
past_editbuff = 0; search_offscreen = 0;
if (!ISSET(REVERSE_SEARCH)) { /* forward search */ if (!ISSET(REVERSE_SEARCH)) { /* forward search */
/* Argh, current_x is set to -1 by nano.c:do_int_spell_fix(), and /* Argh, current_x is set to -1 by nano.c:do_int_spell_fix(), and
@ -274,7 +262,7 @@ filestruct *findnextstr(int quiet, int bracket_mode,
fileptr = fileptr->next; fileptr = fileptr->next;
if (fileptr == editbot) if (fileptr == editbot)
past_editbuff = 1; search_offscreen = 1;
/* EOF reached?, wrap around once */ /* EOF reached?, wrap around once */
if (fileptr == NULL) { if (fileptr == NULL) {
@ -282,7 +270,7 @@ filestruct *findnextstr(int quiet, int bracket_mode,
if (bracket_mode) if (bracket_mode)
return NULL; return NULL;
fileptr = fileage; fileptr = fileage;
past_editbuff = 1; search_offscreen = 1;
if (!quiet) { if (!quiet) {
statusbar(_("Search Wrapped")); statusbar(_("Search Wrapped"));
SET(DISABLE_CURPOS); SET(DISABLE_CURPOS);
@ -299,7 +287,7 @@ filestruct *findnextstr(int quiet, int bracket_mode,
/* We found an instance */ /* We found an instance */
current_x_find = found - fileptr->data; current_x_find = found - fileptr->data;
/* Ensure we haven't wrapped around again! */ /* Ensure we haven't wrapped around again! */
if ((search_last_line) && (current_x_find > beginx)) { if (search_last_line && current_x_find > beginx) {
if (!quiet) if (!quiet)
not_found_msg(needle); not_found_msg(needle);
return NULL; return NULL;
@ -308,7 +296,7 @@ filestruct *findnextstr(int quiet, int bracket_mode,
#ifndef NANO_SMALL #ifndef NANO_SMALL
else { /* reverse search */ else { /* reverse search */
current_x_find = current_x - 1; current_x_find = current_x - 1;
/* Make sure we haven't passed the begining of the string */ /* Make sure we haven't passed the beginning of the string */
rev_start = &fileptr->data[current_x_find]; rev_start = &fileptr->data[current_x_find];
searchstr = fileptr->data; searchstr = fileptr->data;
@ -329,14 +317,14 @@ filestruct *findnextstr(int quiet, int bracket_mode,
fileptr = fileptr->prev; fileptr = fileptr->prev;
if (fileptr == edittop->prev) if (fileptr == edittop->prev)
past_editbuff = 1; search_offscreen = 1;
/* SOF reached?, wrap around once */ /* SOF reached?, wrap around once */
/* ? */ if (fileptr == NULL) { /* ? */ if (fileptr == NULL) {
if (bracket_mode) if (bracket_mode)
return NULL; return NULL;
fileptr = filebot; fileptr = filebot;
past_editbuff = 1; search_offscreen = 1;
if (!quiet) { if (!quiet) {
statusbar(_("Search Wrapped")); statusbar(_("Search Wrapped"));
SET(DISABLE_CURPOS); SET(DISABLE_CURPOS);
@ -366,7 +354,7 @@ filestruct *findnextstr(int quiet, int bracket_mode,
current_x = current_x_find; current_x = current_x_find;
if (!bracket_mode) { if (!bracket_mode) {
if (past_editbuff) if (search_offscreen)
edit_update(fileptr, CENTER); edit_update(fileptr, CENTER);
else else
update_line(current, current_x); update_line(current, current_x);
@ -403,7 +391,7 @@ int do_search(void)
return 1; return 1;
} }
/* If answer is now == "", copy last_search into answer... */ /* If answer is now "", copy last_search into answer... */
if (answer[0] == '\0') if (answer[0] == '\0')
answer = mallocstrcpy(answer, last_search); answer = mallocstrcpy(answer, last_search);
else else
@ -415,10 +403,15 @@ int do_search(void)
update_history(&search_history, answer); update_history(&search_history, answer);
#endif /* !NANO_SMALL */ #endif /* !NANO_SMALL */
#ifndef NANO_SMALL
/* add this search string to the search history list */
update_history(&search_history, answer);
#endif /* !NANO_SMALL */
search_last_line = 0; search_last_line = 0;
didfind = findnextstr(FALSE, FALSE, current, current_x, answer); didfind = findnextstr(FALSE, FALSE, current, current_x, answer);
if ((fileptr == current) && (fileptr_x == current_x) && didfind != NULL) if (fileptr == current && fileptr_x == current_x && didfind != NULL)
statusbar(_("This is the only occurrence")); statusbar(_("This is the only occurrence"));
search_abort(); search_abort();
@ -438,9 +431,9 @@ void replace_abort(void)
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
int replace_regexp(char *string, int create_flag) int replace_regexp(char *string, int create_flag)
{ {
/* split personality here - if create_flag is null, just calculate /* Split personality here - if create_flag is NULL, just calculate
* the size of the replacement line (necessary because of * the size of the replacement line (necessary because of
* subexpressions like \1 \2 \3 in the replaced text) */ * subexpressions like \1 \2 \3 in the replaced text). */
char *c; char *c;
int new_size = strlen(current->data) + 1; int new_size = strlen(current->data) + 1;
@ -459,14 +452,14 @@ int replace_regexp(char *string, int create_flag)
c++; c++;
new_size++; new_size++;
} else { } else {
int num = (int) *(c + 1) - (int) '0'; int num = (int)(*(c + 1) - '0');
if (num >= 1 && num <= 9) { if (num >= 1 && num <= 9) {
int i = regmatches[num].rm_so; int i = regmatches[num].rm_so;
if (num > search_regexp.re_nsub) { if (num > search_regexp.re_nsub) {
/* Ugh, they specified a subexpression that doesn't /* Ugh, they specified a subexpression that doesn't
exist. */ * exist. */
return -1; return -1;
} }
@ -491,7 +484,7 @@ int replace_regexp(char *string, int create_flag)
} }
if (create_flag) if (create_flag)
*string = 0; *string = '\0';
return new_size; return new_size;
} }
@ -549,19 +542,13 @@ char *replace_line(void)
return copy; return copy;
} }
void print_replaced(int num) /* Step through each replace word and prompt user before replacing
{ * word. Return -1 if the string to replace isn't found at all.
if (num > 1) * Otherwise, return the number of replacements made. */
statusbar(_("Replaced %d occurrences"), num);
else if (num == 1)
statusbar(_("Replaced 1 occurrence"));
}
/* step through each replace word and prompt user before replacing word */
int do_replace_loop(const char *prevanswer, const filestruct *begin, int do_replace_loop(const char *prevanswer, const filestruct *begin,
int *beginx, int wholewords, int *i) int *beginx, int wholewords, int *i)
{ {
int replaceall = 0, numreplaced = 0; int replaceall = 0, numreplaced = -1;
filestruct *fileptr = NULL; filestruct *fileptr = NULL;
char *copy; char *copy;
@ -602,6 +589,9 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin,
continue; continue;
/* If we're here, we've found the search string */ /* If we're here, we've found the search string */
if (numreplaced == -1)
numreplaced = 0;
if (!replaceall) { if (!replaceall) {
curs_set(0); curs_set(0);
do_replace_highlight(TRUE, prevanswer); do_replace_highlight(TRUE, prevanswer);
@ -664,10 +654,14 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin,
break; break;
} }
/* If text has been added to the magicline, make a new magicline. */
if (filebot->data[0] != '\0')
new_magicline();
return numreplaced; return numreplaced;
} }
/* Replace a string */ /* Replace a string. */
int do_replace(void) int do_replace(void)
{ {
int i, numreplaced, beginx; int i, numreplaced, beginx;
@ -738,7 +732,13 @@ int do_replace(void)
current_x = beginx; current_x = beginx;
renumber_all(); renumber_all();
edit_update(current, CENTER); edit_update(current, CENTER);
print_replaced(numreplaced);
if (numreplaced >= 0)
statusbar(__("Replaced %d occurrence", "Replaced %d occurrences",
numreplaced), numreplaced);
else
not_found_msg(prevanswer);
replace_abort(); replace_abort();
return 1; return 1;
} }
@ -752,7 +752,11 @@ void goto_abort(void)
int do_gotoline(int line, int save_pos) int do_gotoline(int line, int save_pos)
{ {
if (line <= 0) { /* Ask for it */ if (line <= 0) { /* Ask for it */
if (statusq(0, goto_list, (line ? answer : ""), 0, _("Enter line number"))) { if (statusq(0, goto_list, (line ? answer : ""),
#ifndef NANO_SMALL
0,
#endif
_("Enter line number"))) {
statusbar(_("Aborted")); statusbar(_("Aborted"));
goto_abort(); goto_abort();
return 0; return 0;
@ -815,7 +819,7 @@ int do_find_bracket(void)
char ch_under_cursor, wanted_ch; char ch_under_cursor, wanted_ch;
const char *pos, *brackets = "([{<>}])"; const char *pos, *brackets = "([{<>}])";
char regexp_pat[] = "[ ]"; char regexp_pat[] = "[ ]";
int offset, have_past_editbuff = 0, flagsave, current_x_save, count = 1; int offset, have_search_offscreen = 0, flagsave, current_x_save, count = 1;
filestruct *current_save; filestruct *current_save;
ch_under_cursor = current->data[current_x]; ch_under_cursor = current->data[current_x];
@ -853,12 +857,16 @@ int do_find_bracket(void)
while (1) { while (1) {
search_last_line = 0; search_last_line = 0;
if (findnextstr(1, 1, current, current_x, regexp_pat) != NULL) { if (findnextstr(1, 1, current, current_x, regexp_pat) != NULL) {
have_past_editbuff |= past_editbuff; have_search_offscreen |= search_offscreen;
if (current->data[current_x] == ch_under_cursor) /* found identical bracket */
/* found identical bracket */
if (current->data[current_x] == ch_under_cursor)
count++; count++;
else { /* found complementary bracket */ else {
/* found complementary bracket */
if (!(--count)) { if (!(--count)) {
if (have_past_editbuff) if (have_search_offscreen)
edit_update(current, CENTER); edit_update(current, CENTER);
else else
update_line(current, current_x); update_line(current, current_x);
@ -867,7 +875,9 @@ int do_find_bracket(void)
break; break;
} }
} }
} else { /* didn't find either left or right bracket */ } else {
/* didn't find either left or right bracket */
statusbar(_("No matching bracket")); statusbar(_("No matching bracket"));
current_x = current_x_save; current_x = current_x_save;
current = current_save; current = current_save;

28
utils.c
View File

@ -54,7 +54,7 @@ int num_of_digits(int n)
/* Fix the memory allocation for a string. */ /* Fix the memory allocation for a string. */
void align(char **strp) void align(char **strp)
{ {
assert(strp != NULL); if (strp != NULL)
*strp = nrealloc(*strp, strlen(*strp) + 1); *strp = nrealloc(*strp, strlen(*strp) + 1);
} }
@ -199,34 +199,20 @@ void nperror(const char *s)
/* Thanks BG, many ppl have been asking for this... */ /* Thanks BG, many ppl have been asking for this... */
void *nmalloc(size_t howmuch) void *nmalloc(size_t howmuch)
{ {
void *r; void *r = malloc(howmuch);
/* Panic save? */ if (r == NULL && howmuch != 0)
die(_("nano is out of memory!"));
if ((r = malloc(howmuch)) == NULL)
die(_("nano: malloc: out of memory!"));
return r;
}
/* We're going to need this too - Hopefully this will minimize the
* transition cost of moving to the appropriate function. */
char *charalloc(size_t howmuch)
{
char *r = (char *)malloc(howmuch * sizeof(char));
if (r == NULL)
die(_("nano: malloc: out of memory!"));
return r; return r;
} }
void *nrealloc(void *ptr, size_t howmuch) void *nrealloc(void *ptr, size_t howmuch)
{ {
void *r; void *r = realloc(ptr, howmuch);
if ((r = realloc(ptr, howmuch)) == NULL) if (r == NULL && howmuch != 0)
die(_("nano: realloc: out of memory!")); die(_("nano is out of memory!"));
return r; return r;
} }

32
winio.c
View File

@ -161,10 +161,10 @@ void check_statblank(void)
} }
} }
/* Repaint the statusbar when getting a character in nanogetstr. buf /* Repaint the statusbar when getting a character in nanogetstr(). buf
* should be no longer than COLS - 4. * should be no longer than COLS - 4.
* *
* Note that we must turn on A_REVERSE here, since do_help turns it * Note that we must turn on A_REVERSE here, since do_help() turns it
* off! */ * off! */
void nanoget_repaint(const char *buf, const char *inputbuf, int x) void nanoget_repaint(const char *buf, const char *inputbuf, int x)
{ {
@ -313,13 +313,13 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
case NANO_CONTROL_I: case NANO_CONTROL_I:
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* tab history completion */ /* tab history completion */
if (history_list) { if (history_list != NULL) {
if ((!complete) || (last_kbinput != NANO_CONTROL_I)) { if (!complete || last_kbinput != NANO_CONTROL_I) {
history_list->current = (historytype *)history_list; history_list->current = (historytype *)history_list;
history_list->len = strlen(answer); history_list->len = strlen(answer);
} }
if (history_list->len) { if (history_list->len > 0) {
complete = get_history_completion(history_list, answer); complete = get_history_completion(history_list, answer);
xend = strlen(complete); xend = strlen(complete);
x = xend; x = xend;
@ -349,18 +349,20 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
x--; x--;
break; break;
case KEY_UP: case KEY_UP:
case NANO_UP_KEY:
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (history_list) { if (history_list) {
/* If there's no previous temp holder, or if we already arrowed /* If there's no previous temp holder, or if we already
back down to it and (possibly edited ir), update the holder */ arrowed back down to it and (possibly edited it),
update the holder */
if (currentbuf == NULL || (ret2cb == 1 && strcmp(currentbuf, answer))) { if (currentbuf == NULL || (ret2cb == 1 && strcmp(currentbuf, answer))) {
currentbuf = mallocstrcpy(currentbuf, answer); currentbuf = mallocstrcpy(currentbuf, answer);
ret2cb = 0; ret2cb = 0;
} }
/* get older search from the history list */ /* get older search from the history list */
if ((history = get_history_older(history_list))) { if ((history = get_history_older(history_list)) != NULL) {
answer = mallocstrcpy(answer, history); answer = mallocstrcpy(answer, history);
xend = strlen(history); xend = strlen(history);
} else { } else {
@ -372,10 +374,11 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
#endif #endif
break; break;
case KEY_DOWN: case KEY_DOWN:
case NANO_DOWN_KEY:
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (history_list) { if (history_list) {
/* get newer search from the history list */ /* get newer search from the history list */
if ((history = get_history_newer(history_list))) { if ((history = get_history_newer(history_list)) != NULL) {
answer = mallocstrcpy(answer, history); answer = mallocstrcpy(answer, history);
xend = strlen(history); xend = strlen(history);
@ -395,7 +398,6 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
break; break;
case KEY_DC: case KEY_DC:
goto do_deletekey; goto do_deletekey;
case 27: case 27:
switch (kbinput = wgetch(edit)) { switch (kbinput = wgetch(edit)) {
case 'O': case 'O':
@ -432,7 +434,6 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
case '4': case '4':
case '8': case '8':
x = xend; x = xend;
goto skip_tilde;
skip_tilde: skip_tilde:
nodelay(edit, TRUE); nodelay(edit, TRUE);
kbinput = wgetch(edit); kbinput = wgetch(edit);
@ -479,7 +480,7 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
wrefresh(bottomwin); wrefresh(bottomwin);
} /* while (kbinput ...) */ } /* while (kbinput ...) */
/* In Pico mode, just check for a blank answer here */ /* Just check for a blank answer here */
if (answer[0] == '\0') if (answer[0] == '\0')
return -2; return -2;
else else
@ -1101,15 +1102,14 @@ void edit_refresh(void)
nlines++; nlines++;
} }
/* What the hell are we expecting to update the screen if this /* What the hell are we expecting to update the screen if this
isn't here? Luck?? */ isn't here? Luck? */
wrefresh(edit); wrefresh(edit);
leaveok(edit, FALSE); leaveok(edit, FALSE);
} }
} }
/* /* Same as above, but touch the window first, so everything is
* Same as above, but touch the window first, so everything is redrawn. * redrawn. */
*/
void edit_refresh_clearok(void) void edit_refresh_clearok(void)
{ {
clearok(edit, TRUE); clearok(edit, TRUE);