Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f2f4d3ca9 | ||
|
|
2d189ae46d | ||
|
|
95add8dabe | ||
|
|
973addcde8 | ||
|
|
4e12cb8455 | ||
|
|
2a044ee3ea | ||
|
|
c81cf52cf2 | ||
|
|
c84e765b8e | ||
|
|
5c1c143ed2 | ||
|
|
3c4e99137d | ||
|
|
8f0a921fc1 | ||
|
|
513157dfa0 | ||
|
|
fa195e6d5d | ||
|
|
215eb3645e | ||
|
|
83c3f951f6 | ||
|
|
025548ad29 | ||
|
|
8227d419bb | ||
|
|
f30c1390c7 | ||
|
|
b549f3761a | ||
|
|
e137f12e5e | ||
|
|
86cab67339 | ||
|
|
566635ec16 | ||
|
|
95a9de0d3f | ||
|
|
1d77823f79 | ||
|
|
874969be81 | ||
|
|
6b83e5290c | ||
|
|
faeeb5bd7e | ||
|
|
dc7136a082 | ||
|
|
77bf1b5197 | ||
|
|
90ad8e20b9 | ||
|
|
2cc58882f6 | ||
|
|
93f2ea1194 | ||
|
|
d2780eca94 | ||
|
|
80ea9c5de9 | ||
|
|
b08b38680d | ||
|
|
5c27d723c9 | ||
|
|
447f1b4b75 | ||
|
|
6f681c1be2 | ||
|
|
a50d0e35f7 | ||
|
|
599c559b3c | ||
|
|
ea577874ef | ||
|
|
14c8620e0b | ||
|
|
3c1131a5b3 | ||
|
|
015c74093a | ||
|
|
d31ddb789f | ||
|
|
8f76112084 | ||
|
|
1f37c4514d | ||
|
|
91a1862eed | ||
|
|
e418b694b6 | ||
|
|
12dc8cae80 | ||
|
|
0b499d465b | ||
|
|
fa406949ec | ||
|
|
70859f4a5b | ||
|
|
9fb13fb8f0 | ||
|
|
274142cb10 | ||
|
|
b8576780bf | ||
|
|
a9dea9859d | ||
|
|
a855fa2acc | ||
|
|
09b8124859 | ||
|
|
07fcc4c973 | ||
|
|
1347f22c95 | ||
|
|
9015f187a5 |
116
ChangeLog
116
ChangeLog
@@ -1,3 +1,119 @@
|
||||
GNU nano 2.1.7 - 2008.11.10
|
||||
2008-10-20 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c (do_writeout): Add check for file modification when saving
|
||||
the file so the user can at least know they may be blowing away changes.
|
||||
|
||||
2008-10-14 Chris Allegretta <chrisa@asty.org>
|
||||
* nanorc.5: Fix redo man page entry and update explanation, reported by
|
||||
Eitan Adler <eitanadlerlist@gmail.com>
|
||||
* global.c (shortcut_init), search.c (search_init): Fix add_to_sclist for ^W^T so
|
||||
invalid messages will display properly. Fixes Savannah bug 24507.
|
||||
|
||||
2008-10-13 Chris Allegretta <chrisa@asty.org>
|
||||
* Remove CUTTOEND as an undo type as it's unneeded, fix u->to_end logic in undo struct.
|
||||
* undo.c (update_undo): Don't free cutbuffer if NULL, fix for Savannah bug #24499
|
||||
|
||||
2008-10-04 Chris Allegretta <chrisa@asty.org>
|
||||
* cut.c (Add_undo): Save last cut undo information so it can be used for next uncut, fixes
|
||||
Savannah bug 24183.
|
||||
|
||||
GNU nano 2.1.6 - 2008.10.03
|
||||
2008-10-03 Pascal Gentil <pascal.gentil@univ-rennes1.fr>
|
||||
* fortran.nanorc: Sample python syntax highlighting file
|
||||
|
||||
2008-09-30 Dirkjan Ochtman <dirkjan@ochtman.nl>
|
||||
* python.nanorc: Small python syntax update
|
||||
|
||||
2008-09-30 <bluestorm_dylc@hotmail.com>
|
||||
* ocaml.nanorc: Sample OCaml syntax highlighting file
|
||||
|
||||
2008-09-30 Dave Geering <dgeering@toshiba-tap.com>
|
||||
* objc.nanorc: Sample Objective-C Syntax Hightlighting file
|
||||
|
||||
2008-09-30 Chris Allegretta <chrisa@asty.org>
|
||||
* configure.ac: Change extra, multibuffer, color and rcfile configure options to default to enabled
|
||||
--enable-tiny will now disable these options as well
|
||||
* python.nanorc, ruby.nanorc: Add header lines for python and ruby as well
|
||||
|
||||
2008-09-21 Chris Allegretta <chrisa@asty.org>
|
||||
* rcfile.c, color.c, nano.h: Add new capability for matching a syntax type by the "header" (1st line)
|
||||
of a file being edited. Based on Savannah bug 24197 and inital proof of concept by Dave Geering
|
||||
<dgeering@toshiba-tap.com>
|
||||
|
||||
2008-09-16 Chris Allegretta <chrisa@asty.org>
|
||||
* text.c: Add support for undoing a text uncut. Split out the undo and redo of a text cut
|
||||
in order to avoid code duplication.
|
||||
|
||||
2008-09-06 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.c: Do call disable_signals at startup regardless, since under cygwin we can't generate
|
||||
^C without it.
|
||||
|
||||
GNU nano 2.1.5 - 2008.08.30
|
||||
2008-08-29 Chris Allegretta <chrisa@asty.org>
|
||||
* configure.ac, color.c, rcfile.c, utils.c: 1st attempt at supporting systems which don't support
|
||||
GNU-style word boundaries. New function fixbounds() to translate from GNU-style to
|
||||
BSD-style, autoconf option GNU_WORDBOUNDS.
|
||||
* nano-regress: New perl script to check for some of the more obvious issues with compilation
|
||||
issues with certain configure options.
|
||||
* global.c, help.c, browser.c, files.c, proto.h: Fix several compipation and programmatic
|
||||
issues with --disable-help, especially that do-writeout was treating ^G the same as ^M.
|
||||
|
||||
2008-08-28 Chris Allegretta <chrisa@asty.org>
|
||||
* configure.ac, rcfile.c: Add support for an alternate rcfilename at configure time. Maybe this
|
||||
should become a command line option some day, but I don't see the need currently. Start of
|
||||
fix for Savannah bug #24128: Add nanorc support to win32 platform.
|
||||
|
||||
2008-08-21 Chris Allegretta <chrisa@asty.org>
|
||||
* text.c: Change error messages where we may possibly get into a bad state and urge
|
||||
the user to save when this happens. Originally by Benno Schulenberg <bensberg@justemail.net>
|
||||
* text.c (do_enter): Fix issue when compiled with --enable-debug, fixes Savannah bug 24092.
|
||||
|
||||
2008-08-08 Magnus Granberg <zorry@ume.nu> / Adam Conrad <?>
|
||||
* files.c (write_file): Add needed flags to open() calls when writing out files. Fixes Savannah bug
|
||||
#23827: Compilation fails with -D_FORTIFY_SOURCE=2
|
||||
|
||||
2008-08-08 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c (write_file): Check exit code of fclose(), since in certain out of space conditions the OS will
|
||||
happily report successful fwrite()s until you try and close the file. Fix for Savannah bug
|
||||
#24000: no free space on partition - nano claims successful write - file empty
|
||||
|
||||
GNU nano 2.1.4 - 2008.08.09
|
||||
2008-08-08 Chris Allegretta <chrisa@asty.org>
|
||||
* files.c (write_file): Do not go on and attempt to write the main file if writing the backup file failed,
|
||||
related to Savannah bug 24000.
|
||||
* text.c (do_redo): Fix improperly restoring the text when redoing a line split.
|
||||
* text.c (add_undo): Fix check for multi-line cut check skips adding other new legit events.
|
||||
|
||||
2008-07-23 Chris Allegretta <chrisa@asty.org>
|
||||
* text.c: Reset openfile-> to OTHER after an undo or redo so we don't mistakenly
|
||||
mistakenly think this is an update when it's really an add. Also
|
||||
Fix an extra ; after an if statement which makes nano try to free a struct which
|
||||
may be NULL
|
||||
|
||||
GNU nano 2.1.3 - 2008.08.04
|
||||
2008-07-23 Chris Allegretta <chrisa@asty.org>
|
||||
* configure.ac: Add ncursesw dir to include path if lib detected
|
||||
|
||||
2008-07-11 Mike Frysinger <vapier@gentoo.org>
|
||||
* doc/nanorc.sample.in: Include the updates files in the default sample nanorc.
|
||||
|
||||
2008-07-11 Fabian Groffen <grobian@gentoo.org>
|
||||
* nano.c: Don't include langinfo.h if not using ENABLE_UTF8
|
||||
(Savannah patch 6565)
|
||||
|
||||
2008-07-11 Mitsuya Shibata <mty.shibata@gmail.com>
|
||||
* text.c: Fix crashing in help menu when using certain locales
|
||||
(Savannah bug 23751)
|
||||
|
||||
2008-07-09 Chris Allegretta <chrisa@asty.org>
|
||||
* nano.c/nano.h/global.c/text.c: New generalized undo code, currently
|
||||
just works for adding and deleting text and splitting and unsplitting lines.
|
||||
|
||||
2008-06-29 Chris Allegretta <chrisa@asty.org>
|
||||
* global.c: Fix for not having search history when --disable-justify is used
|
||||
(Savannah bug 23733)
|
||||
|
||||
|
||||
GNU nano 2.1.2 - 2008.06.24
|
||||
2008-06-24 Chris Allegretta <chrisa@asty.org>
|
||||
* rcfile.c: Added function check_bad_binding() to look for sequences which
|
||||
|
||||
69
NEWS
69
NEWS
@@ -1,4 +1,61 @@
|
||||
2008/04/24 - GNU nano 2.1.2 "New York City" is released. This release
|
||||
2008.11.10 - GNU nano 2.1.7 "Effingham" is ready to make good on those
|
||||
campaign promises of lower bug rates and 50% more pie.
|
||||
This release includes a new check for external
|
||||
modifications when saving a file, some code and
|
||||
documentation cleanups, and more bug fixes for
|
||||
the new undo code (but we continue to welcome your bug
|
||||
reports via the Savananh bug page at
|
||||
http://savannah.gnu.org/bugs/?func=additem&group=nano.
|
||||
Come get some.
|
||||
|
||||
2008.10.03 - GNU nano 2.1.6 was for new features before it was against
|
||||
them. This release includes more undo capability,
|
||||
several new syntax highlighting configurations including
|
||||
Objective C, OCaml, and Fortran, and a new capability
|
||||
to activate highlighting based on the 1st line of the
|
||||
file being edited. Also, the new default configure
|
||||
options now include color syntax highlighting, .nanorc
|
||||
support, multibuffer and extras. These items can still
|
||||
be disabled and are not enabled with --enable-tiny. Bug
|
||||
fixes include better signal handling under Cygwin, and
|
||||
that's about it. Again please remember to
|
||||
submit bug reports via Savannah at
|
||||
http://savannah.gnu.org/bugs/?func=additem&group=nano
|
||||
as undo functions certainly need more testing.
|
||||
Bon appetit.
|
||||
|
||||
2008.08.30 - GNU nano 2.1.5 is ready to lead on day one. This release
|
||||
contains a better fix for incorrectly reported successful
|
||||
writes on full filesystems, more helpful messages when
|
||||
an internal error occurs in the undo code, and fixes for
|
||||
various combinations of configure-time options and
|
||||
compiler flags. Also included is new support for
|
||||
changing the rc file name at configure time, and
|
||||
using GNU-style regexes for word-boundaries on systems
|
||||
which do not support them natively, as well as the ever
|
||||
popular translation updates. Rock the tarball.
|
||||
|
||||
2008.08.09 - GNU nano 2.1.4 "I told you so!" is released. This release
|
||||
includes fixes for several severe issues with the new
|
||||
undo/redo code. Also the behavior of writing
|
||||
files when using backup mode has changed as well: if writing
|
||||
the backup file fails, nano will not attempt to write the
|
||||
current file. This should help folks who enjoy "extreme
|
||||
text editing" i.e. editing files on file systems which
|
||||
are likely to run out of space; see Savannah bug 24000.
|
||||
Have fun with it!
|
||||
|
||||
2008.08.04 - GNY nano 2.1.3 "least stable version ever" is released. This
|
||||
release includes new (and experimental) undo and redo
|
||||
functionality for most text operations. The default
|
||||
key bindings are Meta-U for undo and Meta-E for redo, but
|
||||
these can be remapped using the new 2.1 keybinding code.
|
||||
Also included are some fixes for configuring using wide
|
||||
curses, crashing when invoking the help menu with
|
||||
certain locales, and not saving the search history when
|
||||
compiled with configure options.
|
||||
|
||||
2008.04.24 - GNU nano 2.1.2 "New York City" is released. This release
|
||||
contains fixes for binding bad keys, some
|
||||
configure-specific compilation failures, and more issues
|
||||
with the new input back end and in particular the status
|
||||
@@ -6,7 +63,7 @@
|
||||
compiling on AIX, and a segfault when making the terminal
|
||||
window too small. Rest in Peace Tim and George!
|
||||
|
||||
2008/04/01 - GNU nano 2.1.1 wont get fooled again. This release contains
|
||||
2008.04.01 - GNU nano 2.1.1 wont get fooled again. This release contains
|
||||
fixes for the new user-rebindable keys (in particular
|
||||
bracket match which was mis-bound), and various
|
||||
problems with translations and configure-related
|
||||
@@ -18,7 +75,7 @@
|
||||
binding code to the Savannah page
|
||||
(https://savannah.gnu.org/bugs/?group=nano).
|
||||
|
||||
2008/03/18 - GNU nano 2.1.0 "under old mismanagement" is released.
|
||||
2008.03.18 - GNU nano 2.1.0 "under old mismanagement" is released.
|
||||
This first release in the 2.1 development series
|
||||
introduces rebinadble keys for most actions inside
|
||||
the editor. Please see the nanorc(5) page for
|
||||
@@ -28,7 +85,7 @@
|
||||
https://savannah.gnu.org/bugs/?group=nano and
|
||||
thanks for sticking with us!
|
||||
|
||||
2007/12/20 - GNU nano 2.0.7 keeps its balance. This release fixes
|
||||
2007.12.20- GNU nano 2.0.7 keeps its balance. This release fixes
|
||||
several bugs, among others: a segfault and several
|
||||
cursor positioning problems when uncutting text or
|
||||
inserting files into the current buffer; a problem where
|
||||
@@ -50,12 +107,12 @@
|
||||
under the GNU GPL version 3 or later and the GNU FDL
|
||||
version 1.2 or later. Have fun.
|
||||
|
||||
2007/04/26 - GNU nano 2.0.6 "that was quick" is released. This release
|
||||
2007.04.26- GNU nano 2.0.6 "that was quick" is released. This release
|
||||
fixes a potential segfault after justifying text marked
|
||||
from the bottom up. It also adds one more minor
|
||||
documentation update. Enjoy.
|
||||
|
||||
2007/04/22 - GNU nano 2.0.5 braces for impact. Among other things, this
|
||||
2007.04.22- GNU nano 2.0.5 braces for impact. Among other things, this
|
||||
release fixes various problems (including a segfault)
|
||||
when trying to open or save a file in a directory
|
||||
beginning with "~" that isn't a home directory; fixes a
|
||||
|
||||
102
configure.ac
102
configure.ac
@@ -20,7 +20,7 @@
|
||||
#
|
||||
# $Id$
|
||||
|
||||
AC_INIT([GNU nano], [2.1.2], [nano-devel@gnu.org], [nano])
|
||||
AC_INIT([GNU nano], [2.1.7], [nano-devel@gnu.org], [nano])
|
||||
AC_CONFIG_SRCDIR([src/nano.c])
|
||||
AC_CANONICAL_TARGET([])
|
||||
AM_INIT_AUTOMAKE
|
||||
@@ -64,12 +64,6 @@ if test x$debug_support != xyes; then
|
||||
AC_DEFINE(NDEBUG, 1, [Shut up assert warnings :-)])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(extra,
|
||||
[ --enable-extra Enable extra features, currently only easter eggs],
|
||||
[if test x$enableval = xyes; then
|
||||
AC_DEFINE(NANO_EXTRA, 1, [Define this to enable extra stuff.]) extra_support=yes
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(tiny,
|
||||
[ --enable-tiny Disable features for the sake of size],
|
||||
[if test x$enableval = xyes; then
|
||||
@@ -84,6 +78,16 @@ AC_ARG_ENABLE(tiny,
|
||||
AC_DEFINE(DISABLE_WRAPPING, 1, [Define this to disable all text wrapping.])
|
||||
fi])
|
||||
|
||||
|
||||
AC_ARG_ENABLE(extra,
|
||||
[ --disable-extra Disable extra features, currently only easter eggs],
|
||||
[if test x$enableval != xno; then
|
||||
AC_DEFINE(NANO_EXTRA, 1, [Define this to enable extra stuff.]) extra_support=yes
|
||||
fi],
|
||||
[if test x$enable_tiny != xyes; then
|
||||
AC_DEFINE(NANO_EXTRA, 1, [Define this to enable extra stuff.]) extra_support=yes
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(browser,
|
||||
[ --disable-browser Disable built-in file browser],
|
||||
[if test x$enableval != xyes; then
|
||||
@@ -139,8 +143,8 @@ AC_ARG_ENABLE(wrapping-as-root,
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(color,
|
||||
[ --enable-color Enable color and syntax highlighting],
|
||||
[if test x$enableval = xyes; then
|
||||
[ --disable-color Disable color and syntax highlighting],
|
||||
[if test x$enableval != xno; then
|
||||
if test x$ac_cv_header_regex_h = xyes; then
|
||||
AC_DEFINE(ENABLE_NANORC, 1, [Define this to use .nanorc files.]) nanorc_support=yes
|
||||
AC_DEFINE(ENABLE_COLOR, 1, [Define this to have syntax highlighting, requires regex.h and ENABLE_NANORC too!]) color_support=yes
|
||||
@@ -148,32 +152,76 @@ AC_ARG_ENABLE(color,
|
||||
AC_MSG_ERROR([
|
||||
*** The header file regex.h was not found. If you wish to use color
|
||||
*** support this header file is required. Please either install C
|
||||
*** libraries that include the regex.h file or do not call the configure
|
||||
*** script with --enable-color.])
|
||||
*** libraries that include the regex.h file or call the configure
|
||||
*** script with --disable-color.])
|
||||
fi
|
||||
fi])
|
||||
fi], [
|
||||
if test x$enable_tiny != xyes; then
|
||||
if test x$ac_cv_header_regex_h = xyes; then
|
||||
AC_DEFINE(ENABLE_NANORC, 1, [Define this to use .nanorc files.]) nanorc_support=yes
|
||||
AC_DEFINE(ENABLE_COLOR, 1, [Define this to have syntax highlighting, requires regex.h and ENABLE_NANORC too!]) color_support=yes
|
||||
else
|
||||
AC_MSG_ERROR([
|
||||
*** The header file regex.h was not found. If you wish to use color
|
||||
*** support this header file is required. Please either install C
|
||||
*** libraries that include the regex.h file or call the configure
|
||||
*** script with --disable-color.])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(multibuffer,
|
||||
[ --enable-multibuffer Enable multiple file buffers],
|
||||
[if test x$enableval = xyes; then
|
||||
[ --disable-multibuffer Disable multiple file buffers],
|
||||
[if test x$enableval != xno; then
|
||||
AC_DEFINE(ENABLE_MULTIBUFFER, 1, [Define this to enable multiple file buffers.]) multibuffer_support=yes
|
||||
fi])
|
||||
fi],
|
||||
[if test x$enable_tiny != xyes; then
|
||||
AC_DEFINE(ENABLE_MULTIBUFFER, 1, [Define this to enable multiple file buffers.]) multibuffer_support=yes
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(nanorc,
|
||||
[ --enable-nanorc Enable use of .nanorc files],
|
||||
[if test x$enableval = xyes; then
|
||||
[ --disable-nanorc Disable use of .nanorc files],
|
||||
[if test x$enableval != xno; then
|
||||
AC_DEFINE(ENABLE_NANORC, 1, [Define this to use .nanorc files.]) nanorc_support=yes
|
||||
fi])
|
||||
fi],
|
||||
[if test x$enable_tiny != xyes; then
|
||||
AC_DEFINE(ENABLE_NANORC, 1, [Define this to use .nanorc files.]) nanorc_support=yes
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(all,
|
||||
[ --enable-all Enable ALL extra nano functionality (kitchen sink option)],
|
||||
[ --enable-all Enable ALL extra nano functionality (ignored for compatibility as all options default to on)],
|
||||
[if test x$enableval = xyes; then
|
||||
AC_DEFINE(ENABLE_NANORC, 1, [Define this to use .nanorc files.]) nanorc_support=yes
|
||||
AC_DEFINE(ENABLE_COLOR, 1, [Define this to have syntax highlighting, requires regex.h and ENABLE_NANORC too!]) color_support=yes
|
||||
AC_DEFINE(ENABLE_MULTIBUFFER, 1, [Define this to enable multiple file buffers.]) multibuffer_support=yes
|
||||
AC_DEFINE(NANO_EXTRA, 1, [Define this to enable extra stuff.]) extra_support=yes
|
||||
echo "--enable-all option no longer needed, ignoring for compatiblity"
|
||||
fi])
|
||||
|
||||
if test x$color_support = xyes; then
|
||||
# now check for the end of word boundary support (/< and />)
|
||||
AC_MSG_CHECKING([for GNU-style word boundary regex support])
|
||||
AC_TRY_RUN([
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <regex.h>
|
||||
int main(void)
|
||||
{
|
||||
regex_t r;
|
||||
size_t nmatch;
|
||||
regmatch_t pmatch;
|
||||
|
||||
if (regcomp(&r, "\\\\>", REG_EXTENDED|REG_NOSUB))
|
||||
return 1;
|
||||
if (regexec(&r, "word boundary", nmatch, &pmatch, 0))
|
||||
return 1;
|
||||
return 0;
|
||||
}],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(GNU_WORDBOUNDS, 1, [Define if the system supports GNU-style word boundaries in regexes.]) gnu_wordbounds=yes,
|
||||
AC_MSG_RESULT(no),
|
||||
AC_MSG_WARN([*** Can't check for gnu word boundary support when cross-compiling])
|
||||
)
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING([whether to enable UTF-8 support])
|
||||
AC_ARG_ENABLE(utf8,
|
||||
[ --enable-utf8 Enable UTF-8 support],
|
||||
@@ -387,6 +435,12 @@ fi
|
||||
AM_CONDITIONAL(USE_COLOR, test x$color_support = xyes)
|
||||
AM_CONDITIONAL(USE_NANORC, test x$nanorc_support = xyes)
|
||||
|
||||
AC_ARG_ENABLE(altrcname,
|
||||
[ --enable-altrcname Specify alternate rcfile name (default: .nanorc)],
|
||||
[if test x$enableval != no; then
|
||||
AC_DEFINE_UNQUOTED(RCFILE_NAME, "$enableval", [Specify alternate rcfile name (default: .nanorc)]) rcfilename=$enableval
|
||||
fi])
|
||||
|
||||
dnl Checks for functions.
|
||||
|
||||
AC_CHECK_FUNCS(getdelim getline isblank strcasecmp strcasestr strncasecmp strnlen vsnprintf)
|
||||
@@ -417,7 +471,7 @@ if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
AC_CHECK_HEADERS(ncurses.h)
|
||||
|
||||
if test x$enable_utf8 != xno; then
|
||||
AC_CHECK_LIB(ncursesw, get_wch, [CURSES_LIB="-lncursesw" CURSES_LIB_NAME=ncursesw CURSES_LIB_WIDE=yes])
|
||||
AC_CHECK_LIB(ncursesw, get_wch, [CURSES_LIB="-lncursesw" CPPFLAGS="-I/usr/include/ncursesw $CPPFLAGS" CURSES_LIB_NAME=ncursesw CURSES_LIB_WIDE=yes])
|
||||
fi
|
||||
|
||||
if eval "test x$CURSES_LIB_NAME = x"; then
|
||||
|
||||
@@ -396,6 +396,12 @@ Count the number of words in the current buffer.
|
||||
.B refresh
|
||||
Refresh the screen.
|
||||
.TP
|
||||
.B undo
|
||||
Undo the text action peformed (add text, delete text, etc).
|
||||
.TP
|
||||
.B redo
|
||||
"Re-do" the last undone action (i.e. undo an undo)
|
||||
.TP
|
||||
.B suspend
|
||||
Suspend the editor (if the suspend function is enabled, see the
|
||||
"suspendenable" entry below).
|
||||
|
||||
@@ -222,6 +222,9 @@
|
||||
# bind M-A casesens search
|
||||
# bind ^S research main
|
||||
|
||||
## Set this if your backspace key sends delete most of the time (2.1.3+)
|
||||
# bind kdel backspace all
|
||||
|
||||
|
||||
## Nanorc files
|
||||
# include "@PKGDATADIR@/nanorc.nanorc"
|
||||
@@ -229,9 +232,24 @@
|
||||
## C/C++
|
||||
# include "@PKGDATADIR@/c.nanorc"
|
||||
|
||||
## Cascading Style Sheets
|
||||
# include "@PKGDATADIR@/css.nanorc"
|
||||
|
||||
## Debian files
|
||||
# include "@PKGDATADIR@/debian.nanorc"
|
||||
|
||||
## Gentoo files
|
||||
# include "@PKGDATADIR@/gentoo.nanorc"
|
||||
|
||||
## HTML
|
||||
# include "@PKGDATADIR@/html.nanorc"
|
||||
|
||||
## PHP
|
||||
# include "@PKGDATADIR@/php.nanorc"
|
||||
|
||||
## TCL
|
||||
# include "@PKGDATADIR@/tcl.nanorc"
|
||||
|
||||
## TeX
|
||||
# include "@PKGDATADIR@/tex.nanorc"
|
||||
|
||||
@@ -259,6 +277,9 @@
|
||||
## Java
|
||||
# include "@PKGDATADIR@/java.nanorc"
|
||||
|
||||
## AWK
|
||||
# include "@PKGDATADIR@/awk.nanorc"
|
||||
|
||||
## Assembler
|
||||
# include "@PKGDATADIR@/asm.nanorc"
|
||||
|
||||
@@ -267,3 +288,6 @@
|
||||
|
||||
## POV-Ray
|
||||
# include "@PKGDATADIR@/pov.nanorc"
|
||||
|
||||
## XML-type files
|
||||
# include "@PKGDATADIR@/xml.nanorc"
|
||||
|
||||
@@ -19,6 +19,9 @@ pkgdata_DATA = asm.nanorc \
|
||||
debian.nanorc \
|
||||
awk.nanorc \
|
||||
css.nanorc \
|
||||
xml.nanorc
|
||||
xml.nanorc \
|
||||
ocaml.nanorc \
|
||||
objc.nanorc \
|
||||
fortran.nanorc
|
||||
|
||||
EXTRA_DIST = $(pkgdata_DATA)
|
||||
|
||||
41
doc/syntax/fortran.nanorc
Normal file
41
doc/syntax/fortran.nanorc
Normal file
@@ -0,0 +1,41 @@
|
||||
## Here is an example for Fortran 90/95
|
||||
|
||||
syntax "fortran" "\.(f|f90|f95)$"
|
||||
|
||||
#color red "\<[A-Z_]a[0-9A-Z_]+\>"
|
||||
color red "\<[0-9]+\>"
|
||||
|
||||
icolor green "\<(action|advance|all|allocatable|allocated|any|apostrophe)\>"
|
||||
icolor green "\<(append|asis|assign|assignment|associated|character|common)\>"
|
||||
icolor green "\<(complex|data|default|delim|dimension|double precision)\>"
|
||||
icolor green "\<(elemental|epsilon|external|file|fmt|form|format|huge)\>"
|
||||
icolor green "\<(implicit|include|index|inquire|integer|intent|interface)\>"
|
||||
icolor green "\<(intrinsic|iostat|kind|logical|module|none|null|only)>"
|
||||
icolor green "\<(operator|optional|pack|parameter|pointer|position|private)\>"
|
||||
icolor green "\<(program|public|real|recl|recursive|selected_int_kind)\>"
|
||||
icolor green "\<(selected_real_kind|subroutine|status)\>"
|
||||
|
||||
icolor cyan "\<(abs|achar|adjustl|adjustr|allocate|bit_size|call|char)\>"
|
||||
icolor cyan "\<(close|contains|count|cpu_time|cshift|date_and_time)\>"
|
||||
icolor cyan "\<(deallocate|digits|dot_product|eor|eoshift|function|iachar)\>"
|
||||
icolor cyan "\<(iand|ibclr|ibits|ibset|ichar|ieor|iolength|ior|ishft|ishftc)\>"
|
||||
icolor cyan "\<(lbound|len|len_trim|matmul|maxexponent|maxloc|maxval|merge)\>"
|
||||
icolor cyan "\<(minexponent|minloc|minval|mvbits|namelist|nearest|nullify)\>"
|
||||
icolor cyan "\<(open|pad|present|print|product|pure|quote|radix)\>"
|
||||
icolor cyan "\<(random_number|random_seed|range|read|readwrite|replace)\>"
|
||||
icolor cyan "\<(reshape|rewind|save|scan|sequence|shape|sign|size|spacing)\>"
|
||||
icolor cyan "\<(spread|sum|system_clock|target|transfer|transpose|trim)\>"
|
||||
icolor cyan "\<(ubound|unpack|verify|write|tiny|type|use|yes)\>"
|
||||
|
||||
icolor yellow "\<(.and.|case|do|else|else?if|else?where|end|end?do|end?if)\>"
|
||||
icolor yellow "\<(end?select|.eqv.|forall|if|lge|lgt|lle|llt|.neqv.|.not.)\>"
|
||||
icolor yellow "\<(.or.|repeat|select case|then|where|while)\>"
|
||||
|
||||
icolor magenta "\<(continue|cycle|exit|go?to|result|return)\>"
|
||||
|
||||
## String highlighting.
|
||||
icolor yellow "<[^= ]*>" ""(\\.|[^"])*""
|
||||
|
||||
## Comment highlighting
|
||||
icolor blue "!.*"
|
||||
|
||||
@@ -5,7 +5,7 @@ syntax "nanorc" "\.?nanorc$"
|
||||
icolor brightwhite "^[[:space:]]*((un)?set|include|syntax|i?color).*$"
|
||||
## Keywords
|
||||
icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(autoindent|backup|backupdir|backwards|boldtext|brackets|casesensitive|const|cut|fill|historylog|matchbrackets|morespace|mouse|multibuffer|noconvert|nofollow|nohelp|nonewlines|nowrap|operatingdir|preserve|punct)\>" "^[[:space:]]*(set|unset)[[:space:]]+(quickblank|quotestr|rebinddelete|rebindkeypad|regexp|smarthome|smooth|speller|suspend|tabsize|tabstospaces|tempfile|view|whitespace|wordbounds)\>"
|
||||
icolor green "^[[:space:]]*(set|unset|include|syntax)\>"
|
||||
icolor green "^[[:space:]]*(set|unset|include|syntax|header)\>"
|
||||
## Colors
|
||||
icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>"
|
||||
icolor magenta "^[[:space:]]*i?color\>" "\<(start|end)="
|
||||
|
||||
41
doc/syntax/objc.nanorc
Normal file
41
doc/syntax/objc.nanorc
Normal file
@@ -0,0 +1,41 @@
|
||||
## Here is an example for C/C++/Obj-C.
|
||||
##
|
||||
syntax "m" "\.m$"
|
||||
|
||||
|
||||
## Stuffs
|
||||
color brightwhite "\<[A-Z_][0-9A-Z_]+\>"
|
||||
color green "\<(float|double|BOOL|bool|char|int|short|long|id|sizeof|enum|void|static|const|struct|union|typedef|extern|(un)?signed|inline)\>"
|
||||
color green "\<[[:alpha:]_][[:alnum:]_]*_t\>"
|
||||
color green "\<(class|namespace|template|public|protected|private|typename|this|friend|virtual|using|mutable|volatile|register|explicit)\>"
|
||||
color brightgreen "\<(for|if|while|do|else|case|default|switch)\>"
|
||||
color brightgreen "\<(try|throw|catch|operator|new|delete)\>"
|
||||
color brightgreen "\<(goto|continue|break|return)\>"
|
||||
color brightgreen "@\<(en(code|d)|i(mplementation|nterface)|selector)\>"
|
||||
##
|
||||
## GCC builtins
|
||||
color cyan "__attribute__[[:space:]]*\(\([^)]*\)\)" "__(aligned|asm|builtin|hidden|inline|packed|restrict|section|typeof|weak)__"
|
||||
|
||||
## Selector/method
|
||||
color brightmagenta "(^|[[:space:]])\[.*[[:space:]].*\]"
|
||||
color white ":[[:alnum:]]*"
|
||||
color magenta "[[:alnum:]]*:"
|
||||
color white "\[[^][:space:]]*\]"
|
||||
|
||||
##
|
||||
## String highlighting. You will in general want your comments and
|
||||
## strings to come last, because syntax highlighting rules will be
|
||||
## applied in the order they are read in.
|
||||
color brightblack "'([^'\]|(\\["'abfnrtv\\]))'" "'\\(([0-3]?[0-7]{1,2}))'" "'\\x[0-9A-Fa-f]{1,2}'"
|
||||
color brightblack "<[^= ]*>" ""(\\.|[^"])*""
|
||||
color brightblue "@"(\\.|[^"])*""
|
||||
##
|
||||
## This string is VERY resource intensive!
|
||||
## color brightyellow start=""(\\.|[^"])*\\[[:space:]]*$" end="^(\\.|[^"])*""
|
||||
|
||||
color brightblue "^[[:space:]]*#[[:space:]]*(define|include|import|(un|ifn?)def|endif|el(if|se)|if|warning|error)"
|
||||
|
||||
## Comment highlighting
|
||||
color yellow "//.*"
|
||||
color yellow start="/\*" end="\*/"
|
||||
|
||||
27
doc/syntax/ocaml.nanorc
Normal file
27
doc/syntax/ocaml.nanorc
Normal file
@@ -0,0 +1,27 @@
|
||||
# OCaml sample nanorc
|
||||
#
|
||||
syntax "ocaml" "\.mli?$"
|
||||
#uid
|
||||
color red "\<[A-Z][0-9a-z_]{2,}\>"
|
||||
#declarations
|
||||
color green "\<(let|val|method|in|and|rec|private|virtual|constraint)\>"
|
||||
#structure items
|
||||
color red "\<(type|open|class|module|exception|external)\>"
|
||||
#patterns
|
||||
color blue "\<(fun|function|functor|match|try|with)\>"
|
||||
#patterns-modifiers
|
||||
color yellow "\<(as|when|of)\>"
|
||||
#conditions
|
||||
color cyan "\<(if|then|else)\>"
|
||||
#blocs
|
||||
color magenta "\<(begin|end|object|struct|sig|for|while|do|done|to|downto)\>"
|
||||
#constantes
|
||||
color green "\<(true|false)\>"
|
||||
#modules/classes
|
||||
color green "\<(include|inherit|initializer)\>"
|
||||
#expr modifiers
|
||||
color yellow "\<(new|ref|mutable|lazy|assert|raise)\>"
|
||||
#comments
|
||||
color white start="\(\*" end="\*\)"
|
||||
#strings (no multiline handling yet)
|
||||
color brightblack ""[^\"]*""
|
||||
@@ -1,6 +1,7 @@
|
||||
## Here is an example for Perl.
|
||||
##
|
||||
syntax "perl" "\.p[lm]$"
|
||||
header "^#!.*/perl[-0-9._]*"
|
||||
color red "\<(accept|alarm|atan2|bin(d|mode)|c(aller|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork))\>" "\<(get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join)\>" "\<(keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek(dir)?)\>" "\<(se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr(y)?|truncate|umask)\>" "\<(un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\>"
|
||||
color magenta "\<(continue|else|elsif|do|for|foreach|if|unless|until|while|eq|ne|lt|gt|le|ge|cmp|x|my|sub|use|package|can|isa)\>"
|
||||
icolor cyan start="[$@%]" end="( |[^0-9A-Z_]|-)"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
## Here is an example for Python.
|
||||
##
|
||||
syntax "python" "\.py$"
|
||||
header "^#!.*/python[-0-9._]*"
|
||||
icolor brightblue "def [0-9A-Z_]+"
|
||||
color brightcyan "\<(and|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|map|not|or|pass|print|raise|return|try|while)\>"
|
||||
color brightcyan "\<(and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield)\>"
|
||||
color brightgreen "['][^']*[^\\][']" "[']{3}.*[^\\][']{3}"
|
||||
color brightgreen "["][^"]*[^\\]["]" "["]{3}.*[^\\]["]{3}"
|
||||
color brightgreen start=""""[^"]" end=""""" start="'''[^']" end="'''"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
## Here is an example for Ruby.
|
||||
##
|
||||
syntax "ruby" "\.rb$"
|
||||
header "^#!.*/ruby[-0-9._]*"
|
||||
## Asciibetical list of reserved words
|
||||
color yellow "\<(BEGIN|END|alias|and|begin|break|case|class|def|defined\?|do|else|elsif|end|ensure|false|for|if|in|module|next|nil|not|or|redo|rescue|retry|return|self|super|then|true|undef|unless|until|when|while|yield)\>"
|
||||
## Constants
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
## Here is an example for Bourne shell scripts.
|
||||
##
|
||||
syntax "sh" "\.sh$"
|
||||
header "^#!.*/(ba|k|pdk|)sh[-0-9_]*"
|
||||
icolor brightgreen "^[0-9A-Z_]+\(\)"
|
||||
color green "\<(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while)\>"
|
||||
color green "(\{|\}|\(|\)|\;|\]|\[|`|\\|\$|<|>|!|=|&|\|)"
|
||||
|
||||
27
nano-regress
Executable file
27
nano-regress
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
|
||||
sub combinations {
|
||||
return [] unless @_;
|
||||
my $first = shift;
|
||||
my @rest = combinations(@_);
|
||||
return @rest, map { [$first, @$_] } @rest;
|
||||
}
|
||||
|
||||
my @allargs=("--enable-debug", "--disable-extra", "--enable-tiny", "--disable-browser --disable-help --disable-mouse --disable-operatingdir --disable-speller", "--disable-multibuffer", "--disable-nanorc", "--with-slang");
|
||||
my @combos = combinations(@allargs);
|
||||
|
||||
my $i = 0;
|
||||
foreach my $name (@combos) {
|
||||
my @args = @$name;
|
||||
my $pct = $i / $#combos * 100;
|
||||
printf "Trying with options: @args, %d%% done...\n", $pct;
|
||||
if (system "(./configure @args && make clean all) >/dev/null 2>&1") {
|
||||
print "Build failed for args: @args\n";
|
||||
print "Try running make to reproduce\n";
|
||||
exit(1);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
print "All options completed successfully!\n";
|
||||
874
po/nano.pot
874
po/nano.pot
File diff suppressed because it is too large
Load Diff
878
po/pt_BR.po
878
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
963
po/zh_CN.po
963
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
853
po/zh_TW.po
853
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -173,8 +173,8 @@ char *do_browser(char *path, DIR *dir)
|
||||
total_redraw();
|
||||
} else if (f->scfunc == do_help_void) {
|
||||
#ifndef DISABLE_HELP
|
||||
do_browser_help();
|
||||
curs_set(0);
|
||||
do_browser_help();
|
||||
curs_set(0);
|
||||
#else
|
||||
nano_disabled_msg();
|
||||
#endif
|
||||
@@ -558,7 +558,9 @@ void parse_browser_input(int *kbinput, bool *meta_key, bool *func_key)
|
||||
*kbinput = sc_seq_or(do_page_up, 0);
|
||||
break;
|
||||
case '?':
|
||||
#ifndef DISABLE_HELP
|
||||
*kbinput = sc_seq_or(do_help_void, 0);
|
||||
#endif
|
||||
break;
|
||||
/* Cancel equivalent to Exit here. */
|
||||
case 'E':
|
||||
|
||||
51
src/color.c
51
src/color.c
@@ -131,7 +131,7 @@ void color_update(void)
|
||||
|
||||
/* If we didn't specify a syntax override string, or if we did and
|
||||
* there was no syntax by that name, get the syntax based on the
|
||||
* file extension. */
|
||||
* file extension, and then look in the header. */
|
||||
if (openfile->colorstrings == NULL) {
|
||||
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||
tmpsyntax = tmpsyntax->next) {
|
||||
@@ -153,7 +153,7 @@ void color_update(void)
|
||||
* already. */
|
||||
if (not_compiled) {
|
||||
e->ext = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(e->ext, e->ext_regex, REG_EXTENDED);
|
||||
regcomp(e->ext, fixbounds(e->ext_regex), REG_EXTENDED);
|
||||
}
|
||||
|
||||
/* Set colorstrings if we matched the extension
|
||||
@@ -174,8 +174,51 @@ void color_update(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we haven't matched anything yet, try the headers */
|
||||
if (openfile->colorstrings == NULL) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "No match for file extensions, looking at headers...\n");
|
||||
#endif
|
||||
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||
tmpsyntax = tmpsyntax->next) {
|
||||
exttype *e;
|
||||
|
||||
for (e = tmpsyntax->headers; e != NULL; e = e->next) {
|
||||
bool not_compiled = (e->ext == NULL);
|
||||
|
||||
/* e->ext_regex has already been checked for validity
|
||||
* elsewhere. Compile its specified regex if we haven't
|
||||
* already. */
|
||||
if (not_compiled) {
|
||||
e->ext = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(e->ext, fixbounds(e->ext_regex), REG_EXTENDED);
|
||||
}
|
||||
|
||||
/* Set colorstrings if we matched the extension
|
||||
* regex. */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Comparing header regex \"%s\" to fileage \"%s\"...\n", e->ext_regex, openfile->fileage->data);
|
||||
#endif
|
||||
if (regexec(e->ext, openfile->fileage->data, 0, NULL, 0) == 0)
|
||||
openfile->colorstrings = tmpsyntax->color;
|
||||
|
||||
if (openfile->colorstrings != NULL)
|
||||
break;
|
||||
|
||||
/* Decompile e->ext_regex's specified regex if we aren't
|
||||
* going to use it. */
|
||||
if (not_compiled) {
|
||||
regfree(e->ext);
|
||||
free(e->ext);
|
||||
e->ext = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If we didn't get a syntax based on the file extension, and we
|
||||
* have a default syntax, use it. */
|
||||
if (openfile->colorstrings == NULL && defcolor != NULL)
|
||||
@@ -188,13 +231,13 @@ void color_update(void)
|
||||
* regexes if we haven't already. */
|
||||
if (tmpcolor->start == NULL) {
|
||||
tmpcolor->start = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(tmpcolor->start, tmpcolor->start_regex,
|
||||
regcomp(tmpcolor->start, fixbounds(tmpcolor->start_regex),
|
||||
REG_EXTENDED | (tmpcolor->icase ? REG_ICASE : 0));
|
||||
}
|
||||
|
||||
if (tmpcolor->end_regex != NULL && tmpcolor->end == NULL) {
|
||||
tmpcolor->end = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(tmpcolor->end, tmpcolor->end_regex,
|
||||
regcomp(tmpcolor->end, fixbounds(tmpcolor->end_regex),
|
||||
REG_EXTENDED | (tmpcolor->icase ? REG_ICASE : 0));
|
||||
}
|
||||
}
|
||||
|
||||
24
src/cut.c
24
src/cut.c
@@ -28,7 +28,6 @@
|
||||
|
||||
static bool keep_cutbuffer = FALSE;
|
||||
/* Should we keep the contents of the cutbuffer? */
|
||||
static filestruct *cutbottom = NULL;
|
||||
/* Pointer to the end of the cutbuffer. */
|
||||
|
||||
/* Indicate that we should no longer keep the contents of the
|
||||
@@ -114,7 +113,7 @@ void cut_to_eof(void)
|
||||
* position to the end of the file into the cutbuffer. */
|
||||
void do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
bool copy_text, bool cut_till_end
|
||||
bool copy_text, bool cut_till_end, bool undoing
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
@@ -163,6 +162,7 @@ void do_cut_text(
|
||||
keep_cutbuffer = TRUE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
|
||||
if (cut_till_end) {
|
||||
/* If cut_till_end is TRUE, move all text up to the end of the
|
||||
* file into the cutbuffer. */
|
||||
@@ -204,12 +204,14 @@ void do_cut_text(
|
||||
* disturbing the text. */
|
||||
if (!old_no_newlines)
|
||||
UNSET(NO_NEWLINES);
|
||||
} else
|
||||
} else if (!undoing)
|
||||
update_undo(CUT);
|
||||
#endif
|
||||
/* Leave the text in the cutbuffer, and mark the file as
|
||||
* modified. */
|
||||
set_modified();
|
||||
|
||||
|
||||
/* Update the screen. */
|
||||
edit_refresh();
|
||||
|
||||
@@ -221,9 +223,12 @@ void do_cut_text(
|
||||
/* Move text from the current filestruct into the cutbuffer. */
|
||||
void do_cut_text_void(void)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
add_undo(CUT);
|
||||
#endif
|
||||
do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
FALSE, FALSE
|
||||
FALSE, FALSE, FALSE
|
||||
#endif
|
||||
);
|
||||
}
|
||||
@@ -233,13 +238,16 @@ void do_cut_text_void(void)
|
||||
* back into the filestruct afterward. */
|
||||
void do_copy_text(void)
|
||||
{
|
||||
do_cut_text(TRUE, FALSE);
|
||||
do_cut_text(TRUE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* Cut from the current cursor position to the end of the file. */
|
||||
void do_cut_till_end(void)
|
||||
{
|
||||
do_cut_text(FALSE, TRUE);
|
||||
#ifndef NANO_TINY
|
||||
add_undo(CUT);
|
||||
#endif
|
||||
do_cut_text(FALSE, TRUE, FALSE);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
@@ -252,6 +260,10 @@ void do_uncut_text(void)
|
||||
if (cutbuffer == NULL)
|
||||
return;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(UNCUT);
|
||||
#endif
|
||||
|
||||
/* Add a copy of the text in the cutbuffer to the current filestruct
|
||||
* at the current cursor position. */
|
||||
copy_from_filestruct(cutbuffer, cutbottom);
|
||||
|
||||
82
src/files.c
82
src/files.c
@@ -75,6 +75,8 @@ void initialize_buffer(void)
|
||||
openfile->fmt = NIX_FILE;
|
||||
|
||||
openfile->current_stat = NULL;
|
||||
openfile->undotop = NULL;
|
||||
openfile->current_undo = NULL;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
openfile->colorstrings = NULL;
|
||||
@@ -99,7 +101,7 @@ void initialize_buffer_text(void)
|
||||
|
||||
/* If it's not "", filename is a file to open. We make a new buffer, if
|
||||
* necessary, and then open and read the file, if applicable. */
|
||||
void open_buffer(const char *filename)
|
||||
void open_buffer(const char *filename, bool undoable)
|
||||
{
|
||||
bool new_buffer = (openfile == NULL
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
@@ -140,7 +142,7 @@ void open_buffer(const char *filename)
|
||||
/* If we have a non-new file, read it in. Then, if the buffer has
|
||||
* no stat, update the stat, if applicable. */
|
||||
if (rc == 0) {
|
||||
read_file(f, filename);
|
||||
read_file(f, filename, undoable);
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->current_stat == NULL) {
|
||||
openfile->current_stat =
|
||||
@@ -190,7 +192,7 @@ void replace_buffer(const char *filename)
|
||||
|
||||
/* If we have a non-new file, read it in. */
|
||||
if (rc == 0)
|
||||
read_file(f, filename);
|
||||
read_file(f, filename, FALSE);
|
||||
|
||||
/* Move back to the beginning of the first line of the buffer. */
|
||||
openfile->current = openfile->fileage;
|
||||
@@ -337,8 +339,9 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
|
||||
}
|
||||
|
||||
/* Read an open file into the current buffer. f should be set to the
|
||||
* open file, and filename should be set to the name of the file. */
|
||||
void read_file(FILE *f, const char *filename)
|
||||
* open file, and filename should be set to the name of the file.
|
||||
undoable means do we want to create undo records to try and undo this */
|
||||
void read_file(FILE *f, const char *filename, bool undoable)
|
||||
{
|
||||
size_t num_lines = 0;
|
||||
/* The number of lines in the file. */
|
||||
@@ -369,6 +372,11 @@ void read_file(FILE *f, const char *filename)
|
||||
buf = charalloc(bufx);
|
||||
buf[0] = '\0';
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (undoable)
|
||||
add_undo(INSERT);
|
||||
#endif
|
||||
|
||||
if (openfile->current == openfile->fileage)
|
||||
first_line_ins = TRUE;
|
||||
else
|
||||
@@ -487,7 +495,7 @@ void read_file(FILE *f, const char *filename)
|
||||
/* If we didn't get a file and we don't already have one, open a
|
||||
* blank buffer. */
|
||||
if (fileptr == NULL)
|
||||
open_buffer("");
|
||||
open_buffer("", FALSE);
|
||||
|
||||
/* Attach the file we got to the filestruct. If we got a file of
|
||||
* zero bytes, don't do anything. */
|
||||
@@ -559,6 +567,9 @@ void read_file(FILE *f, const char *filename)
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (undoable)
|
||||
update_undo(INSERT);
|
||||
|
||||
if (format == 3)
|
||||
statusbar(
|
||||
P_("Read %lu line (Converted from DOS and Mac format)",
|
||||
@@ -851,7 +862,7 @@ void do_insertfile(
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (ISSET(MULTIBUFFER))
|
||||
/* Open a blank buffer. */
|
||||
open_buffer("");
|
||||
open_buffer("", FALSE);
|
||||
#endif
|
||||
|
||||
/* Save the command's output in the current buffer. */
|
||||
@@ -875,7 +886,7 @@ void do_insertfile(
|
||||
|
||||
/* Save the file specified in answer in the current
|
||||
* buffer. */
|
||||
open_buffer(answer);
|
||||
open_buffer(answer, TRUE);
|
||||
#ifndef NANO_TINY
|
||||
}
|
||||
#endif
|
||||
@@ -1463,14 +1474,15 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
free(backuptemp);
|
||||
backuptemp = get_next_filename(backupname, "~");
|
||||
if (*backuptemp == '\0') {
|
||||
statusbar(_("Error writing %s: %s"), backupname,
|
||||
statusbar(_("Error writing backup file %s: %s"), backupname,
|
||||
_("Too many backup files?"));
|
||||
free(backuptemp);
|
||||
free(backupname);
|
||||
/* If we can't write to the backup, go on, since only
|
||||
* saving the original file is better than saving
|
||||
* nothing. */
|
||||
goto skip_backup;
|
||||
/* If we can't write to the backup, DONT go on, since
|
||||
whatever caused the backup file to fail (e.g. disk
|
||||
full may well cause the real file write to fail, which
|
||||
means we could lose both the backup and the original! */
|
||||
goto cleanup_and_exit;
|
||||
} else {
|
||||
free(backupname);
|
||||
backupname = backuptemp;
|
||||
@@ -1487,14 +1499,16 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
|
||||
if (backup_file == NULL || chmod(backupname,
|
||||
openfile->current_stat->st_mode) == -1) {
|
||||
statusbar(_("Error writing %s: %s"), backupname,
|
||||
statusbar(_("Error writing backup file %s: %s"), backupname,
|
||||
strerror(errno));
|
||||
free(backupname);
|
||||
if (backup_file != NULL)
|
||||
fclose(backup_file);
|
||||
/* If we can't write to the backup, go on, since only saving
|
||||
* the original file is better than saving nothing. */
|
||||
goto skip_backup;
|
||||
/* If we can't write to the backup, DONT go on, since
|
||||
whatever caused the backup file to fail (e.g. disk
|
||||
full may well cause the real file write to fail, which
|
||||
means we could lose both the backup and the original! */
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -1514,17 +1528,19 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
strerror(errno));
|
||||
beep();
|
||||
} else
|
||||
statusbar(_("Error writing %s: %s"), backupname,
|
||||
statusbar(_("Error writing backup file %s: %s"), backupname,
|
||||
strerror(errno));
|
||||
/* If we can't read from or write to the backup, go on,
|
||||
* since only saving the original file is better than saving
|
||||
* nothing. */
|
||||
/* If we can't write to the backup, DONT go on, since
|
||||
whatever caused the backup file to fail (e.g. disk
|
||||
full may well cause the real file write to fail, which
|
||||
means we could lose both the backup and the original! */
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
free(backupname);
|
||||
}
|
||||
|
||||
skip_backup:
|
||||
skip_backup:
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* If NOFOLLOW_SYMLINKS is set and the file is a link, we aren't
|
||||
@@ -1572,7 +1588,7 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
}
|
||||
|
||||
if (f_open == NULL) {
|
||||
fd_source = open(realname, O_RDONLY | O_CREAT);
|
||||
fd_source = open(realname, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
|
||||
if (fd_source != -1) {
|
||||
f_source = fdopen(fd_source, "rb");
|
||||
@@ -1691,7 +1707,7 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
int fd_source;
|
||||
FILE *f_source = NULL;
|
||||
|
||||
fd_source = open(tempname, O_RDONLY | O_CREAT);
|
||||
fd_source = open(tempname, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
|
||||
if (fd_source != -1) {
|
||||
f_source = fdopen(fd_source, "rb");
|
||||
@@ -1712,8 +1728,11 @@ bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
} else
|
||||
fclose(f);
|
||||
} else if (fclose(f) != 0) {
|
||||
statusbar(_("Error writing %s: %s"), realname,
|
||||
strerror(errno));
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
|
||||
if (!tmp && append == OVERWRITE) {
|
||||
if (!nonamechange) {
|
||||
@@ -1929,6 +1948,8 @@ bool do_writeout(bool exiting)
|
||||
} else if (s && s->scfunc == (void *) append_msg) {
|
||||
append = (append == APPEND) ? OVERWRITE : APPEND;
|
||||
continue;
|
||||
} else if (s && s->scfunc == do_help_void) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -2007,6 +2028,15 @@ bool do_writeout(bool exiting)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->current_stat && openfile->current_stat->st_mtime < st.st_mtime) {
|
||||
i = do_yesno_prompt(FALSE,
|
||||
_("File was modified since you opened it, continue saving ? "));
|
||||
if (i == 0 || i == -1)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Convert newlines to nulls, just before we save the
|
||||
|
||||
120
src/global.c
120
src/global.c
@@ -1,5 +1,4 @@
|
||||
/* $Id$
|
||||
*/
|
||||
/* $Id$ */
|
||||
/**************************************************************************
|
||||
* global.c *
|
||||
* *
|
||||
@@ -22,11 +21,12 @@
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "assert.h"
|
||||
#include "proto.h"
|
||||
|
||||
/* Global variables. */
|
||||
#ifndef NANO_TINY
|
||||
@@ -69,6 +69,7 @@ int editwinrows = 0;
|
||||
|
||||
filestruct *cutbuffer = NULL;
|
||||
/* The buffer where we store cut text. */
|
||||
filestruct *cutbottom = NULL;
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
filestruct *jusbuffer = NULL;
|
||||
/* The buffer where we store unjustified text. */
|
||||
@@ -150,11 +151,6 @@ const shortcut *currshortcut;
|
||||
int currmenu;
|
||||
/* The currently loaded menu */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
toggle *toggles = NULL;
|
||||
/* The global toggle list. */
|
||||
#endif
|
||||
|
||||
sc *sclist = NULL;
|
||||
/* New shortcut key struct */
|
||||
subnfunc *allfuncs = NULL;
|
||||
@@ -241,7 +237,7 @@ void add_to_funcs(void *func, int menus, const char *desc, const char *help,
|
||||
f->menus = menus;
|
||||
f->desc = desc;
|
||||
f->viewok = viewok;
|
||||
#ifndef NANO_TINY
|
||||
#ifndef DISABLE_HELP
|
||||
f->help = help;
|
||||
f->blank_after = blank_after;
|
||||
#endif
|
||||
@@ -487,6 +483,9 @@ void shortcut_init(bool unjustify)
|
||||
const char *insert_file_msg = N_("Insert File");
|
||||
const char *go_to_line_msg = N_("Go To Line");
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
const char *nano_justify_msg = N_("Justify the current paragraph");
|
||||
#endif
|
||||
#ifndef DISABLE_HELP
|
||||
/* TRANSLATORS: The next long series of strings are shortcut descriptions;
|
||||
* they are best kept shorter than 56 characters, but may be longer. */
|
||||
@@ -501,9 +500,6 @@ void shortcut_init(bool unjustify)
|
||||
;
|
||||
const char *nano_writeout_msg =
|
||||
N_("Write the current file to disk");
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
const char *nano_justify_msg = N_("Justify the current paragraph");
|
||||
#endif
|
||||
const char *nano_insert_msg =
|
||||
N_("Insert another file into the current one");
|
||||
const char *nano_whereis_msg =
|
||||
@@ -528,6 +524,8 @@ void shortcut_init(bool unjustify)
|
||||
N_("Copy the current line and store it in the cutbuffer");
|
||||
const char *nano_indent_msg = N_("Indent the current line");
|
||||
const char *nano_unindent_msg = N_("Unindent the current line");
|
||||
const char *nano_undo_msg = N_("Undo the last operation");
|
||||
const char *nano_redo_msg = N_("Redo the last undone operation");
|
||||
#endif
|
||||
const char *nano_forward_msg = N_("Go forward one character");
|
||||
const char *nano_back_msg = N_("Go back one character");
|
||||
@@ -644,10 +642,8 @@ void shortcut_init(bool unjustify)
|
||||
free(f);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_HELP
|
||||
add_to_funcs(do_help_void, MALL, get_help_msg, nano_help_msg,
|
||||
add_to_funcs(do_help_void, MALL, get_help_msg, IFSCHELP(nano_help_msg),
|
||||
FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs((void *) cancel_msg,
|
||||
(MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MWRITEFILE|MINSERTFILE|MEXTCMD|MSPELL|MWHEREISFILE|MGOTODIR|MYESNO),
|
||||
@@ -698,6 +694,7 @@ void shortcut_init(bool unjustify)
|
||||
add_to_funcs(do_page_down, MMAIN|MHELP,
|
||||
next_page_msg, IFSCHELP(nano_nextpage_msg), TRUE, VIEW);
|
||||
|
||||
|
||||
/* TRANSLATORS: Try to keep this at most 10 characters. */
|
||||
add_to_funcs(do_cut_text_void, MMAIN, N_("Cut Text"), IFSCHELP(nano_cut_msg),
|
||||
FALSE, NOVIEW);
|
||||
@@ -724,7 +721,7 @@ void shortcut_init(bool unjustify)
|
||||
#ifndef DISABLE_SPELLER
|
||||
if (!ISSET(RESTRICTED))
|
||||
/* TRANSLATORS: Try to keep this at most 10 characters. */
|
||||
add_to_funcs(do_spell, MMAIN, N_("To Spell"), nano_spell_msg,
|
||||
add_to_funcs(do_spell, MMAIN, N_("To Spell"), IFSCHELP(nano_spell_msg),
|
||||
TRUE, NOVIEW);
|
||||
#endif
|
||||
|
||||
@@ -759,19 +756,25 @@ void shortcut_init(bool unjustify)
|
||||
#ifndef NANO_TINY
|
||||
|
||||
add_to_funcs(do_mark, MMAIN, N_("Mark Text"),
|
||||
nano_mark_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_mark_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs(do_research, (MMAIN|MBROWSER), whereis_next_msg,
|
||||
nano_whereis_next_msg, TRUE, VIEW);
|
||||
IFSCHELP(nano_whereis_next_msg), TRUE, VIEW);
|
||||
|
||||
add_to_funcs(do_copy_text, MMAIN, N_("Copy Text"),
|
||||
nano_copy_msg, FALSE, NOVIEW);
|
||||
IFSCHELP(nano_copy_msg), FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(do_indent_void, MMAIN, N_("Indent Text"),
|
||||
nano_indent_msg, FALSE, NOVIEW);
|
||||
IFSCHELP(nano_indent_msg), FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(do_unindent, MMAIN, N_("Unindent Text"),
|
||||
nano_unindent_msg, TRUE, NOVIEW);
|
||||
IFSCHELP(nano_unindent_msg), FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(do_undo, MMAIN, N_("Undo"),
|
||||
IFSCHELP(nano_undo_msg), FALSE, NOVIEW);
|
||||
|
||||
add_to_funcs(do_redo, MMAIN, N_("Redo"),
|
||||
IFSCHELP(nano_redo_msg), TRUE, NOVIEW);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -791,10 +794,10 @@ void shortcut_init(bool unjustify)
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_next_word_void, MMAIN, N_("Next Word"),
|
||||
nano_nextword_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_nextword_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs(do_prev_word_void, MMAIN, N_("Prev Word"),
|
||||
nano_prevword_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_prevword_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(do_up_void, (MMAIN|MHELP|MBROWSER), N_("Prev Line"),
|
||||
@@ -811,21 +814,21 @@ void shortcut_init(bool unjustify)
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
add_to_funcs(do_para_begin_void, (MMAIN|MWHEREIS), beg_of_par_msg,
|
||||
nano_parabegin_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_parabegin_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs(do_para_end_void, (MMAIN|MWHEREIS), end_of_par_msg,
|
||||
nano_paraend_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_paraend_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_find_bracket, MMAIN, _("Find Other Bracket"),
|
||||
nano_bracket_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_bracket_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs(do_scroll_up, MMAIN, N_("Scroll Up"),
|
||||
nano_scrollup_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_scrollup_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs(do_scroll_down, MMAIN, N_("Scroll Down"),
|
||||
nano_scrolldown_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_scrolldown_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
@@ -867,7 +870,7 @@ void shortcut_init(bool unjustify)
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_cut_till_end, MMAIN, N_("CutTillEnd"),
|
||||
nano_cut_till_end_msg, TRUE, NOVIEW);
|
||||
IFSCHELP(nano_cut_till_end_msg), TRUE, NOVIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(xon_complaint, MMAIN, "", "", FALSE, VIEW);
|
||||
@@ -875,12 +878,12 @@ void shortcut_init(bool unjustify)
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
add_to_funcs(do_full_justify, (MMAIN|MWHEREIS), fulljstify_msg,
|
||||
nano_fulljustify_msg, FALSE, NOVIEW);
|
||||
IFSCHELP(nano_fulljustify_msg), FALSE, NOVIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_wordlinechar_count, MMAIN, N_("Word Count"),
|
||||
nano_wordcount_msg, FALSE, VIEW);
|
||||
IFSCHELP(nano_wordcount_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs(total_refresh, (MMAIN|MHELP), refresh_msg,
|
||||
@@ -892,11 +895,11 @@ void shortcut_init(bool unjustify)
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs((void *) case_sens_msg,
|
||||
(MWHEREIS|MREPLACE|MWHEREISFILE),
|
||||
case_sens_msg, nano_case_msg, FALSE, VIEW);
|
||||
case_sens_msg, IFSCHELP(nano_case_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs((void *) backwards_msg,
|
||||
(MWHEREIS|MREPLACE|MWHEREISFILE),
|
||||
backwards_msg, nano_reverse_msg, FALSE, VIEW);
|
||||
backwards_msg, IFSCHELP(nano_reverse_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REGEX_H
|
||||
@@ -908,11 +911,11 @@ void shortcut_init(bool unjustify)
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs((void *) prev_history_msg,
|
||||
(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE),
|
||||
prev_history_msg, nano_prev_history_msg, FALSE, VIEW);
|
||||
prev_history_msg, IFSCHELP(nano_prev_history_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs((void *) next_history_msg,
|
||||
(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE),
|
||||
next_history_msg, nano_next_history_msg, FALSE, VIEW);
|
||||
next_history_msg, IFSCHELP(nano_next_history_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs((void *) no_replace_msg, MREPLACE,
|
||||
@@ -925,7 +928,7 @@ void shortcut_init(bool unjustify)
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs((void *) to_files_msg,
|
||||
(MGOTOLINE|MINSERTFILE),
|
||||
to_files_msg, nano_tofiles_msg, FALSE, VIEW);
|
||||
to_files_msg, IFSCHELP(nano_tofiles_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -937,23 +940,23 @@ void shortcut_init(bool unjustify)
|
||||
* backups are disabled. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs((void *) dos_format_msg, MWRITEFILE,
|
||||
dos_format_msg, nano_dos_msg, FALSE, NOVIEW);
|
||||
dos_format_msg, IFSCHELP(nano_dos_msg), FALSE, NOVIEW);
|
||||
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs((void *) mac_format_msg, MWRITEFILE,
|
||||
mac_format_msg, nano_mac_msg, FALSE, NOVIEW);
|
||||
mac_format_msg, IFSCHELP(nano_mac_msg), FALSE, NOVIEW);
|
||||
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs((void *) append_msg, MWRITEFILE,
|
||||
append_msg, nano_append_msg, FALSE, NOVIEW);
|
||||
append_msg, IFSCHELP(nano_append_msg), FALSE, NOVIEW);
|
||||
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs((void *) prepend_msg, MWRITEFILE,
|
||||
prepend_msg, nano_prepend_msg, FALSE, NOVIEW);
|
||||
prepend_msg, IFSCHELP(nano_prepend_msg), FALSE, NOVIEW);
|
||||
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs((void *) backup_file_msg, MWRITEFILE,
|
||||
backup_file_msg, nano_backup_msg, FALSE, NOVIEW);
|
||||
backup_file_msg, IFSCHELP(nano_backup_msg), FALSE, NOVIEW);
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -961,14 +964,14 @@ void shortcut_init(bool unjustify)
|
||||
* It's useless since inserting files is disabled. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs((void *) ext_cmd_msg, MINSERTFILE,
|
||||
ext_cmd_msg, nano_execute_msg, FALSE, NOVIEW);
|
||||
ext_cmd_msg, IFSCHELP(nano_execute_msg), FALSE, NOVIEW);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* If we're using restricted mode, the multibuffer toggle is
|
||||
* disabled. It's useless since inserting files is disabled. */
|
||||
if (!ISSET(RESTRICTED))
|
||||
add_to_funcs((void *) new_buffer_msg, MINSERTFILE,
|
||||
new_buffer_msg, nano_multibuffer_msg, FALSE, NOVIEW);
|
||||
new_buffer_msg, IFSCHELP(nano_multibuffer_msg), FALSE, NOVIEW);
|
||||
#endif
|
||||
|
||||
add_to_funcs((void *) insert_file_msg, MEXTCMD,
|
||||
@@ -976,7 +979,7 @@ void shortcut_init(bool unjustify)
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
add_to_funcs((void *) new_buffer_msg, MEXTCMD,
|
||||
new_buffer_msg, nano_multibuffer_msg, FALSE, NOVIEW);
|
||||
new_buffer_msg, IFSCHELP(nano_multibuffer_msg), FALSE, NOVIEW);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -989,22 +992,20 @@ void shortcut_init(bool unjustify)
|
||||
|
||||
add_to_funcs((void *) first_file_msg,
|
||||
(MBROWSER|MWHEREISFILE),
|
||||
first_file_msg, nano_firstfile_msg, FALSE, VIEW);
|
||||
first_file_msg, IFSCHELP(nano_firstfile_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs((void *) last_file_msg,
|
||||
(MBROWSER|MWHEREISFILE),
|
||||
last_file_msg, nano_lastfile_msg, FALSE, VIEW);
|
||||
last_file_msg, IFSCHELP(nano_lastfile_msg), FALSE, VIEW);
|
||||
|
||||
add_to_funcs((void *) goto_dir_msg, MBROWSER,
|
||||
goto_dir_msg, nano_gotodir_msg, FALSE, VIEW);
|
||||
goto_dir_msg, IFSCHELP(nano_gotodir_msg), FALSE, VIEW);
|
||||
#endif
|
||||
|
||||
currmenu = MMAIN;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MALL, "^G", do_help_void, 0, TRUE);
|
||||
add_to_sclist(MALL, "F1", do_help_void, 0, TRUE);
|
||||
#endif
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", do_exit, 0, TRUE);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", do_exit, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^_", do_gotolinecolumn_void, 0, TRUE);
|
||||
@@ -1044,7 +1045,7 @@ void shortcut_init(bool unjustify)
|
||||
add_to_sclist(MMAIN, "M-R", do_replace, 0, TRUE);
|
||||
add_to_sclist(MWHEREIS, "^R", do_replace, 0, FALSE);
|
||||
add_to_sclist(MREPLACE, "^R", (void *) no_replace_msg, 0, FALSE);
|
||||
add_to_sclist(MWHEREIS, "^T", do_gotolinecolumn_void, 0, TRUE);
|
||||
add_to_sclist(MWHEREIS, "^T", do_gotolinecolumn_void, 0, FALSE);
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MMAIN, "^^", do_mark, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "F15", do_mark, 0, TRUE);
|
||||
@@ -1055,6 +1056,8 @@ void shortcut_init(bool unjustify)
|
||||
add_to_sclist(MMAIN, "M-6", do_copy_text, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-}", do_indent_void, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-{", do_unindent, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-U", do_undo, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "M-E", do_redo, 0, TRUE);
|
||||
add_to_sclist(MALL, "^F", do_right, 0, TRUE);
|
||||
add_to_sclist(MALL, "^B", do_left, 0, TRUE);
|
||||
add_to_sclist(MMAIN, "^Space", do_next_word_void, 0, TRUE);
|
||||
@@ -1072,13 +1075,13 @@ void shortcut_init(bool unjustify)
|
||||
add_to_sclist(MALL, "khome", do_home, 0, TRUE);
|
||||
add_to_sclist(MALL, "^E", do_end, 0, TRUE);
|
||||
add_to_sclist(MALL, "kend", do_end, 0, TRUE);
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "^P", (void *) prev_history_msg, 0, FALSE);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "kup", (void *) prev_history_msg, 0, FALSE);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "^N", (void *) next_history_msg, 0, FALSE);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "kdown", (void *) next_history_msg, 0, FALSE);
|
||||
#endif
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2,
|
||||
"^W", do_para_begin_void, 0, TRUE);
|
||||
add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2,
|
||||
@@ -1333,6 +1336,10 @@ sc *strtosc(int menu, char *input)
|
||||
s->scfunc = do_find_bracket;
|
||||
else if (!strcasecmp(input, "wordcount"))
|
||||
s->scfunc = do_wordlinechar_count;
|
||||
else if (!strcasecmp(input, "undo"))
|
||||
s->scfunc = do_undo;
|
||||
else if (!strcasecmp(input, "redo"))
|
||||
s->scfunc = do_redo;
|
||||
else if (!strcasecmp(input, "prevhistory")) {
|
||||
s->scfunc = (void *) prev_history_msg;
|
||||
s->execute = FALSE;
|
||||
@@ -1436,6 +1443,8 @@ sc *strtosc(int menu, char *input)
|
||||
s->scfunc = do_enter;
|
||||
else if (!strcasecmp(input, "delete"))
|
||||
s->scfunc = do_delete;
|
||||
else if (!strcasecmp(input, "backspace"))
|
||||
s->scfunc = do_backspace;
|
||||
else if (!strcasecmp(input, "refresh"))
|
||||
s->scfunc = total_refresh;
|
||||
else if (!strcasecmp(input, "casesens")) {
|
||||
@@ -1576,15 +1585,6 @@ void thanks_for_all_the_fish(void)
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
if (jusbuffer != NULL)
|
||||
free_filestruct(jusbuffer);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
/* Free the memory associated with each toggle. */
|
||||
while (toggles != NULL) {
|
||||
toggle *t = toggles;
|
||||
|
||||
toggles = toggles->next;
|
||||
free(t);
|
||||
}
|
||||
#endif
|
||||
/* Free the memory associated with each open file buffer. */
|
||||
if (openfile != NULL)
|
||||
|
||||
21
src/help.c
21
src/help.c
@@ -201,12 +201,6 @@ void do_help(void (*refresh_func)(void))
|
||||
help_text = NULL;
|
||||
}
|
||||
|
||||
/* Start the help browser for the edit window. */
|
||||
void do_help_void(void)
|
||||
{
|
||||
do_help(&edit_refresh);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_BROWSER
|
||||
/* Start the help browser for the file browser. */
|
||||
void do_browser_help(void)
|
||||
@@ -552,3 +546,18 @@ size_t help_line_len(const char *ptr)
|
||||
}
|
||||
|
||||
#endif /* !DISABLE_HELP */
|
||||
|
||||
/* Start the help browser for the edit window. */
|
||||
void do_help_void(void)
|
||||
{
|
||||
|
||||
#ifndef DISABLE_HELP
|
||||
/* Start the help browser for the edit window. */
|
||||
do_help(&edit_refresh);
|
||||
#else
|
||||
if (currmenu == MMAIN)
|
||||
nano_disabled_msg();
|
||||
else
|
||||
beep();
|
||||
#endif
|
||||
}
|
||||
|
||||
20
src/nano.c
20
src/nano.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id$ */
|
||||
/**************************************************************************
|
||||
* nano.c *
|
||||
* *
|
||||
@@ -32,7 +32,9 @@
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#ifdef ENABLE_UTF8
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
#include <termios.h>
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
@@ -502,6 +504,9 @@ openfilestruct *make_new_opennode(void)
|
||||
newnode->filebot = NULL;
|
||||
newnode->edittop = NULL;
|
||||
newnode->current = NULL;
|
||||
#ifndef NANO_TINY
|
||||
newnode->last_action = OTHER;
|
||||
#endif
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@@ -1268,7 +1273,6 @@ void disable_extended_io(void)
|
||||
tcsetattr(0, TCSANOW, &term);
|
||||
}
|
||||
|
||||
#ifdef USE_SLANG
|
||||
/* Disable interpretation of the special control keys in our terminal
|
||||
* settings. */
|
||||
void disable_signals(void)
|
||||
@@ -1279,7 +1283,6 @@ void disable_signals(void)
|
||||
term.c_lflag &= ~ISIG;
|
||||
tcsetattr(0, TCSANOW, &term);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Enable interpretation of the special control keys in our terminal
|
||||
@@ -1346,8 +1349,8 @@ void terminal_init(void)
|
||||
if (ISSET(PRESERVE))
|
||||
enable_flow_control();
|
||||
|
||||
#ifdef USE_SLANG
|
||||
disable_signals();
|
||||
#ifdef USE_SLANG
|
||||
if (!ISSET(PRESERVE))
|
||||
disable_flow_control();
|
||||
|
||||
@@ -1642,6 +1645,9 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||
set_modified();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(ADD);
|
||||
|
||||
|
||||
/* Note that current_x has not yet been incremented. */
|
||||
if (openfile->mark_set && openfile->current ==
|
||||
openfile->mark_begin && openfile->current_x <
|
||||
@@ -2224,7 +2230,7 @@ int main(int argc, char **argv)
|
||||
icol == 1)
|
||||
parse_line_column(&argv[i][1], &iline, &icol);
|
||||
else {
|
||||
open_buffer(argv[i]);
|
||||
open_buffer(argv[i], FALSE);
|
||||
|
||||
if (iline > 1 || icol > 1) {
|
||||
do_gotolinecolumn(iline, icol, FALSE, FALSE, FALSE,
|
||||
@@ -2241,14 +2247,14 @@ int main(int argc, char **argv)
|
||||
* buffer or a new buffer, depending on whether multibuffer mode is
|
||||
* enabled. */
|
||||
if (optind < argc)
|
||||
open_buffer(argv[optind]);
|
||||
open_buffer(argv[optind], FALSE);
|
||||
|
||||
/* We didn't open any files if all the command line arguments were
|
||||
* invalid files like directories or if there were no command line
|
||||
* arguments given. In this case, we have to load a blank buffer.
|
||||
* Also, we unset view mode to allow editing. */
|
||||
if (openfile == NULL) {
|
||||
open_buffer("");
|
||||
open_buffer("", FALSE);
|
||||
UNSET(VIEW_MODE);
|
||||
}
|
||||
|
||||
|
||||
67
src/nano.h
67
src/nano.h
@@ -169,6 +169,10 @@ typedef enum {
|
||||
CONTROL, META, FKEY, RAW
|
||||
} function_type;
|
||||
|
||||
typedef enum {
|
||||
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, UNCUT, INSERT, OTHER
|
||||
} undo_type;
|
||||
|
||||
/* Structure types. */
|
||||
typedef struct filestruct {
|
||||
char *data;
|
||||
@@ -238,6 +242,8 @@ typedef struct syntaxtype {
|
||||
/* The name of this syntax. */
|
||||
exttype *extensions;
|
||||
/* The list of extensions that this syntax applies to. */
|
||||
exttype *headers;
|
||||
/* Regexes to match on the 'header' (1st line) of the file */
|
||||
colortype *color;
|
||||
/* The colors used in this syntax. */
|
||||
struct syntaxtype *next;
|
||||
@@ -245,6 +251,38 @@ typedef struct syntaxtype {
|
||||
} syntaxtype;
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct undo {
|
||||
ssize_t lineno;
|
||||
undo_type type;
|
||||
/* What type of undo was this */
|
||||
int begin;
|
||||
/* Where did this action begin or end */
|
||||
char *strdata;
|
||||
/* String type data we will use for ccopying the affected line back */
|
||||
int xflags;
|
||||
/* Some flag data we need */
|
||||
|
||||
/* Cut specific stuff we need */
|
||||
filestruct *cutbuffer;
|
||||
/* Copy of the cutbuffer */
|
||||
filestruct *cutbottom;
|
||||
/* Copy of cutbottom */
|
||||
bool mark_set;
|
||||
/* was the marker set when we cut */
|
||||
bool to_end;
|
||||
/* was this a cut to end */
|
||||
ssize_t mark_begin_lineno;
|
||||
/* copy copy copy */
|
||||
ssize_t mark_begin_x;
|
||||
/* Another shadow variable */
|
||||
struct undo *next;
|
||||
} undo;
|
||||
|
||||
|
||||
#endif /* NANO_TINY */
|
||||
|
||||
|
||||
typedef struct openfilestruct {
|
||||
char *filename;
|
||||
/* The current file's name. */
|
||||
@@ -278,6 +316,11 @@ typedef struct openfilestruct {
|
||||
/* The current file's format. */
|
||||
struct stat *current_stat;
|
||||
/* The current file's stat. */
|
||||
undo *undotop;
|
||||
/* Top of the undo list */
|
||||
undo *current_undo;
|
||||
/* The current (i.e. n ext) level of undo */
|
||||
undo_type last_action;
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
colortype *colorstrings;
|
||||
@@ -318,25 +361,6 @@ typedef struct shortcut {
|
||||
/* Next shortcut. */
|
||||
} shortcut;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct toggle {
|
||||
int val;
|
||||
/* The sequence to toggle the key. We should only need one. */
|
||||
const char *desc;
|
||||
/* The description of the toggle, e.g. "Cut to end"; we'll
|
||||
* append Enabled or Disabled to it. */
|
||||
#ifndef DISABLE_HELP
|
||||
bool blank_after;
|
||||
/* Whether there should be a blank line after the description of
|
||||
* the toggle. */
|
||||
#endif
|
||||
long flag;
|
||||
/* Which flag actually gets toggled. */
|
||||
struct toggle *next;
|
||||
/* Next toggle. */
|
||||
} toggle;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
typedef struct rcoption {
|
||||
const char *name;
|
||||
@@ -667,6 +691,11 @@ typedef struct subnfunc {
|
||||
#define TOGGLE_BACKWARDS_KEY NANO_META_B
|
||||
#define TOGGLE_DOS_KEY NANO_META_D
|
||||
#define TOGGLE_MAC_KEY NANO_META_M
|
||||
|
||||
/* Extra bits for the undo function */
|
||||
#define UNDO_DEL_DEL (1<<0)
|
||||
#define UNDO_DEL_BACKSPACE (1<<1)
|
||||
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#define VIEW TRUE
|
||||
|
||||
26
src/proto.h
26
src/proto.h
@@ -47,6 +47,7 @@ extern WINDOW *bottomwin;
|
||||
extern int editwinrows;
|
||||
|
||||
extern filestruct *cutbuffer;
|
||||
extern filestruct *cutbottom;
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
extern filestruct *jusbuffer;
|
||||
#endif
|
||||
@@ -60,6 +61,7 @@ extern char *matchbrackets;
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
|
||||
extern char *whitespace;
|
||||
extern int whitespace_len[2];
|
||||
extern undo_type last_action;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
@@ -100,9 +102,6 @@ extern char *syntaxstr;
|
||||
|
||||
extern const shortcut *currshortcut;
|
||||
extern int currmenu;
|
||||
#ifndef NANO_TINY
|
||||
extern toggle *toggles;
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern filestruct *search_history;
|
||||
@@ -240,7 +239,7 @@ void cut_to_eof(void);
|
||||
#endif
|
||||
void do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
bool copy_text, bool cut_till_end
|
||||
bool copy_text, bool cut_till_end, bool undoing
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
@@ -256,7 +255,7 @@ void do_uncut_text(void);
|
||||
void make_new_buffer(void);
|
||||
void initialize_buffer(void);
|
||||
void initialize_buffer_text(void);
|
||||
void open_buffer(const char *filename);
|
||||
void open_buffer(const char *filename, bool undoable);
|
||||
#ifndef DISABLE_SPELLER
|
||||
void replace_buffer(const char *filename);
|
||||
#endif
|
||||
@@ -269,7 +268,7 @@ bool close_buffer(void);
|
||||
#endif
|
||||
filestruct *read_line(char *buf, filestruct *prevnode, bool
|
||||
*first_line_ins, size_t buf_len);
|
||||
void read_file(FILE *f, const char *filename);
|
||||
void read_file(FILE *f, const char *filename, bool undoable);
|
||||
int open_file(const char *filename, bool newfie, FILE **f);
|
||||
char *get_next_filename(const char *name, const char *suffix);
|
||||
void do_insertfile(
|
||||
@@ -344,12 +343,12 @@ void thanks_for_all_the_fish(void);
|
||||
#endif
|
||||
|
||||
/* All functions in help.c. */
|
||||
#ifndef DISABLE_HELP
|
||||
void do_help(void (*refresh_func)(void));
|
||||
void do_help_void(void);
|
||||
#ifndef DISABLE_BROWSER
|
||||
void do_browser_help(void);
|
||||
#endif
|
||||
void do_help_void(void);
|
||||
#ifndef DISABLE_HELP
|
||||
void do_help(void (*refresh_func)(void));
|
||||
void help_init(void);
|
||||
void parse_help_input(int *kbinput, bool *meta_key, bool *func_key);
|
||||
size_t help_line_len(const char *ptr);
|
||||
@@ -619,6 +618,8 @@ void do_tab(void);
|
||||
void do_indent(ssize_t cols);
|
||||
void do_indent_void(void);
|
||||
void do_unindent(void);
|
||||
void do_undo(void);
|
||||
void do_redo(void);
|
||||
#endif
|
||||
void do_enter(void);
|
||||
#ifndef NANO_TINY
|
||||
@@ -684,6 +685,7 @@ ssize_t ngetdelim(char **lineptr, size_t *n, int delim, FILE *stream);
|
||||
#endif
|
||||
#ifdef HAVE_REGEX_H
|
||||
bool regexp_bol_or_eol(const regex_t *preg, const char *string);
|
||||
const char *fixbounds(const char *r);
|
||||
#endif
|
||||
#ifndef DISABLE_SPELLER
|
||||
bool is_whole_word(size_t pos, const char *buf, const char *word);
|
||||
@@ -706,8 +708,11 @@ void new_magicline(void);
|
||||
void remove_magicline(void);
|
||||
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
||||
**bot, size_t *bot_x, bool *right_side_up);
|
||||
void add_undo(undo_type current_action);
|
||||
void update_undo(undo_type action);
|
||||
#endif
|
||||
size_t get_totsize(const filestruct *begin, const filestruct *end);
|
||||
filestruct *fsfromline(ssize_t lineno);
|
||||
#ifdef DEBUG
|
||||
void dump_filestruct(const filestruct *inptr);
|
||||
void dump_filestruct_reverse(void);
|
||||
@@ -739,9 +744,6 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
|
||||
const sc *get_shortcut(int menu, int *kbinput, bool
|
||||
*meta_key, bool *func_key);
|
||||
const sc *first_sc_for(int menu, void *func);
|
||||
#ifndef NANO_TINY
|
||||
const toggle *get_toggle(int kbinput, bool meta_key);
|
||||
#endif
|
||||
void blank_line(WINDOW *win, int y, int x, int n);
|
||||
void blank_titlebar(void);
|
||||
void blank_topbar(void);
|
||||
|
||||
88
src/rcfile.c
88
src/rcfile.c
@@ -103,6 +103,8 @@ static char *nanorc = NULL;
|
||||
#ifdef ENABLE_COLOR
|
||||
static syntaxtype *endsyntax = NULL;
|
||||
/* The end of the list of syntaxes. */
|
||||
static exttype *endheader = NULL;
|
||||
/* End of header list */
|
||||
static colortype *endcolor = NULL;
|
||||
/* The end of the color list for the current syntax. */
|
||||
#endif
|
||||
@@ -217,19 +219,19 @@ char *parse_next_regex(char *ptr)
|
||||
bool nregcomp(const char *regex, int eflags)
|
||||
{
|
||||
regex_t preg;
|
||||
int rc = regcomp(&preg, regex, REG_EXTENDED | eflags);
|
||||
const char *r = fixbounds(regex);
|
||||
int rc = regcomp(&preg, r, REG_EXTENDED | eflags);
|
||||
|
||||
if (rc != 0) {
|
||||
size_t len = regerror(rc, &preg, NULL, 0);
|
||||
char *str = charalloc(len);
|
||||
|
||||
regerror(rc, &preg, str, len);
|
||||
rcfile_error(N_("Bad regex \"%s\": %s"), regex, str);
|
||||
rcfile_error(N_("Bad regex \"%s\": %s"), r, str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
regfree(&preg);
|
||||
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
@@ -290,7 +292,9 @@ void parse_syntax(char *ptr)
|
||||
endsyntax->desc = mallocstrcpy(NULL, nameptr);
|
||||
endsyntax->color = NULL;
|
||||
endcolor = NULL;
|
||||
endheader = NULL;
|
||||
endsyntax->extensions = NULL;
|
||||
endsyntax->headers = NULL;
|
||||
endsyntax->next = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -380,7 +384,7 @@ void parse_keybinding(char *ptr)
|
||||
for (i = 0; i < strlen(keycopy); i++)
|
||||
keycopy[i] = toupper(keycopy[i]);
|
||||
|
||||
if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F') {
|
||||
if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F' && keycopy[0] != 'K') {
|
||||
rcfile_error(
|
||||
N_("keybindings must begin with \"^\", \"M\", or \"F\"\n"));
|
||||
return;
|
||||
@@ -423,7 +427,7 @@ void parse_keybinding(char *ptr)
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "newsc now address %d, menu func assigned = %d, menu = %d\n",
|
||||
(int) newsc, (int) newsc->scfunc, menu);
|
||||
&newsc, &newsc->scfunc, menu);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -715,6 +719,69 @@ void parse_colors(char *ptr, bool icase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the headers (1st line) of the file which may influence the regex used. */
|
||||
void parse_headers(char *ptr)
|
||||
{
|
||||
char *regstr;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
if (syntaxes == NULL) {
|
||||
rcfile_error(
|
||||
N_("Cannot add a header regex without a syntax command"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(N_("Missing regex string"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now for the fun part. Start adding regexes to individual strings
|
||||
* in the colorstrings array, woo! */
|
||||
while (ptr != NULL && *ptr != '\0') {
|
||||
exttype *newheader;
|
||||
/* The new color structure. */
|
||||
|
||||
if (*ptr != '"') {
|
||||
rcfile_error(
|
||||
N_("Regex strings must begin and end with a \" character"));
|
||||
ptr = parse_next_regex(ptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
|
||||
regstr = ptr;
|
||||
ptr = parse_next_regex(ptr);
|
||||
if (ptr == NULL)
|
||||
break;
|
||||
|
||||
newheader = (exttype *)nmalloc(sizeof(exttype));
|
||||
|
||||
/* Save the regex string if it's valid */
|
||||
if (nregcomp(regstr, 0)) {
|
||||
newheader->ext_regex = mallocstrcpy(NULL, regstr);
|
||||
newheader->ext = NULL;
|
||||
newheader->next = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting a new header entry: %s\n", newheader->ext_regex);
|
||||
#endif
|
||||
|
||||
if (endheader == NULL) {
|
||||
endsyntax->headers = newheader;
|
||||
} else {
|
||||
endheader->next = newheader;
|
||||
}
|
||||
|
||||
endheader = newheader;
|
||||
} else
|
||||
free(newheader);
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* Check whether the user has unmapped every shortcut for a
|
||||
@@ -812,7 +879,9 @@ void parse_rcfile(FILE *rcstream
|
||||
rcfile_error(N_("Syntax \"%s\" has no color commands"),
|
||||
endsyntax->desc);
|
||||
parse_syntax(ptr);
|
||||
} else if (strcasecmp(keyword, "color") == 0)
|
||||
} else if (strcasecmp(keyword, "header") == 0)
|
||||
parse_headers(ptr);
|
||||
else if (strcasecmp(keyword, "color") == 0)
|
||||
parse_colors(ptr, FALSE);
|
||||
else if (strcasecmp(keyword, "icolor") == 0)
|
||||
parse_colors(ptr, TRUE);
|
||||
@@ -1044,8 +1113,11 @@ void do_rcfile(void)
|
||||
if (homedir == NULL)
|
||||
rcfile_error(N_("I can't find my home directory! Wah!"));
|
||||
else {
|
||||
nanorc = charealloc(nanorc, strlen(homedir) + 9);
|
||||
sprintf(nanorc, "%s/.nanorc", homedir);
|
||||
#ifndef RCFILE_NAME
|
||||
#define RCFILE_NAME ".nanorc"
|
||||
#endif
|
||||
nanorc = charealloc(nanorc, strlen(homedir) + strlen(RCFILE_NAME) + 2);
|
||||
sprintf(nanorc, "%s/%s", homedir, RCFILE_NAME);
|
||||
|
||||
/* Don't open directories, character files, or block files. */
|
||||
if (stat(nanorc, &rcinfo) != -1) {
|
||||
|
||||
@@ -254,12 +254,13 @@ int search_init(bool replacing, bool use_answer)
|
||||
func == (void *) no_replace_msg) {
|
||||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return -2; /* Call the opposite search function. */
|
||||
} else if (func == (void *) go_to_line_msg) {
|
||||
} else if (func == do_gotolinecolumn_void) {
|
||||
do_gotolinecolumn(openfile->current->lineno,
|
||||
openfile->placewewant + 1, TRUE, TRUE, FALSE,
|
||||
TRUE);
|
||||
/* Put answer up on the statusbar and
|
||||
* fall through. */
|
||||
return 3;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -788,6 +789,9 @@ ssize_t do_replace_loop(
|
||||
char *copy;
|
||||
size_t length_change;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(REPLACE);
|
||||
#endif
|
||||
if (i == 2)
|
||||
replaceall = TRUE;
|
||||
|
||||
|
||||
541
src/text.c
541
src/text.c
@@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id$ */
|
||||
/**************************************************************************
|
||||
* text.c *
|
||||
* *
|
||||
@@ -70,6 +70,10 @@ void do_delete(void)
|
||||
/* Do we have to call edit_refresh(), or can we get away with
|
||||
* just update_line()? */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(DEL);
|
||||
#endif
|
||||
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL && openfile->current_x <= strlen(openfile->current->data));
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
@@ -359,6 +363,299 @@ void do_unindent(void)
|
||||
{
|
||||
do_indent(-tabsize);
|
||||
}
|
||||
|
||||
/* undo a cut, or re-do an uncut */
|
||||
void undo_cut(undo *u)
|
||||
{
|
||||
cutbuffer = copy_filestruct(u->cutbuffer);
|
||||
|
||||
/* Compute cutbottom for the uncut using out copy */
|
||||
for (cutbottom = cutbuffer; cutbottom->next != NULL; cutbottom = cutbottom->next)
|
||||
;
|
||||
|
||||
/* Get to where we need to uncut from */
|
||||
if (u->mark_set && u->mark_begin_lineno < u->lineno)
|
||||
do_gotolinecolumn(u->mark_begin_lineno, u->mark_begin_x+1, FALSE, FALSE, FALSE, FALSE);
|
||||
else
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
|
||||
copy_from_filestruct(cutbuffer, cutbottom);
|
||||
free_filestruct(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
|
||||
}
|
||||
|
||||
/* Re-do a cut, or undo an uncut */
|
||||
void redo_cut(undo *u) {
|
||||
int i;
|
||||
filestruct *t, *c;
|
||||
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
openfile->mark_set = u->mark_set;
|
||||
if (cutbuffer)
|
||||
free(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
|
||||
/* Move ahead the same # lines we had if a marked cut */
|
||||
if (u->mark_set) {
|
||||
for (i = 1, t = openfile->fileage; i != u->mark_begin_lineno; i++)
|
||||
t = t->next;
|
||||
openfile->mark_begin = t;
|
||||
} else if (!u->to_end) {
|
||||
/* Here we have a regular old potentially multi-line ^K cut. We'll
|
||||
need to trick nano into thinking it's a marked cut to cut more
|
||||
than one line again */
|
||||
for (c = u->cutbuffer, t = openfile->current; c->next != NULL && t->next != NULL; ) {
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Advancing, lineno = %d, data = \"%s\"\n", t->lineno, t->data);
|
||||
#endif
|
||||
c = c->next;
|
||||
t = t->next;
|
||||
}
|
||||
openfile->mark_begin = t;
|
||||
openfile->mark_begin_x = 0;
|
||||
openfile->mark_set = TRUE;
|
||||
}
|
||||
|
||||
openfile->mark_begin_x = u->mark_begin_x;
|
||||
do_cut_text(FALSE, u->to_end, TRUE);
|
||||
openfile->mark_set = FALSE;
|
||||
openfile->mark_begin = NULL;
|
||||
openfile->mark_begin_x = 0;
|
||||
edit_refresh();
|
||||
}
|
||||
|
||||
/* Undo the last thing(s) we did */
|
||||
void do_undo(void)
|
||||
{
|
||||
undo *u = openfile->current_undo;
|
||||
filestruct *f = openfile->current, *t;
|
||||
int len = 0;
|
||||
char *undidmsg, *data;
|
||||
filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom;
|
||||
|
||||
if (!u) {
|
||||
statusbar(_("Nothing in undo buffer!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (u->lineno <= f->lineno)
|
||||
for (; f->prev != NULL && f->lineno != u->lineno; f = f->prev)
|
||||
;
|
||||
else
|
||||
for (; f->next != NULL && f->lineno != u->lineno; f = f->next)
|
||||
;
|
||||
if (f->lineno != u->lineno) {
|
||||
statusbar(_("Internal error: can't match line %d. Please save your work"), u->lineno);
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "data we're about to undo = \"%s\"\n", f->data);
|
||||
fprintf(stderr, "Undo running for type %d\n", u->type);
|
||||
#endif
|
||||
|
||||
openfile->current_x = u->begin;
|
||||
switch(u->type) {
|
||||
case ADD:
|
||||
undidmsg = _("text add");
|
||||
len = strlen(f->data) - strlen(u->strdata) + 1;
|
||||
data = charalloc(len);
|
||||
strncpy(data, f->data, u->begin);
|
||||
strcpy(&data[u->begin], &f->data[u->begin + strlen(u->strdata)]);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
break;
|
||||
case DEL:
|
||||
undidmsg = _("text delete");
|
||||
len = strlen(f->data) + strlen(u->strdata) + 1;
|
||||
data = charalloc(len);
|
||||
|
||||
strncpy(data, f->data, u->begin);
|
||||
strcpy(&data[u->begin], u->strdata);
|
||||
strcpy(&data[u->begin + strlen(u->strdata)], &f->data[u->begin]);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
if (u->xflags == UNDO_DEL_BACKSPACE)
|
||||
openfile->current_x += strlen(u->strdata);
|
||||
break;
|
||||
case SPLIT:
|
||||
undidmsg = _("line split");
|
||||
free(f->data);
|
||||
f->data = mallocstrcpy(NULL, u->strdata);
|
||||
if (f->next != NULL) {
|
||||
filestruct *tmp = f->next;
|
||||
unlink_node(tmp);
|
||||
delete_node(tmp);
|
||||
}
|
||||
renumber(f);
|
||||
break;
|
||||
case UNSPLIT:
|
||||
undidmsg = _("line join");
|
||||
t = make_new_node(f);
|
||||
t->data = mallocstrcpy(NULL, u->strdata);
|
||||
data = mallocstrncpy(NULL, f->data, u->begin);
|
||||
data[u->begin] = '\0';
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
splice_node(f, t, f->next);
|
||||
renumber(f);
|
||||
break;
|
||||
case CUT:
|
||||
undidmsg = _("text cut");
|
||||
undo_cut(u);
|
||||
break;
|
||||
case UNCUT:
|
||||
undidmsg = _("text uncut");
|
||||
redo_cut(u);
|
||||
break;
|
||||
case INSERT:
|
||||
undidmsg = _("text insert");
|
||||
cutbuffer = NULL;
|
||||
cutbottom = NULL;
|
||||
/* When we updated mark_begin_lineno in update_undo, it was effectively how many line
|
||||
were inserted due to being partitioned before read_file was called. So we
|
||||
add its value here */
|
||||
openfile->mark_begin = fsfromline(u->lineno + u->mark_begin_lineno - 1);
|
||||
openfile->mark_begin_x = 0;
|
||||
openfile->mark_set = TRUE;
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
cut_marked();
|
||||
u->cutbuffer = cutbuffer;
|
||||
u->cutbottom = cutbottom;
|
||||
cutbuffer = oldcutbuffer;
|
||||
cutbottom = oldcutbottom;
|
||||
openfile->mark_set = FALSE;
|
||||
break;
|
||||
case REPLACE:
|
||||
undidmsg = _("text replace");
|
||||
data = u->strdata;
|
||||
u->strdata = f->data;
|
||||
f->data = data;
|
||||
break;
|
||||
default:
|
||||
undidmsg = _("Internal error: unknown type. Please save your work");
|
||||
break;
|
||||
|
||||
}
|
||||
do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
|
||||
statusbar(_("Undid action (%s)"), undidmsg);
|
||||
openfile->current_undo = openfile->current_undo->next;
|
||||
openfile->last_action = OTHER;
|
||||
}
|
||||
|
||||
void do_redo(void)
|
||||
{
|
||||
undo *u = openfile->undotop;
|
||||
filestruct *f = openfile->current, *t;
|
||||
int len = 0;
|
||||
char *undidmsg, *data;
|
||||
|
||||
for (; u != NULL && u->next != openfile->current_undo; u = u->next)
|
||||
;
|
||||
if (!u) {
|
||||
statusbar(_("Nothing to re-do!"));
|
||||
return;
|
||||
}
|
||||
if (u->next != openfile->current_undo) {
|
||||
statusbar(_("Internal error: Redo setup failed. Please save your work"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->lineno <= f->lineno)
|
||||
for (; f->prev != NULL && f->lineno != u->lineno; f = f->prev)
|
||||
;
|
||||
else
|
||||
for (; f->next != NULL && f->lineno != u->lineno; f = f->next)
|
||||
;
|
||||
if (f->lineno != u->lineno) {
|
||||
statusbar(_("Internal error: can't match line %d. Please save your work"), u->lineno);
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "data we're about to redo = \"%s\"\n", f->data);
|
||||
fprintf(stderr, "Redo running for type %d\n", u->type);
|
||||
#endif
|
||||
|
||||
switch(u->type) {
|
||||
case ADD:
|
||||
undidmsg = _("text add");
|
||||
len = strlen(f->data) + strlen(u->strdata) + 1;
|
||||
data = charalloc(len);
|
||||
strncpy(data, f->data, u->begin);
|
||||
strcpy(&data[u->begin], u->strdata);
|
||||
strcpy(&data[u->begin + strlen(u->strdata)], &f->data[u->begin]);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
break;
|
||||
case DEL:
|
||||
undidmsg = _("text delete");
|
||||
len = strlen(f->data) + strlen(u->strdata) + 1;
|
||||
data = charalloc(len);
|
||||
strncpy(data, f->data, u->begin);
|
||||
strcpy(&data[u->begin], &f->data[u->begin + strlen(u->strdata)]);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
break;
|
||||
case SPLIT:
|
||||
undidmsg = _("line split");
|
||||
t = make_new_node(f);
|
||||
t->data = mallocstrcpy(NULL, &u->strdata[u->begin]);
|
||||
data = mallocstrncpy(NULL, f->data, u->begin);
|
||||
data[u->begin] = '\0';
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
splice_node(f, t, f->next);
|
||||
renumber(f);
|
||||
break;
|
||||
case UNSPLIT:
|
||||
undidmsg = _("line join");
|
||||
len = strlen(f->data) + strlen(u->strdata + 1);
|
||||
data = charalloc(len);
|
||||
strcpy(data, f->data);
|
||||
strcat(data, u->strdata);
|
||||
free(f->data);
|
||||
f->data = data;
|
||||
if (f->next != NULL) {
|
||||
filestruct *tmp = f->next;
|
||||
unlink_node(tmp);
|
||||
delete_node(tmp);
|
||||
}
|
||||
renumber(f);
|
||||
break;
|
||||
case CUT:
|
||||
undidmsg = _("text cut");
|
||||
redo_cut(u);
|
||||
break;
|
||||
case UNCUT:
|
||||
undidmsg = _("text uncut");
|
||||
undo_cut(u);
|
||||
break;
|
||||
case REPLACE:
|
||||
undidmsg = _("text replace");
|
||||
data = u->strdata;
|
||||
u->strdata = f->data;
|
||||
f->data = data;
|
||||
break;
|
||||
case INSERT:
|
||||
undidmsg = _("text insert");
|
||||
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
|
||||
copy_from_filestruct(u->cutbuffer, u->cutbottom);
|
||||
openfile->placewewant = xplustabs();
|
||||
break;
|
||||
default:
|
||||
undidmsg = _("Internal error: unknown type. Please save your work");
|
||||
break;
|
||||
|
||||
}
|
||||
do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
|
||||
statusbar(_("Redid action (%s)"), undidmsg);
|
||||
|
||||
openfile->current_undo = u;
|
||||
openfile->last_action = OTHER;
|
||||
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Someone hits Enter *gasp!* */
|
||||
@@ -370,6 +667,9 @@ void do_enter(void)
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
update_undo(SPLIT);
|
||||
|
||||
|
||||
/* Do auto-indenting, like the neolithic Turbo Pascal editor. */
|
||||
if (ISSET(AUTOINDENT)) {
|
||||
/* If we are breaking the line in the indentation, the new
|
||||
@@ -495,7 +795,7 @@ bool execute_command(const char *command)
|
||||
if (f == NULL)
|
||||
nperror("fdopen");
|
||||
|
||||
read_file(f, "stdin");
|
||||
read_file(f, "stdin", TRUE);
|
||||
|
||||
if (wait(NULL) == -1)
|
||||
nperror("wait");
|
||||
@@ -510,6 +810,233 @@ bool execute_command(const char *command)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Add a new undo struct to the top of the current pile */
|
||||
void add_undo(undo_type current_action)
|
||||
{
|
||||
undo *u;
|
||||
char *data;
|
||||
openfilestruct *fs = openfile;
|
||||
static undo *last_cutu = NULL; /* Last thing we cut to set up the undo for uncut */
|
||||
|
||||
/* Ugh, if we were called while cutting not-to-end, non-marked and on the same lineno,
|
||||
we need to abort here */
|
||||
u = fs->current_undo;
|
||||
if (current_action == CUT && u && u->type == CUT
|
||||
&& !u->mark_set && u->lineno == fs->current->lineno)
|
||||
return;
|
||||
|
||||
/* Blow away the old undo stack if we are starting from the middle */
|
||||
while (fs->undotop != NULL && fs->undotop != fs->current_undo) {
|
||||
undo *u2 = fs->undotop;
|
||||
fs->undotop = fs->undotop->next;
|
||||
if (u2->strdata != NULL)
|
||||
free(u2->strdata);
|
||||
if (u2->cutbuffer)
|
||||
free_filestruct(u2->cutbuffer);
|
||||
free(u2);
|
||||
}
|
||||
|
||||
/* Allocate and initialize a new undo type */
|
||||
u = nmalloc(sizeof(undo));
|
||||
u->type = current_action;
|
||||
u->lineno = fs->current->lineno;
|
||||
u->begin = fs->current_x;
|
||||
u->next = fs->undotop;
|
||||
fs->undotop = u;
|
||||
fs->current_undo = u;
|
||||
u->strdata = NULL;
|
||||
u->cutbuffer = NULL;
|
||||
u->cutbottom = NULL;
|
||||
u->mark_set = 0;
|
||||
u->mark_begin_lineno = 0;
|
||||
u->mark_begin_x = 0;
|
||||
u->xflags = 0;
|
||||
u->to_end = FALSE;
|
||||
|
||||
switch (u->type) {
|
||||
/* We need to start copying data into the undo buffer or we wont be able
|
||||
to restore it later */
|
||||
case ADD:
|
||||
data = charalloc(2);
|
||||
data[0] = fs->current->data[fs->current_x];
|
||||
data[1] = '\0';
|
||||
u->strdata = data;
|
||||
break;
|
||||
case DEL:
|
||||
if (u->begin != strlen(fs->current->data)) {
|
||||
data = mallocstrncpy(NULL, &fs->current->data[u->begin], 2);
|
||||
data[1] = '\0';
|
||||
u->strdata = data;
|
||||
break;
|
||||
}
|
||||
/* Else purposely fall into unsplit code */
|
||||
current_action = u->type = UNSPLIT;
|
||||
case UNSPLIT:
|
||||
if (fs->current->next) {
|
||||
data = mallocstrcpy(NULL, fs->current->next->data);
|
||||
u->strdata = data;
|
||||
}
|
||||
break;
|
||||
case INSERT:
|
||||
case SPLIT:
|
||||
case REPLACE:
|
||||
data = mallocstrcpy(NULL, fs->current->data);
|
||||
u->strdata = data;
|
||||
break;
|
||||
case CUT:
|
||||
u->mark_set = openfile->mark_set;
|
||||
if (u->mark_set) {
|
||||
u->mark_begin_lineno = openfile->mark_begin->lineno;
|
||||
u->mark_begin_x = openfile->mark_begin_x;
|
||||
}
|
||||
u->to_end = (ISSET(CUT_TO_END)) ? TRUE : FALSE;
|
||||
last_cutu = u;
|
||||
break;
|
||||
case UNCUT:
|
||||
if (!last_cutu)
|
||||
statusbar(_("Internal error: can't setup uncut. Please save your work."));
|
||||
else if (last_cutu->type == CUT) {
|
||||
u->cutbuffer = last_cutu->cutbuffer;
|
||||
u->cutbottom = last_cutu->cutbottom;
|
||||
}
|
||||
break;
|
||||
case OTHER:
|
||||
statusbar(_("Internal error: unknown type. Please save your work."));
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "fs->current->data = \"%s\", current_x = %d, u->begin = %d, type = %d\n",
|
||||
fs->current->data, fs->current_x, u->begin, current_action);
|
||||
fprintf(stderr, "left update_add...\n");
|
||||
#endif
|
||||
fs->last_action = current_action;
|
||||
}
|
||||
|
||||
/* Update an undo item, or determine whether a new one
|
||||
is really needed and bounce the data to add_undo
|
||||
instead. The latter functionality just feels
|
||||
gimmicky and may just be more hassle than
|
||||
it's worth, so it should be axed if needed. */
|
||||
void update_undo(undo_type action)
|
||||
{
|
||||
undo *u;
|
||||
char *data;
|
||||
int len = 0;
|
||||
openfilestruct *fs = openfile;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "action = %d, fs->last_action = %d, openfile->current->lineno = %d",
|
||||
action, fs->last_action, openfile->current->lineno);
|
||||
if (fs->current_undo)
|
||||
fprintf(stderr, "fs->current_undo->lineno = %d\n", fs->current_undo->lineno);
|
||||
else
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
/* Change to an add if we're not using the same undo struct
|
||||
that we should be using */
|
||||
if (action != fs->last_action
|
||||
|| (action != CUT && action != INSERT
|
||||
&& openfile->current->lineno != fs->current_undo->lineno)) {
|
||||
add_undo(action);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(fs->undotop != NULL);
|
||||
u = fs->undotop;
|
||||
|
||||
switch (u->type) {
|
||||
case ADD:
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "fs->current->data = \"%s\", current_x = %d, u->begin = %d\n",
|
||||
fs->current->data, fs->current_x, u->begin);
|
||||
#endif
|
||||
len = strlen(u->strdata) + 2;
|
||||
data = nrealloc((void *) u->strdata, len * sizeof(char *));
|
||||
data[len-2] = fs->current->data[fs->current_x];
|
||||
data[len-1] = '\0';
|
||||
u->strdata = (char *) data;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "current undo data now \"%s\"\n", u->strdata);
|
||||
#endif
|
||||
break;
|
||||
case DEL:
|
||||
len = strlen(u->strdata) + 2;
|
||||
assert(len > 2);
|
||||
if (fs->current_x == u->begin) {
|
||||
/* They're deleting */
|
||||
if (!u->xflags)
|
||||
u->xflags = UNDO_DEL_DEL;
|
||||
else if (u->xflags != UNDO_DEL_DEL) {
|
||||
add_undo(action);
|
||||
return;
|
||||
}
|
||||
data = charalloc(len);
|
||||
strcpy(data, u->strdata);
|
||||
data[len-2] = fs->current->data[fs->current_x];;
|
||||
data[len-1] = '\0';
|
||||
free(u->strdata);
|
||||
u->strdata = data;
|
||||
} else if (fs->current_x == u->begin - 1) {
|
||||
/* They're backspacing */
|
||||
if (!u->xflags)
|
||||
u->xflags = UNDO_DEL_BACKSPACE;
|
||||
else if (u->xflags != UNDO_DEL_BACKSPACE) {
|
||||
add_undo(action);
|
||||
return;
|
||||
}
|
||||
data = charalloc(len);
|
||||
data[0] = fs->current->data[fs->current_x];
|
||||
strcpy(&data[1], u->strdata);
|
||||
free(u->strdata);
|
||||
u->strdata = data;
|
||||
u->begin--;
|
||||
} else {
|
||||
/* They deleted something else on the line */
|
||||
add_undo(DEL);
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "current undo data now \"%s\"\nu->begin = %d\n", u->strdata, u->begin);
|
||||
#endif
|
||||
break;
|
||||
case CUT:
|
||||
if (!cutbuffer)
|
||||
break;
|
||||
if (u->cutbuffer)
|
||||
free(u->cutbuffer);
|
||||
u->cutbuffer = copy_filestruct(cutbuffer);
|
||||
/* Compute cutbottom for the uncut using out copy */
|
||||
for (u->cutbottom = u->cutbuffer; u->cutbottom->next != NULL; u->cutbottom = u->cutbottom->next)
|
||||
;
|
||||
break;
|
||||
case REPLACE:
|
||||
case UNCUT:
|
||||
add_undo(action);
|
||||
break;
|
||||
case INSERT:
|
||||
u->mark_begin_lineno = openfile->current->lineno;
|
||||
case SPLIT:
|
||||
case UNSPLIT:
|
||||
/* These cases are handled by the earlier check for a new line and action */
|
||||
case OTHER:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Done in udpate_undo (type was %d)\n", action);
|
||||
#endif
|
||||
if (fs->last_action != action) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting add_undo for new action as it does not match last_action\n");
|
||||
#endif
|
||||
add_undo(action);
|
||||
}
|
||||
fs->last_action = action;
|
||||
}
|
||||
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#ifndef DISABLE_WRAPPING
|
||||
@@ -800,6 +1327,15 @@ ssize_t break_line(const char *line, ssize_t goal
|
||||
/* In fact, the whole line displays shorter than goal. */
|
||||
return cur_loc;
|
||||
|
||||
#ifndef DISABLE_HELP
|
||||
if (newln && blank_loc <= 0) {
|
||||
/* If blank was not found or was found only first character,
|
||||
* force line break. */
|
||||
cur_loc -= line_len;
|
||||
return cur_loc;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (blank_loc == -1) {
|
||||
/* No blank was found that was short enough. */
|
||||
bool found_blank = FALSE;
|
||||
@@ -2464,3 +3000,4 @@ void do_verbatim_input(void)
|
||||
|
||||
free(output);
|
||||
}
|
||||
|
||||
|
||||
53
src/utils.c
53
src/utils.c
@@ -253,6 +253,42 @@ bool regexp_bol_or_eol(const regex_t *preg, const char *string)
|
||||
regexec(preg, string, 0, NULL, REG_NOTBOL | REG_NOTEOL) ==
|
||||
REG_NOMATCH);
|
||||
}
|
||||
|
||||
/* Fix the regex if we're on platforms which requires an adjustment
|
||||
* from GNU-style to BSD-style word boundaries. */
|
||||
const char *fixbounds(const char *r) {
|
||||
#ifndef GNU_WORDBOUNDS
|
||||
int i, j = 0;
|
||||
char *r2 = charalloc(strlen(r) * 5);
|
||||
char *r3;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "fixbounds(): Start string = \"%s\"\n", r);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < strlen(r); i++) {
|
||||
if (r[i] != '\0' && r[i] == '\\' && (r[i+1] == '>' || r[i+1] == '<')) {
|
||||
strcpy(&r2[j], "[[:");
|
||||
r2[j+3] = r[i+1];
|
||||
strcpy(&r2[j+4], ":]]");
|
||||
i++;
|
||||
j += 6;
|
||||
} else
|
||||
r2[j] = r[i];
|
||||
j++;
|
||||
}
|
||||
r2[j] = '\0';
|
||||
r3 = mallocstrcpy(NULL, r2);
|
||||
free(r2);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "fixbounds(): Ending string = \"%s\"\n", r3);
|
||||
#endif
|
||||
return (const char *) r3;
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_SPELLER
|
||||
@@ -586,6 +622,23 @@ size_t get_totsize(const filestruct *begin, const filestruct *end)
|
||||
return totsize;
|
||||
}
|
||||
|
||||
/* Get back a pointer given a line number in the current openfilestruct */
|
||||
filestruct *fsfromline(ssize_t lineno)
|
||||
{
|
||||
filestruct *f = openfile->current;
|
||||
|
||||
if (lineno <= openfile->current->lineno)
|
||||
for (; f->lineno != lineno && f != openfile->fileage; f = f->prev)
|
||||
;
|
||||
else
|
||||
for (; f->lineno != lineno && f->next != NULL; f = f->next)
|
||||
;
|
||||
|
||||
if (f->lineno != lineno)
|
||||
f = NULL;
|
||||
return f;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Dump the filestruct inptr to stderr. */
|
||||
void dump_filestruct(const filestruct *inptr)
|
||||
|
||||
@@ -1697,7 +1697,12 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
|
||||
for (; j > 0; j--) {
|
||||
if (f->next != NULL)
|
||||
f = f->next;
|
||||
while (f->next != NULL && ((f->menus & currmenu) == 0 || strlen(f->help) == 0))
|
||||
|
||||
while (f->next != NULL && ((f->menus & currmenu) == 0
|
||||
#ifndef DISABLE_HELP
|
||||
|| strlen(f->help) == 0
|
||||
#endif
|
||||
))
|
||||
f = f->next;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user