]> git.wh0rd.org Git - nano.git/commitdiff
Commit back some undo/redo rewrites
authorChris Allegretta <chrisa@asty.org>
Thu, 31 Jul 2008 04:24:04 +0000 (04:24 +0000)
committerChris Allegretta <chrisa@asty.org>
Thu, 31 Jul 2008 04:24:04 +0000 (04:24 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4283 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

src/cut.c
src/global.c
src/nano.h
src/proto.h
src/text.c

index 57ba5c3c2331f48f2ed9d0f27f64af4a389f97d1..b56f6d4653711a9fc147472515d6c7f91c8a5a84 100644 (file)
--- a/src/cut.c
+++ b/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
@@ -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. */
@@ -205,11 +205,13 @@ void do_cut_text(
        if (!old_no_newlines)
            UNSET(NO_NEWLINES);
     } else
+       update_undo(CUT, openfile);
 #endif
        /* Leave the text in the cutbuffer, and mark the file as
         * modified. */
        set_modified();
 
+
     /* Update the screen. */
     edit_refresh();
 
@@ -221,6 +223,7 @@ void do_cut_text(
 /* Move text from the current filestruct into the cutbuffer. */
 void do_cut_text_void(void)
 {
+    add_undo(CUT, openfile);
     do_cut_text(
 #ifndef NANO_TINY
        FALSE, FALSE
@@ -239,6 +242,7 @@ void do_copy_text(void)
 /* Cut from the current cursor position to the end of the file. */
 void do_cut_till_end(void)
 {
+    add_undo(CUTTOEND, openfile);
     do_cut_text(FALSE, TRUE);
 }
 #endif /* !NANO_TINY */
index 5ca7c8d9af9ea8900bdecd62bb2ee74bef795c9c..0cece9c282b0d8f35c40beb79056379bbadd7067 100644 (file)
@@ -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. */
index f40d69d4ba32d723e2c3093fb86e5caf0318b1c3..694acd38f191fb7f8da905777697fcf20a72dc19 100644 (file)
@@ -170,7 +170,7 @@ typedef enum {
 }  function_type;
 
 typedef enum {
-    ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, UNCUT, OTHER
+    ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, CUTTOEND, UNCUT, OTHER
 } undo_type;
 
 /* Structure types. */
@@ -251,20 +251,37 @@ typedef struct syntaxtype {
 
 #ifndef NANO_TINY
 typedef struct undo {
+    ssize_t lineno;
     undo_type type;
-    filestruct *fs;
+       /* What type of undo was this */
     int begin;
        /* Where did this  action begin or end */
     char *strdata;
-       /* Generic pointer for data regardless of what type it is */
-    filestruct *fsdata;
-       /* Generic pointer for data regardless of what type it is */
-    struct undo *next;
-    ssize_t lineno;
+       /* 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. */
index 6af1d46207c7c6c2331b0c9079baaff4b0095328..2d8c34cf7b0ac13af50de6908e3a661767096bd0 100644 (file)
@@ -47,6 +47,7 @@ extern WINDOW *bottomwin;
 extern int editwinrows;
 
 extern filestruct *cutbuffer;
+extern filestruct *cutbottom;
 #ifndef DISABLE_JUSTIFY
 extern filestruct *jusbuffer;
 #endif
index 5666015b0b09a8fa5d51176e833378e7ed978612..2c908f6099a863c1ea683b8e6a00b853019ce66b 100644 (file)
@@ -368,9 +368,9 @@ void do_unindent(void)
 void do_undo(void)
 {
     undo *u = openfile->current_undo;
-    filestruct *f = openfile->current, *t;
+    filestruct *f = openfile->current, *t, *t2;
     int len = 0;
-    char *action, *data;
+    char *undidmsg, *data;
 
     if (!u) {
        statusbar(_("Nothing in undo buffer!"));
@@ -396,7 +396,7 @@ void do_undo(void)
     openfile->current_x = u->begin;
     switch(u->type) {
     case ADD:
-       action = _("text add");
+       undidmsg = _("text add");
        len = strlen(f->data) - strlen(u->strdata) + 1;
         data = charalloc(len);
         strncpy(data, f->data, u->begin);
@@ -405,7 +405,7 @@ void do_undo(void)
        f->data = data;
        break;
     case DEL:
-       action = _("text delete");
+       undidmsg = _("text delete");
        len = strlen(f->data) + strlen(u->strdata) + 1;
        data = charalloc(len);
 
@@ -418,7 +418,7 @@ void do_undo(void)
            openfile->current_x += strlen(u->strdata);
        break;
     case SPLIT:
-       action = _("line split");
+       undidmsg = _("line split");
        free(f->data);
        f->data = mallocstrcpy(NULL, u->strdata);
        if (f->next != NULL) {
@@ -429,7 +429,7 @@ void do_undo(void)
        renumber(f);
        break;
     case UNSPLIT:
-       action = _("line join");
+       undidmsg = _("line join");
        t = make_new_node(f);
        t->data = mallocstrcpy(NULL, u->strdata);
        data = mallocstrncpy(NULL, f->data, u->begin);
@@ -439,14 +439,26 @@ void do_undo(void)
        splice_node(f, t, f->next);
        renumber(f);
        break;
+    case CUT:
+    case CUTTOEND:
+       undidmsg = _("text cut");
+       cutbuffer = copy_filestruct(u->cutbuffer);
+       for (cutbottom = cutbuffer; cutbottom->next != NULL; cutbottom = cutbottom->next)
+           ;
+       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);
+       break;
     default:
-       action = _("wtf?");
+       undidmsg = _("wtf?");
        break;
 
     }
-    openfile->current = f;
-    edit_refresh();
-    statusbar(_("Undid action (%s)"), action);
+    do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
+    statusbar(_("Undid action (%s)"), undidmsg);
     openfile->current_undo = openfile->current_undo->next;
 
 }
@@ -454,9 +466,9 @@ void do_undo(void)
 void do_redo(void)
 {
     undo *u = openfile->undotop;
-    filestruct *f = openfile->current, *t;
-    int len = 0;
-    char *action, *data;
+    filestruct *f = openfile->current, *t, *t2;
+    int len = 0, i, i2;
+    char *undidmsg, *data;
 
     for (; u != NULL && u->next != openfile->current_undo; u = u->next)
        ;
@@ -486,7 +498,7 @@ void do_redo(void)
 
     switch(u->type) {
     case ADD:
-       action = _("text add");
+       undidmsg = _("text add");
        len = strlen(f->data) + strlen(u->strdata) + 1;
         data = charalloc(len);
        strcpy(&data[u->begin], u->strdata);
@@ -495,7 +507,7 @@ void do_redo(void)
        f->data = data;
        break;
     case DEL:
-       action = _("text delete");
+       undidmsg = _("text delete");
        len = strlen(f->data) + strlen(u->strdata) + 1;
        data = charalloc(len);
         strncpy(data, f->data, u->begin);
@@ -504,7 +516,7 @@ void do_redo(void)
        f->data = data;
        break;
     case SPLIT:
-       action = _("line split");
+       undidmsg = _("line split");
        t = make_new_node(f);
        t->data = mallocstrcpy(NULL, u->strdata);
        data = mallocstrncpy(NULL, f->data, u->begin);
@@ -515,7 +527,7 @@ void do_redo(void)
        renumber(f);
        break;
     case UNSPLIT:
-       action = _("line join");
+       undidmsg = _("line join");
        len = strlen(f->data) + strlen(u->strdata + 1);
        data = charalloc(len);
        strcpy(data, f->data);
@@ -529,15 +541,33 @@ void do_redo(void)
        }
        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;
+       t = cutbuffer;
+       cutbuffer = NULL;
+       if (u->mark_set) {
+           for (i = 1, t = openfile->fileage; i != u->mark_begin_lineno; i++)
+               t = t->next;
+           openfile->mark_begin = t;
+       }
+       openfile->mark_begin_x = u->mark_begin_x;
+       do_cut_text(FALSE, u->to_end);
+       openfile->mark_set = FALSE;
+        openfile->mark_begin = NULL;
+        openfile->mark_begin_x = 0;
+       cutbuffer = t;
+       edit_refresh();
+       break;
     default:
-       action = _("wtf?");
+       undidmsg = _("wtf?");
        break;
 
     }
-    openfile->current = f;
-    openfile->current_x = u->begin;
-    edit_refresh();
-    statusbar(_("Redid action (%s)"), action);
+    do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
+    statusbar(_("Redid action (%s)"), undidmsg);
 
     openfile->current_undo = u;
 
@@ -697,6 +727,7 @@ 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, openfilestruct *fs)
 {
     undo *u = nmalloc(sizeof(undo));
@@ -713,8 +744,6 @@ void add_undo(undo_type current_action, openfilestruct *fs)
     u->type = current_action;
     u->lineno = fs->current->lineno;
     u->begin = fs->current_x;
-    u->fs = fs->current;
-    u->xflags = 0;
     u->next = fs->undotop;
     fs->undotop = u;
     fs->current_undo = u;
@@ -746,27 +775,44 @@ void add_undo(undo_type current_action, openfilestruct *fs)
        break;
     case SPLIT:
        data = mallocstrcpy(NULL, fs->current->data);
-       u->strdata = data;
         u->begin = fs->current_x;
+       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;
     }
 
 #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, "u->strdata = \"%s\"\n", u->strdata);
     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, openfilestruct *fs)
 {
     undo *u;
     char *data;
     int len = 0;
 
-    if (action != fs->last_action) {
+    /* 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
+           && openfile->current->lineno != fs->undotop->lineno)) {
         add_undo(action, fs);
        return;
     }
@@ -774,13 +820,6 @@ void update_undo(undo_type action, openfilestruct *fs)
     assert(fs->undotop != NULL);
     u = fs->undotop;
 
-    if (u->fs->data != openfile->current->data || u->lineno !=  openfile->current->lineno) {
-        add_undo(action, fs);
-       return;
-    }
-
-
-
     switch (u->type) {
     case ADD:
 #ifdef DEBUG
@@ -836,6 +875,12 @@ void update_undo(undo_type action, openfilestruct *fs)
        fprintf(stderr, "current undo data now \"%s\"\nu->begin = %d\n", u->strdata, u->begin);
 #endif
        break;
+    case CUT:
+    case CUTTOEND:
+    case UNCUT:
+       u->cutbuffer = copy_filestruct(cutbuffer);
+       u->cutbottom = cutbottom;
+       break;
     case SPLIT:
     case UNSPLIT:
        /* We don't really ever update an enter key press, treat it as a new */