]> git.wh0rd.org Git - nano.git/commitdiff
2008-09-16 Chris Allegretta <chrisa@asty.org>
authorChris Allegretta <chrisa@asty.org>
Tue, 16 Sep 2008 21:35:19 +0000 (21:35 +0000)
committerChris Allegretta <chrisa@asty.org>
Tue, 16 Sep 2008 21:35:19 +0000 (21:35 +0000)
        * 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.

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4327 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
src/cut.c
src/text.c

index 3ee65f3aae5e91dc7a4aa32362739391668fa641..e224a67fae67fa63dbcda55fed08b893b7b9662e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+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.
index 72148e131f9ec7c3b42a4b42afb48f305ca916f1..26899864ea919e0371a336a8924859346b00f895 100644 (file)
--- a/src/cut.c
+++ b/src/cut.c
@@ -260,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);
index 3c59492c198cb03e15a172cd7c906413090949de..407b7ecb2113938f61feb8dd4ebc761877a6ea94 100644 (file)
@@ -364,6 +364,70 @@ 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;
+
+       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();
+}
+
 /* Undo the last thing(s) we did */
 void do_undo(void)
 {
@@ -443,21 +507,11 @@ void do_undo(void)
     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;
+        undo_cut(u);
+       break;
+    case UNCUT:
+       undidmsg = _("text uncut");
+       redo_cut(u);
        break;
     case INSERT:
        undidmsg = _("text insert");
@@ -576,43 +630,12 @@ void do_redo(void)
        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();
+       undidmsg = _("text cut");
+       redo_cut(u);
+       break;
+    case UNCUT:
+       undidmsg = _("text uncut");
+       undo_cut(u);
        break;
     case REPLACE:
        undidmsg = _("text replace");
@@ -620,14 +643,11 @@ void do_redo(void)
        u->strdata = f->data;
        f->data = data;
        break;
-     case INSERT:
+    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;
+        copy_from_filestruct(u->cutbuffer, u->cutbottom);
+       openfile->placewewant = xplustabs();
        break;
     default:
        undidmsg = _("Internal error: unknown type.  Please save your work");
@@ -799,7 +819,7 @@ bool execute_command(const char *command)
 /* Add a new undo struct to the top of the current pile */
 void add_undo(undo_type current_action)
 {
-    undo *u;
+    undo *u, *cutu;
     char *data;
     openfilestruct *fs = openfile;
 
@@ -832,6 +852,7 @@ void add_undo(undo_type current_action)
     u->strdata = NULL;
     u->cutbuffer = NULL;
     u->cutbottom  = NULL;
+    u->mark_set = 0;
     u->mark_begin_lineno = 0;
     u->mark_begin_x = 0;
     u->linescut = 0;
@@ -877,6 +898,20 @@ void add_undo(undo_type current_action)
        u->to_end = (current_action == CUTTOEND);
        break;
     case UNCUT:
+       for (cutu = u; cutu != NULL && cutu->type != CUT; cutu = cutu->next)
+           ;
+       if (cutu->type == CUT) {
+           u->cutbuffer = cutu->cutbuffer;
+           u->cutbottom = cutu->cutbottom;
+           if (!cutu->mark_set)
+               u->linescut = cutu->linescut;
+           else {
+               filestruct *c;
+               for (c = u->cutbuffer; c != NULL; c = c->next)
+                   u->linescut++;
+           }
+       } else
+           statusbar(_("Internal error: can't setup uncut.  Please save your work."));
        break;
     case OTHER:
        statusbar(_("Internal error: unknown type.  Please save your work."));
@@ -981,7 +1016,6 @@ void update_undo(undo_type action)
        break;
     case CUT:
     case CUTTOEND:
-    case UNCUT:
        if (u->cutbuffer)
            free(u->cutbuffer);
        u->cutbuffer = copy_filestruct(cutbuffer);
@@ -989,6 +1023,7 @@ void update_undo(undo_type action)
        u->linescut++;
        break;
     case REPLACE:
+    case UNCUT:
        add_undo(action);
        break;
     case INSERT: