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-d3aeb78583b8master
parent
e137f12e5e
commit
b549f3761a
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
153
src/text.c
153
src/text.c
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue