Index: src/chars.c =================================================================== --- src/chars.c (revision 4905) +++ src/chars.c (working copy) @@ -43,6 +43,17 @@ static const char *const bad_mbchar = "\xEF\xBF\xBD"; static const int bad_mbchar_len = 3; +/*add two allocated strings*/ +char* addstrings(char* str1, size_t len1, char* str2, size_t len2) +{ + size_t len = len1 + len2 + 1; + str1 = charealloc(str1, len); + str1[len1] = '\0'; + strncat(&str1[len1], str2, len2); + free(str2); + return str1; +} + /* Enable UTF-8 support. */ void utf8_init(void) { Index: src/cut.c =================================================================== --- src/cut.c (revision 4905) +++ src/cut.c (working copy) @@ -274,6 +274,10 @@ * at the current cursor position. */ copy_from_filestruct(cutbuffer); +#ifndef NANO_TINY + update_undo(PASTE); +#endif + /* Set the current place we want to where the text from the * cutbuffer ends. */ openfile->placewewant = xplustabs(); Index: src/proto.h =================================================================== --- src/proto.h (revision 4905) +++ src/proto.h (working copy) @@ -162,6 +162,7 @@ void utf8_init(void); bool using_utf8(void); #endif +char *addstrings(char* str1, size_t len1, char* str2, size_t len2); #ifndef HAVE_ISBLANK bool nisblank(int c); #endif Index: src/text.c =================================================================== --- src/text.c (revision 4905) +++ src/text.c (working copy) @@ -460,8 +460,6 @@ strcpy(&data[u->begin + strlen(u->strdata)], &f->data[u->begin]); free(f->data); 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 @@ -879,15 +877,13 @@ /* We need to start copying data into the undo buffer * or we won't be able to restore it later. */ case ADD: - data = charalloc(2); - data[0] = '\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; + char *char_buf = charalloc(mb_cur_max()+1); + int char_buf_len = parse_mbchar(&fs->current->data[u->begin], char_buf, NULL); + char_buf[char_buf_len] = '\0'; + u->strdata = char_buf;//Note: there is likely more memory allocated than necessary break; } /* Else purposely fall into unsplit code. */ @@ -942,18 +938,6 @@ 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; @@ -979,8 +963,6 @@ void update_undo(undo_type action) { undo *u; - char *data; - int len = 0; openfilestruct *fs = openfile; if (!ISSET(UNDOABLE)) @@ -1008,61 +990,41 @@ u = fs->undotop; switch (u->type) { - case ADD: + case ADD:{ #ifdef DEBUG fprintf(stderr, "fs->current->data = \"%s\", current_x = %lu, u->begin = %d\n", fs->current->data, (unsigned long) fs->current_x, u->begin); #endif - len = strlen(u->strdata) + 2; - data = (char *) nrealloc((void *) u->strdata, len * sizeof(char *)); - data[len-2] = fs->current->data[fs->current_x - 1]; - data[len-1] = '\0'; - u->strdata = (char *) data; + char *char_buf = charalloc(mb_cur_max()); + size_t char_buf_len = parse_mbchar( &fs->current->data[fs->current_x-1], char_buf, NULL); + u->strdata = addstrings(u->strdata, u->strdata?strlen(u->strdata):0, char_buf, char_buf_len); #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; - assert(len > 2); - if (fs->current_x == u->begin) { + case DEL:{ + char *char_buf = charalloc(mb_cur_max()); + size_t char_buf_len = parse_mbchar( &fs->current->data[fs->current_x], char_buf, NULL); + if (fs->current_x == u->begin) /* They're deleting. */ - if (!u->xflags) - u->xflags = UNdel_del; - else if (u->xflags != UNdel_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) { + u->strdata = addstrings(u->strdata, strlen(u->strdata), char_buf, char_buf_len); + else if (fs->current_x == u->begin - char_buf_len){ /* They're backspacing. */ - if (!u->xflags) - u->xflags = UNdel_backspace; - else if (u->xflags != UNdel_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--; + u->strdata = addstrings(char_buf, char_buf_len, u->strdata, strlen(u->strdata) ); + u->begin = fs->current_x; } else { /* They deleted something else on the line. */ + free(char_buf); 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_EOF: case CUT: @@ -1095,7 +1057,8 @@ break; case REPLACE: case PASTE: - add_undo(action); + u->begin = fs->current_x; + u->lineno = openfile->current->lineno; break; case INSERT: u->mark_begin_lineno = openfile->current->lineno;