Compare commits

..

30 Commits

Author SHA1 Message Date
Chris Allegretta
d2780eca94 GNU nano 2.1.4 release.
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4301 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-09 10:25:22 +00:00
Chris Allegretta
80ea9c5de9 * text.c (add_undo): Fix check for multi-line cut check skips adding other new legit events.
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4300 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-09 10:08:33 +00:00
Chris Allegretta
b08b38680d Re-add the skip_backup label since we do still need it in one case.
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4299 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-09 09:31:33 +00:00
Chris Allegretta
5c27d723c9 * text.c (do_redo): Fix improperly restoring the text when redoing a line split.
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4298 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-09 09:28:07 +00:00
Chris Allegretta
447f1b4b75 * files.c: Do not go on and attempt to write the main file if writing the backup file failed,
related to Savannah bug 24000.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4297 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-09 03:39:10 +00:00
Chris Allegretta
6f681c1be2 * 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 



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4296 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-08 03:02:03 +00:00
Chris Allegretta
a50d0e35f7 Back to SVN version
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4295 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-05 02:38:40 +00:00
Chris Allegretta
599c559b3c GNU nano 2.1.3 release
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4293 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-05 01:35:42 +00:00
Chris Allegretta
ea577874ef - Add redo of an insert
- Fix bug in fsfromlineno
- Tiny cleanups in undo



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4292 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-03 20:19:42 +00:00
Chris Allegretta
14c8620e0b - Change add_undo and current_undo to only take action arg, as openfilestruct arg is always openfile
- Add ability to undo a file/cmd insert, needed to add undoable flag to read_file and open_buffer as a result



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4291 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-03 04:48:05 +00:00
Chris Allegretta
3c1131a5b3 - Add very basic undo for text replace.
- Fix lots of warnings whe using -Wall
- Fix some comments



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4290 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-02 22:31:01 +00:00
Chris Allegretta
015c74093a Allow current undo code to compile with NANO_TINY
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4289 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-02 14:39:42 +00:00
Chris Allegretta
d31ddb789f Allow basic multi-^K cuts to be redone properly. Code getting uglier by the second.
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4288 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-01 07:29:06 +00:00
Chris Allegretta
8f76112084 - When undoing a cut, set cutbuffer to NULL after freeing the current one
- When updating a normal consecutive ^K cut, bail from add_undo since it's not an add, and in update_undo free the old cutbuffer before copying it again.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4287 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-01 06:52:15 +00:00
Chris Allegretta
1f37c4514d When redoing a text add, actually copy the beginning of the line back!
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4286 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-01 04:11:57 +00:00
Chris Allegretta
91a1862eed Add undoing argument to do_cut_text as we don't want to be messing around with the undo contents when we're in the
middle of an undo.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4285 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-08-01 03:50:20 +00:00
Chris Allegretta
e418b694b6 * configure.ac: Add ncursesw dir to include path if lib detected
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4284 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-31 17:01:47 +00:00
Chris Allegretta
12dc8cae80 Commit back some undo/redo rewrites
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4283 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-31 04:24:04 +00:00
Chris Allegretta
0b499d465b Add xflags to undo struct so we can add extra info to the undo process (e.g. backspace vs delete)
Fix redo of a line join.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4282 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-14 07:18:22 +00:00
Chris Allegretta
fa406949ec Allow backspace to be bound to keys in .nanorc
Allow kdel to be rebound
Add note about rebinding kdel to backspace for those using OSX or PuTTY to connect to remote Linux machines in nanorc.sample.in

When undoing text deletes, move current_x to proper location



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4281 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-13 16:44:19 +00:00
Chris Allegretta
70859f4a5b Add ability to rebind the (still unfinished) undo and redo functions in case anyone is interested in testing it out early.
Add to nanorc.5 also.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4280 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-13 01:36:06 +00:00
Chris Allegretta
9fb13fb8f0 2008-07-11 Mike Frysinger <vapier@gentoo.org>
* doc/nanorc.sample.in: Include the updates files in the default sample nanorc.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4279 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-12 02:52:08 +00:00
Chris Allegretta
274142cb10 Clean up some unused variables from old undo implementation.
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4278 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-12 02:48:20 +00:00
Chris Allegretta
b8576780bf 2008-07-11 Fabian Groffen <grobian@gentoo.org>
* nano.c: Don't include langinfo.h if not using ENABLE_UTF8
          (Savannah patch 6565)



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4277 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-12 02:32:19 +00:00
Chris Allegretta
a9dea9859d 2008-07-11 Michael Haubenwallner <michael.haubenwallner@salomon.at>
* global.c: include proto.h earlier in file to fix AIX compilation
          (Savannah patch 6559)



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4275 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-12 02:20:16 +00:00
Chris Allegretta
a855fa2acc 2008-07-11 Michael Haubenwallner <michael.haubenwallner@salomon.at>
* global.c: include proto.h earlier in file to fix AIX compilation
          (Savannah patch 6559)



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4274 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-12 02:13:22 +00:00
Chris Allegretta
09b8124859 Savannah bug 23751: Segfault when viewing help using Japanese locale
Fix break_line crashing when using certain locales from Mitsuya Shibata



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4272 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-12 01:54:49 +00:00
Chris Allegretta
07fcc4c973 Add beginning undo feature, since I want to start fixing bugs from savannah and don't want to manager another checking, and the code basically works for some operations.
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4271 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-07-10 20:13:04 +00:00
Chris Allegretta
1347f22c95 Fix for 23733: search history broken with nano-2.1.1+
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4270 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-06-29 06:22:31 +00:00
Chris Allegretta
9015f187a5 Back to SVN
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4269 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
2008-06-25 03:42:28 +00:00
46 changed files with 14108 additions and 10844 deletions

View File

@@ -1,3 +1,40 @@
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

32
NEWS
View File

@@ -1,4 +1,24 @@
2008/04/24 - GNU nano 2.1.2 "New York City" is released. This release
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 +26,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 +38,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 +48,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 +70,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

View File

@@ -20,7 +20,7 @@
#
# $Id$
AC_INIT([GNU nano], [2.1.2], [nano-devel@gnu.org], [nano])
AC_INIT([GNU nano], [2.1.4], [nano-devel@gnu.org], [nano])
AC_CONFIG_SRCDIR([src/nano.c])
AC_CANONICAL_TARGET([])
AM_INIT_AUTOMAKE
@@ -417,7 +417,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

View File

@@ -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 suspend
Redo the last action which was undone.
.TP
.B suspend
Suspend the editor (if the suspend function is enabled, see the
"suspendenable" entry below).

View File

@@ -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"

680
po/bg.po

File diff suppressed because it is too large Load Diff

755
po/ca.po

File diff suppressed because it is too large Load Diff

702
po/cs.po

File diff suppressed because it is too large Load Diff

680
po/da.po

File diff suppressed because it is too large Load Diff

772
po/de.po

File diff suppressed because it is too large Load Diff

680
po/es.po

File diff suppressed because it is too large Load Diff

680
po/eu.po

File diff suppressed because it is too large Load Diff

676
po/fi.po

File diff suppressed because it is too large Load Diff

1496
po/fr.po

File diff suppressed because it is too large Load Diff

1759
po/ga.po

File diff suppressed because it is too large Load Diff

680
po/gl.po

File diff suppressed because it is too large Load Diff

840
po/hu.po

File diff suppressed because it is too large Load Diff

680
po/id.po

File diff suppressed because it is too large Load Diff

741
po/it.po

File diff suppressed because it is too large Load Diff

782
po/ms.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

680
po/nb.po

File diff suppressed because it is too large Load Diff

775
po/nl.po

File diff suppressed because it is too large Load Diff

703
po/nn.po

File diff suppressed because it is too large Load Diff

680
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

683
po/ro.po

File diff suppressed because it is too large Load Diff

824
po/ru.po

File diff suppressed because it is too large Load Diff

757
po/rw.po

File diff suppressed because it is too large Load Diff

680
po/sr.po

File diff suppressed because it is too large Load Diff

680
po/sv.po

File diff suppressed because it is too large Load Diff

680
po/tr.po

File diff suppressed because it is too large Load Diff

680
po/uk.po

File diff suppressed because it is too large Load Diff

796
po/vi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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(CUTTOEND);
#endif
do_cut_text(FALSE, TRUE, FALSE);
}
#endif /* !NANO_TINY */

View File

@@ -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

View File

@@ -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;
@@ -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");
@@ -698,6 +696,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);
@@ -771,7 +770,13 @@ void shortcut_init(bool unjustify)
nano_indent_msg, FALSE, NOVIEW);
add_to_funcs(do_unindent, MMAIN, N_("Unindent Text"),
nano_unindent_msg, TRUE, NOVIEW);
nano_unindent_msg, FALSE, NOVIEW);
add_to_funcs(do_undo, MMAIN, N_("Undo"),
nano_undo_msg, FALSE, NOVIEW);
add_to_funcs(do_redo, MMAIN, N_("Redo"),
nano_redo_msg, TRUE, NOVIEW);
#endif
@@ -1055,6 +1060,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 +1079,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 +1340,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 +1447,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 +1589,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)

View File

@@ -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;
}
@@ -1642,6 +1647,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 +2232,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 +2249,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);
}

View File

@@ -169,6 +169,10 @@ typedef enum {
CONTROL, META, FKEY, RAW
} function_type;
typedef enum {
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, CUTTOEND, UNCUT, INSERT, OTHER
} undo_type;
/* Structure types. */
typedef struct filestruct {
char *data;
@@ -245,6 +249,40 @@ 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 */
ssize_t linescut;
/* How many lines we cut on a straight non-marked non-to-end cut */
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

View File

@@ -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(
@@ -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
@@ -706,8 +707,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 +743,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);

View File

@@ -380,7 +380,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 +423,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

View File

@@ -788,6 +788,9 @@ ssize_t do_replace_loop(
char *copy;
size_t length_change;
#ifndef NANO_TINY
update_undo(REPLACE);
#endif
if (i == 2)
replaceall = TRUE;

View File

@@ -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,284 @@ void do_unindent(void)
{
do_indent(-tabsize);
}
/* 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(_("Couldnt match current undo line"));
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:
case CUTTOEND:
undidmsg = _("text cut");
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);
do_uncut_text();
free_filestruct(cutbuffer);
cutbuffer = NULL;
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 = _("wtf?");
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;
filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom;
int len = 0, i;
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(_("Can't find previous undo to re-do, argh"));
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(_("Couldnt match current undo line"));
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:
case CUTTOEND:
undidmsg = _("line cut");
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 */
#ifdef DEBUG
fprintf(stderr, "Undoing multi-^K cut, u->linescut = %d\n", u->linescut);
#endif
for (i = 0, t = openfile->current; i < u->linescut; i++) {
#ifdef DEBUG
fprintf(stderr, "Advancing, lineno = %d, data = \"%s\"\n", t->lineno, t->data);
#endif
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();
break;
case REPLACE:
undidmsg = _("text replace");
data = u->strdata;
u->strdata = f->data;
f->data = data;
break;
case INSERT:
undidmsg = _("text insert");
cutbuffer = u->cutbuffer;
cutbottom = u->cutbottom;
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
do_uncut_text();
cutbuffer = oldcutbuffer;
cutbottom = oldcutbottom;
break;
default:
undidmsg = _("wtf?");
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!* */
@@ -367,9 +649,12 @@ void do_enter(void)
filestruct *newnode = make_new_node(openfile->current);
size_t extra = 0;
assert(openfile->current != NULL && openfile->current->data != NULL);
assert(openfile->current != NULL && xopenfile->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 +780,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 +795,223 @@ 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;
/* 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_begin_lineno = 0;
u->mark_begin_x = 0;
u->linescut = 0;
u->xflags = 0;
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:
case CUTTOEND:
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 = (current_action == CUTTOEND);
break;
case UNCUT:
break;
case OTHER:
statusbar(_("OOPS. Tried to add unknown thing to undo struct, I'd 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 != CUTTOEND && 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:
case CUTTOEND:
case UNCUT:
if (u->cutbuffer)
free(u->cutbuffer);
u->cutbuffer = copy_filestruct(cutbuffer);
u->cutbottom = cutbottom;
u->linescut++;
break;
case REPLACE:
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 +1302,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 +2975,4 @@ void do_verbatim_input(void)
free(output);
}

View File

@@ -586,6 +586,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)