]> git.wh0rd.org Git - nano.git/commitdiff
Going to the correct positions for undoing and redoing cuts and
authorBenno Schulenberg <bensberg@justemail.net>
Thu, 15 May 2014 20:00:46 +0000 (20:00 +0000)
committerBenno Schulenberg <bensberg@justemail.net>
Thu, 15 May 2014 20:00:46 +0000 (20:00 +0000)
pastes.  This fixes many undo problems and Savannah bug #25585.
*Patch by Mark Majeres.*

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

ChangeLog
src/cut.c
src/move.c
src/nano.c
src/nano.h
src/proto.h
src/search.c
src/text.c
src/utils.c

index 3a66e2e5388838967c82e942a448c46de9b3d5be..ab8baf4ecffe1f223715860107a6c1ef4493ebc1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-05-15  Mark Majeres  <mark@engine12.com>
+       * src/*, but mainly src/text.c (undo_cut, redo_cut, do_undo, do_redo):
+       Go to the correct positions for undoing/redoing the cuts and pastes.
+       This fixes several undo problems and Savannah bug #25585.
+
 2014-05-15  Benno Schulenberg  <bensberg@justemail.net>
        * doc/syntax/c.nanorc: Improve the magic regex, plus tweaks.
        * src/color.c (color_update): Adjust a comment, and be clearer.
index 4ec428bf2eef9aaada01a155fac1ff69ce48db90..823ec6fb50c833eef1ac603a0b0ab11e6d8dbf9d 100644 (file)
--- a/src/cut.c
+++ b/src/cut.c
@@ -44,6 +44,9 @@ void cutbuffer_reset(void)
  * current line. */
 void cut_line(void)
 {
+    if(!openfile->mark_begin)
+       openfile->mark_begin = openfile->current;
+
     if (openfile->current != openfile->filebot)
        move_to_filestruct(&cutbuffer, &cutbottom, openfile->current, 0,
                openfile->current->next, 0);
@@ -204,7 +207,7 @@ void do_cut_text(
        if (!old_no_newlines)
            UNSET(NO_NEWLINES);
     } else if (!undoing)
-       update_undo(CUT);
+       update_undo(cut_till_end ? CUT_EOF : CUT);
 
     /* Leave the text in the cutbuffer, and mark the file as
      * modified. */
@@ -249,7 +252,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(CUT);
+    add_undo(CUT_EOF);
     do_cut_text(FALSE, TRUE, FALSE);
 }
 #endif /* !NANO_TINY */
@@ -264,7 +267,7 @@ void do_uncut_text(void)
        return;
 
 #ifndef NANO_TINY
-    update_undo(UNCUT);
+    add_undo(PASTE);
 #endif
 
     /* Add a copy of the text in the cutbuffer to the current filestruct
index d8d912a086160daaec4efbc65e184593a1ca306e..355fa02793ee23832ef41306d3eac2342f425873 100644 (file)
@@ -570,7 +570,7 @@ void do_down(
 #endif
 
     /* If we're at the bottom of the file, get out. */
-    if (openfile->current == openfile->filebot)
+    if (openfile->current == openfile->filebot || !openfile->current->next)
        return;
 
     assert(ISSET(SOFTWRAP) || openfile->current_y == openfile->current->lineno - openfile->edittop->lineno);
index 9ca60e1d7b082c40b7f31750386b07f302d0b1a7..bf2d17bf7027b20161c7999056618cf8b6b95ffb 100644 (file)
@@ -2030,7 +2030,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
        set_modified();
 
 #ifndef NANO_TINY
-       update_undo(ADD);
+       add_undo(ADD);
 
        /* Note that current_x has not yet been incremented. */
        if (openfile->mark_set && openfile->current ==
@@ -2041,6 +2041,10 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
 
        openfile->current_x += char_buf_len;
 
+#ifndef NANO_TINY
+       update_undo(ADD);
+#endif
+
 #ifndef DISABLE_WRAPPING
        /* If we're wrapping text, we need to call edit_refresh(). */
        if (!ISSET(NO_WRAP))
index a1da639a72206a46361fc15151fd68468632d6fc..c97faad6e7d29138d52066c5069bdddb6d313cf2 100644 (file)
@@ -187,7 +187,7 @@ typedef enum {
 }  function_type;
 
 typedef enum {
-    ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, UNCUT, ENTER, INSERT, OTHER
+    ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, CUT_EOF, PASTE, ENTER, INSERT, OTHER
 } undo_type;
 
 typedef struct color_pair {
@@ -324,7 +324,7 @@ typedef struct undo {
     ssize_t lineno;
     undo_type type;
        /* What type of undo this was. */
-    int begin;
+    size_t begin;
        /* Where did this action begin or end. */
     char *strdata;
        /* String type data we will use for copying the affected line back. */
@@ -344,7 +344,7 @@ typedef struct undo {
        /* Was this a cut to end? */
     ssize_t mark_begin_lineno;
        /* copy copy copy */
-    ssize_t mark_begin_x;
+    size_t mark_begin_x;
        /* Another shadow variable. */
     struct undo *next;
 } undo;
index c8a4de7a687388e4a0dd280a27f04623ece60783..c1f17b9b689b8c6fa95166081edc50f46ae63632 100644 (file)
@@ -604,6 +604,7 @@ void do_gotolinecolumn_void(void);
 void do_gotopos(ssize_t pos_line, size_t pos_x, ssize_t pos_y, size_t
        pos_pww);
 #endif
+void goto_line_posx(ssize_t line, size_t pos_x);
 #ifndef NANO_TINY
 bool find_bracket_match(bool reverse, const char *bracket_set);
 void do_find_bracket(void);
index d841b463736d852e986b435c100cb64ad72faabd..2480bb9c4a0956f3523a0a26715dacc6f775ce6e 100644 (file)
@@ -1008,6 +1008,20 @@ void do_replace(void)
     search_replace_abort();
 }
 
+/* Go to the specified line and x position. */
+void goto_line_posx(ssize_t line, size_t pos_x)
+{
+    for (openfile->current = openfile->fileage; openfile->current != openfile->filebot &&
+                                       openfile->current->next != NULL && line > 1; line--)
+       openfile->current = openfile->current->next;
+
+    openfile->current_x = pos_x;
+    openfile->placewewant = xplustabs();
+
+    edit_refresh_needed = TRUE;
+    edit_refresh();
+}
+
 /* Go to the specified line and column, or ask for them if interactive
  * is TRUE.  Save the x-coordinate and y-coordinate if save_pos is TRUE.
  * Update the screen afterwards if allow_update is TRUE.  Note that both
index 94696129e1693d4adbb73732da2a8609030e2fb0..aee832e8b138f1b0e9ee1d1865f33b2f4b57a724 100644 (file)
@@ -112,9 +112,8 @@ void do_delete(void)
            edit_refresh_needed = TRUE;
 
        openfile->current->data = charealloc(openfile->current->data,
-               openfile->current_x + strlen(foo->data) + 1);
-       strcpy(openfile->current->data + openfile->current_x,
-               foo->data);
+               strlen(openfile->current->data) + strlen(foo->data) + 1);
+       strcat(openfile->current->data, foo->data);
 #ifndef NANO_TINY
        if (openfile->mark_set && openfile->mark_begin ==
                openfile->current->next) {
@@ -359,6 +358,9 @@ void do_unindent(void)
     do_indent(-tabsize);
 }
 
+#define redo_paste undo_cut
+#define undo_paste redo_cut
+
 /* Undo a cut, or redo an uncut. */
 void undo_cut(undo *u)
 {
@@ -373,10 +375,7 @@ void undo_cut(undo *u)
        ;
 
     /* 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);
+    goto_line_posx(u->mark_begin_lineno, u->mark_begin_x);
 
     copy_from_filestruct(cutbuffer);
     free_filestruct(cutbuffer);
@@ -386,39 +385,26 @@ void undo_cut(undo *u)
 /* Redo a cut, or undo an uncut. */
 void redo_cut(undo *u)
 {
-    int i;
-    filestruct *t, *c;
-
     /* If we cut the magicline, we may as well not crash. :/ */
     if (!u->cutbuffer)
        return;
 
-    do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
+    goto_line_posx(u->lineno, u->begin);
+
+    if (ISSET(NO_NEWLINES) && openfile->current->lineno != u->lineno) {
+       openfile->current_x = strlen(openfile->current->data);
+       openfile->placewewant = xplustabs();
+    }
+
     openfile->mark_set = u->mark_set;
     if (cutbuffer)
        free(cutbuffer);
     cutbuffer = NULL;
 
-    /* Move ahead the same number of 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 = %lu, data = \"%s\"\n", (unsigned long) t->lineno, t->data);
-#endif
-           c = c->next;
-           t = t->next;
-       }
-       openfile->mark_begin = t;
-       openfile->mark_begin_x = 0;
+    openfile->mark_begin = fsfromline(u->mark_begin_lineno);
+
+    if (!ISSET(CUT_TO_END))
        openfile->mark_set = TRUE;
-    }
 
     openfile->mark_begin_x = u->mark_begin_x;
     do_cut_text(FALSE, u->to_end, TRUE);
@@ -431,8 +417,9 @@ void redo_cut(undo *u)
 /* Undo the last thing(s) we did. */
 void do_undo(void)
 {
+    bool gotolinecolumn = FALSE;
     undo *u = openfile->current_undo;
-    filestruct *f = openfile->current, *t;
+    filestruct *t = 0;
     int len = 0;
     char *undidmsg, *data;
     filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom;
@@ -442,14 +429,9 @@ void do_undo(void)
        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);
+    filestruct *f = fsfromline(u->mark_begin_lineno);
+    if (!f) {
+       statusbar(_("Internal error: can't match line %d.  Please save your work."), u->mark_begin_lineno);
        return;
     }
 #ifdef DEBUG
@@ -467,6 +449,7 @@ void do_undo(void)
        strcpy(&data[u->begin], &f->data[u->begin + strlen(u->strdata)]);
        free(f->data);
        f->data = data;
+       goto_line_posx(u->lineno, u->begin);
        break;
     case DEL:
        undidmsg = _("text delete");
@@ -480,6 +463,7 @@ void do_undo(void)
        f->data = data;
        if (u->xflags == UNdel_backspace)
            openfile->current_x += strlen(u->strdata);
+       goto_line_posx(u->mark_begin_lineno, u->mark_begin_x + 1);
        break;
 #ifndef DISABLE_WRAPPING
     case SPLIT:
@@ -494,26 +478,28 @@ void do_undo(void)
            delete_node(foo);
        }
        renumber(f);
+       gotolinecolumn = TRUE;
        break;
 #endif /* !DISABLE_WRAPPING */
     case UNSPLIT:
        undidmsg = _("line join");
        t = make_new_node(f);
        t->data = mallocstrcpy(NULL, u->strdata);
-       data = mallocstrncpy(NULL, f->data, u->begin);
+       data = mallocstrncpy(NULL, f->data, u->begin + 1);
        data[u->begin] = '\0';
        free(f->data);
        f->data = data;
        splice_node(f, t, f->next);
-       renumber(f);
+       gotolinecolumn = TRUE;
        break;
+    case CUT_EOF:
     case CUT:
        undidmsg = _("text cut");
         undo_cut(u);
        break;
-    case UNCUT:
+    case PASTE:
        undidmsg = _("text uncut");
-       redo_cut(u);
+       undo_paste(u);
        break;
     case ENTER:
        undidmsg = _("line break");
@@ -524,6 +510,7 @@ void do_undo(void)
            unlink_node(foo);
            delete_node(foo);
        }
+       goto_line_posx(u->lineno, u->begin);
        break;
     case INSERT:
        undidmsg = _("text insert");
@@ -535,7 +522,7 @@ void do_undo(void)
        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);
+       goto_line_posx(u->lineno, u->begin);
        cut_marked();
        u->cutbuffer = cutbuffer;
        u->cutbottom = cutbottom;
@@ -545,6 +532,7 @@ void do_undo(void)
        break;
     case REPLACE:
        undidmsg = _("text replace");
+       goto_line_posx(u->lineno, u->begin);
        data = u->strdata;
        u->strdata = f->data;
        f->data = data;
@@ -555,17 +543,19 @@ void do_undo(void)
     }
 
     renumber(f);
-    do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
+    if (gotolinecolumn)
+       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;
+    set_modified();
 }
 
 /* Redo the last thing(s) we undid. */
 void do_redo(void)
 {
+    bool gotolinecolumn = FALSE;
     undo *u = openfile->undotop;
-    filestruct *f = openfile->current;
     int len = 0;
     char *undidmsg, *data;
 
@@ -580,14 +570,9 @@ void do_redo(void)
        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);
+    filestruct *f = fsfromline(u->mark_begin_lineno);
+    if (!f) {
+       statusbar(_("Internal error: can't match line %d.  Please save your work."), u->mark_begin_lineno);
        return;
     }
 #ifdef DEBUG
@@ -605,6 +590,7 @@ void do_redo(void)
        strcpy(&data[u->begin + strlen(u->strdata)], &f->data[u->begin]);
        free(f->data);
        f->data = data;
+       goto_line_posx(u->mark_begin_lineno, u->mark_begin_x);
        break;
     case DEL:
        undidmsg = _("text delete");
@@ -614,10 +600,13 @@ void do_redo(void)
        strcpy(&data[u->begin], &f->data[u->begin + strlen(u->strdata)]);
        free(f->data);
        f->data = data;
+       openfile->current_x = u->begin;
+       openfile->placewewant = xplustabs();
+       goto_line_posx(u->lineno, u->begin);
        break;
     case ENTER:
        undidmsg = _("line break");
-       do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
+       goto_line_posx(u->lineno, u->begin);
        do_enter(TRUE);
        break;
 #ifndef DISABLE_WRAPPING
@@ -627,53 +616,55 @@ void do_redo(void)
            prepend_wrap = TRUE;
         do_wrap(f, TRUE);
        renumber(f);
+       gotolinecolumn = TRUE;
        break;
 #endif /* !DISABLE_WRAPPING */
     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;
+       len = strlen(f->data) + strlen(u->strdata) + 1;
+       f->data = charealloc(f->data, len);
+       strcat(f->data, u->strdata);
        if (f->next != NULL) {
            filestruct *tmp = f->next;
            unlink_node(tmp);
            delete_node(tmp);
        }
        renumber(f);
+       gotolinecolumn = TRUE;
        break;
+    case CUT_EOF:
     case CUT:
        undidmsg = _("text cut");
        redo_cut(u);
        break;
-    case UNCUT:
+    case PASTE:
        undidmsg = _("text uncut");
-       undo_cut(u);
+       redo_paste(u);
        break;
     case REPLACE:
        undidmsg = _("text replace");
        data = u->strdata;
        u->strdata = f->data;
        f->data = data;
+       goto_line_posx(u->lineno, u->begin);
        break;
     case INSERT:
        undidmsg = _("text insert");
-       do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
+       goto_line_posx(u->lineno, u->begin);
        copy_from_filestruct(u->cutbuffer);
-       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);
+    if (gotolinecolumn)
+       do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
     statusbar(_("Redid action (%s)"), undidmsg);
 
     openfile->current_undo = u;
     openfile->last_action = OTHER;
+    set_modified();
 }
 #endif /* !NANO_TINY */
 
@@ -841,7 +832,6 @@ 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. */
     ssize_t wrap_loc;
        /* For calculating split beginning. */
@@ -852,8 +842,9 @@ void add_undo(undo_type current_action)
     /* 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)
+    if (u && u->mark_begin_lineno == fs->current->lineno &&
+       ((current_action == CUT && u->type == CUT && !u->mark_set) ||
+       (current_action == ADD && u->type == ADD && u->mark_begin_x == fs->current_x)))
        return;
 
     /* Blow away the old undo stack if we are starting from the middle. */
@@ -880,8 +871,8 @@ void add_undo(undo_type current_action)
     u->cutbuffer = NULL;
     u->cutbottom  = NULL;
     u->mark_set = 0;
-    u->mark_begin_lineno = 0;
-    u->mark_begin_x = 0;
+    u->mark_begin_lineno = fs->current->lineno;
+    u->mark_begin_x =  fs->current_x;
     u->xflags = 0;
     u->to_end = FALSE;
 
@@ -890,8 +881,7 @@ void add_undo(undo_type current_action)
      * or we won't be able to restore it later. */
     case ADD:
         data = charalloc(2);
-        data[0] = fs->current->data[fs->current_x];
-        data[1] = '\0';
+       data[0] = '\0';
         u->strdata = data;
        break;
     case DEL:
@@ -929,21 +919,43 @@ void add_undo(undo_type current_action)
        data = mallocstrcpy(NULL, fs->current->data);
        u->strdata = data;
        break;
+    case CUT_EOF:
+       u->to_end = TRUE;
     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;
+       else if (!ISSET(CUT_TO_END) && !u->to_end) {
+           /* The entire line is being cut regardless of the cursor position. */
+           u->begin = 0;
+           u->mark_begin_x = 0;
+       }
        break;
-    case UNCUT:
-       if (!last_cutu)
+    case PASTE:
+       if (!cutbuffer)
            statusbar(_("Internal error: cannot set up uncut.  Please save your work."));
-       else if (last_cutu->type == CUT) {
-           u->cutbuffer = last_cutu->cutbuffer;
-           u->cutbottom = last_cutu->cutbottom;
+       else {
+           if (u->cutbuffer)
+               free(u->cutbuffer);
+           u->cutbuffer = copy_filestruct(cutbuffer);
+           u->mark_begin_lineno = fs->current->lineno;
+           u->mark_begin_x =  fs->current_x;
+           u->lineno =  fs->current->lineno + cutbottom->lineno - cutbuffer->lineno;
+
+           filestruct *fs_buff = cutbuffer;
+           if (fs_buff->lineno == cutbottom->lineno)
+               u->begin = fs->current_x +  get_totsize(fs_buff,cutbottom);
+           else {
+               /* Advance fs_buff to the last line in the cutbuffer. */
+               while (fs_buff->lineno != cutbottom->lineno && fs_buff->next != NULL)
+                   fs_buff = fs_buff->next;
+               assert(fs_buff->next != NULL);
+               u->begin = get_totsize(fs_buff,cutbottom);
+           }
+
+           u->mark_set = TRUE;
        }
        break;
     case ENTER:
@@ -1004,12 +1016,14 @@ void update_undo(undo_type action)
 #endif
         len = strlen(u->strdata) + 2;
         data = (char *) nrealloc((void *) u->strdata, len * sizeof(char *));
-        data[len-2] = fs->current->data[fs->current_x];
+        data[len-2] = fs->current->data[fs->current_x - 1];
         data[len-1] = '\0';
         u->strdata = (char *) data;
 #ifdef DEBUG
        fprintf(stderr, "current undo data now \"%s\"\n", u->strdata);
 #endif
+       u->mark_begin_lineno = fs->current->lineno;
+       u->mark_begin_x =  fs->current_x;
        break;
     case DEL:
        len = strlen(u->strdata) + 2;
@@ -1051,18 +1065,37 @@ void update_undo(undo_type action)
        fprintf(stderr, "current undo data now \"%s\"\nu->begin = %d\n", u->strdata, u->begin);
 #endif
        break;
+    case CUT_EOF:
     case CUT:
        if (!cutbuffer)
            break;
        if (u->cutbuffer)
            free(u->cutbuffer);
        u->cutbuffer = copy_filestruct(cutbuffer);
-        /* Compute cutbottom for the uncut using our copy. */
-        for (u->cutbottom = u->cutbuffer; u->cutbottom->next != NULL; u->cutbottom = u->cutbottom->next)
-            ;
+       if (u->mark_set) {
+           /* If the "marking" operation was from right-->left or
+            * bottom-->top, then swap the mark points. */
+           if ((u->lineno == u->mark_begin_lineno && u->begin < u->mark_begin_x)
+                       || u->lineno < u->mark_begin_lineno) {
+               size_t x_loc = u->begin;
+               u->begin = u->mark_begin_x;
+               u->mark_begin_x = x_loc;
+
+               ssize_t line = u->lineno;
+               u->lineno = u->mark_begin_lineno;
+               u->mark_begin_lineno = line;
+           }
+       } else if (!ISSET(CUT_TO_END)) {
+           /* Compute cutbottom for the uncut using our copy. */
+           u->cutbottom = u->cutbuffer;
+           while (u->cutbottom->next != NULL)
+               u->cutbottom = u->cutbottom->next;
+           if (!u->to_end)
+               u->lineno++;
+       }
        break;
     case REPLACE:
-    case UNCUT:
+    case PASTE:
        add_undo(action);
        break;
     case INSERT:
@@ -1085,14 +1118,8 @@ void update_undo(undo_type action)
 #ifdef DEBUG
     fprintf(stderr, "Done in update_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 */
 
index dda90c76d5c094fecd13afae1b4343da2a15a4bb..3aab3fc0630e005b35ab2d3c4e5eb9be3ad062d7 100644 (file)
@@ -476,7 +476,10 @@ size_t get_page_start(size_t column)
  * current_x. */
 size_t xplustabs(void)
 {
-    return strnlenpt(openfile->current->data, openfile->current_x);
+    if (openfile->current)
+       return strnlenpt(openfile->current->data, openfile->current_x);
+    else
+       return 0;
 }
 
 /* Return the index in s of the character displayed at the given column,