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.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4327 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2008-09-16 21:35:19 +00:00
parent e137f12e5e
commit b549f3761a
3 changed files with 102 additions and 60 deletions

View File

@ -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> 2008-09-06 Chris Allegretta <chrisa@asty.org>
* nano.c: Do call disable_signals at startup regardless, since under cygwin we can't generate * nano.c: Do call disable_signals at startup regardless, since under cygwin we can't generate
^C without it. ^C without it.

View File

@ -260,6 +260,10 @@ void do_uncut_text(void)
if (cutbuffer == NULL) if (cutbuffer == NULL)
return; return;
#ifndef NANO_TINY
update_undo(UNCUT);
#endif
/* Add a copy of the text in the cutbuffer to the current filestruct /* Add a copy of the text in the cutbuffer to the current filestruct
* at the current cursor position. */ * at the current cursor position. */
copy_from_filestruct(cutbuffer, cutbottom); copy_from_filestruct(cutbuffer, cutbottom);

View File

@ -364,6 +364,70 @@ void do_unindent(void)
do_indent(-tabsize); 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 */ /* Undo the last thing(s) we did */
void do_undo(void) void do_undo(void)
{ {
@ -443,21 +507,11 @@ void do_undo(void)
case CUT: case CUT:
case CUTTOEND: case CUTTOEND:
undidmsg = _("text cut"); undidmsg = _("text cut");
cutbuffer = copy_filestruct(u->cutbuffer); undo_cut(u);
break;
/* Compute cutbottom for the uncut using out copy */ case UNCUT:
for (cutbottom = cutbuffer; cutbottom->next != NULL; cutbottom = cutbottom->next) undidmsg = _("text uncut");
; redo_cut(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);
do_uncut_text();
free_filestruct(cutbuffer);
cutbuffer = NULL;
break; break;
case INSERT: case INSERT:
undidmsg = _("text insert"); undidmsg = _("text insert");
@ -576,43 +630,12 @@ void do_redo(void)
break; break;
case CUT: case CUT:
case CUTTOEND: case CUTTOEND:
undidmsg = _("line cut"); undidmsg = _("text cut");
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE); redo_cut(u);
openfile->mark_set = u->mark_set; break;
if (cutbuffer) case UNCUT:
free(cutbuffer); undidmsg = _("text uncut");
cutbuffer = NULL; undo_cut(u);
/* 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; break;
case REPLACE: case REPLACE:
undidmsg = _("text replace"); undidmsg = _("text replace");
@ -622,12 +645,9 @@ void do_redo(void)
break; break;
case INSERT: case INSERT:
undidmsg = _("text insert"); undidmsg = _("text insert");
cutbuffer = u->cutbuffer;
cutbottom = u->cutbottom;
do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE); do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE);
do_uncut_text(); copy_from_filestruct(u->cutbuffer, u->cutbottom);
cutbuffer = oldcutbuffer; openfile->placewewant = xplustabs();
cutbottom = oldcutbottom;
break; break;
default: default:
undidmsg = _("Internal error: unknown type. Please save your work"); 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 */ /* Add a new undo struct to the top of the current pile */
void add_undo(undo_type current_action) void add_undo(undo_type current_action)
{ {
undo *u; undo *u, *cutu;
char *data; char *data;
openfilestruct *fs = openfile; openfilestruct *fs = openfile;
@ -832,6 +852,7 @@ void add_undo(undo_type current_action)
u->strdata = NULL; u->strdata = NULL;
u->cutbuffer = NULL; u->cutbuffer = NULL;
u->cutbottom = NULL; u->cutbottom = NULL;
u->mark_set = 0;
u->mark_begin_lineno = 0; u->mark_begin_lineno = 0;
u->mark_begin_x = 0; u->mark_begin_x = 0;
u->linescut = 0; u->linescut = 0;
@ -877,6 +898,20 @@ void add_undo(undo_type current_action)
u->to_end = (current_action == CUTTOEND); u->to_end = (current_action == CUTTOEND);
break; break;
case UNCUT: 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; break;
case OTHER: case OTHER:
statusbar(_("Internal error: unknown type. Please save your work.")); statusbar(_("Internal error: unknown type. Please save your work."));
@ -981,7 +1016,6 @@ void update_undo(undo_type action)
break; break;
case CUT: case CUT:
case CUTTOEND: case CUTTOEND:
case UNCUT:
if (u->cutbuffer) if (u->cutbuffer)
free(u->cutbuffer); free(u->cutbuffer);
u->cutbuffer = copy_filestruct(cutbuffer); u->cutbuffer = copy_filestruct(cutbuffer);
@ -989,6 +1023,7 @@ void update_undo(undo_type action)
u->linescut++; u->linescut++;
break; break;
case REPLACE: case REPLACE:
case UNCUT:
add_undo(action); add_undo(action);
break; break;
case INSERT: case INSERT: