Commit 12dc8cae authored by Chris Allegretta's avatar Chris Allegretta
Browse files

Commit back some undo/redo rewrites


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4283 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
No related merge requests found
Showing with 110 additions and 42 deletions
+110 -42
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
static bool keep_cutbuffer = FALSE; static bool keep_cutbuffer = FALSE;
/* Should we keep the contents of the cutbuffer? */ /* Should we keep the contents of the cutbuffer? */
static filestruct *cutbottom = NULL;
/* Pointer to the end of the cutbuffer. */ /* Pointer to the end of the cutbuffer. */
/* Indicate that we should no longer keep the contents of the /* Indicate that we should no longer keep the contents of the
...@@ -163,6 +162,7 @@ void do_cut_text( ...@@ -163,6 +162,7 @@ void do_cut_text(
keep_cutbuffer = TRUE; keep_cutbuffer = TRUE;
#ifndef NANO_TINY #ifndef NANO_TINY
if (cut_till_end) { if (cut_till_end) {
/* If cut_till_end is TRUE, move all text up to the end of the /* If cut_till_end is TRUE, move all text up to the end of the
* file into the cutbuffer. */ * file into the cutbuffer. */
...@@ -205,11 +205,13 @@ void do_cut_text( ...@@ -205,11 +205,13 @@ void do_cut_text(
if (!old_no_newlines) if (!old_no_newlines)
UNSET(NO_NEWLINES); UNSET(NO_NEWLINES);
} else } else
update_undo(CUT, openfile);
#endif #endif
/* Leave the text in the cutbuffer, and mark the file as /* Leave the text in the cutbuffer, and mark the file as
* modified. */ * modified. */
set_modified(); set_modified();
/* Update the screen. */ /* Update the screen. */
edit_refresh(); edit_refresh();
...@@ -221,6 +223,7 @@ void do_cut_text( ...@@ -221,6 +223,7 @@ void do_cut_text(
/* Move text from the current filestruct into the cutbuffer. */ /* Move text from the current filestruct into the cutbuffer. */
void do_cut_text_void(void) void do_cut_text_void(void)
{ {
add_undo(CUT, openfile);
do_cut_text( do_cut_text(
#ifndef NANO_TINY #ifndef NANO_TINY
FALSE, FALSE FALSE, FALSE
...@@ -239,6 +242,7 @@ void do_copy_text(void) ...@@ -239,6 +242,7 @@ void do_copy_text(void)
/* Cut from the current cursor position to the end of the file. */ /* Cut from the current cursor position to the end of the file. */
void do_cut_till_end(void) void do_cut_till_end(void)
{ {
add_undo(CUTTOEND, openfile);
do_cut_text(FALSE, TRUE); do_cut_text(FALSE, TRUE);
} }
#endif /* !NANO_TINY */ #endif /* !NANO_TINY */
......
...@@ -69,6 +69,7 @@ int editwinrows = 0; ...@@ -69,6 +69,7 @@ int editwinrows = 0;
filestruct *cutbuffer = NULL; filestruct *cutbuffer = NULL;
/* The buffer where we store cut text. */ /* The buffer where we store cut text. */
filestruct *cutbottom = NULL;
#ifndef DISABLE_JUSTIFY #ifndef DISABLE_JUSTIFY
filestruct *jusbuffer = NULL; filestruct *jusbuffer = NULL;
/* The buffer where we store unjustified text. */ /* The buffer where we store unjustified text. */
......
...@@ -170,7 +170,7 @@ typedef enum { ...@@ -170,7 +170,7 @@ typedef enum {
} function_type; } function_type;
typedef enum { typedef enum {
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, UNCUT, OTHER ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, CUTTOEND, UNCUT, OTHER
} undo_type; } undo_type;
/* Structure types. */ /* Structure types. */
...@@ -251,20 +251,37 @@ typedef struct syntaxtype { ...@@ -251,20 +251,37 @@ typedef struct syntaxtype {
#ifndef NANO_TINY #ifndef NANO_TINY
typedef struct undo { typedef struct undo {
ssize_t lineno;
undo_type type; undo_type type;
filestruct *fs; /* What type of undo was this */
int begin; int begin;
/* Where did this action begin or end */ /* Where did this action begin or end */
char *strdata; char *strdata;
/* Generic pointer for data regardless of what type it is */ /* String type data we will use for ccopying the affected line back */
filestruct *fsdata;
/* Generic pointer for data regardless of what type it is */
struct undo *next;
ssize_t lineno;
int xflags; 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; } undo;
#endif /* NANO_TINY */ #endif /* NANO_TINY */
typedef struct openfilestruct { typedef struct openfilestruct {
char *filename; char *filename;
/* The current file's name. */ /* The current file's name. */
......
...@@ -47,6 +47,7 @@ extern WINDOW *bottomwin; ...@@ -47,6 +47,7 @@ extern WINDOW *bottomwin;
extern int editwinrows; extern int editwinrows;
extern filestruct *cutbuffer; extern filestruct *cutbuffer;
extern filestruct *cutbottom;
#ifndef DISABLE_JUSTIFY #ifndef DISABLE_JUSTIFY
extern filestruct *jusbuffer; extern filestruct *jusbuffer;
#endif #endif
......
...@@ -368,9 +368,9 @@ void do_unindent(void) ...@@ -368,9 +368,9 @@ void do_unindent(void)
void do_undo(void) void do_undo(void)
{ {
undo *u = openfile->current_undo; undo *u = openfile->current_undo;
filestruct *f = openfile->current, *t; filestruct *f = openfile->current, *t, *t2;
int len = 0; int len = 0;
char *action, *data; char *undidmsg, *data;
if (!u) { if (!u) {
statusbar(_("Nothing in undo buffer!")); statusbar(_("Nothing in undo buffer!"));
...@@ -396,7 +396,7 @@ void do_undo(void) ...@@ -396,7 +396,7 @@ void do_undo(void)
openfile->current_x = u->begin; openfile->current_x = u->begin;
switch(u->type) { switch(u->type) {
case ADD: case ADD:
action = _("text add"); undidmsg = _("text add");
len = strlen(f->data) - strlen(u->strdata) + 1; len = strlen(f->data) - strlen(u->strdata) + 1;
data = charalloc(len); data = charalloc(len);
strncpy(data, f->data, u->begin); strncpy(data, f->data, u->begin);
...@@ -405,7 +405,7 @@ void do_undo(void) ...@@ -405,7 +405,7 @@ void do_undo(void)
f->data = data; f->data = data;
break; break;
case DEL: case DEL:
action = _("text delete"); undidmsg = _("text delete");
len = strlen(f->data) + strlen(u->strdata) + 1; len = strlen(f->data) + strlen(u->strdata) + 1;
data = charalloc(len); data = charalloc(len);
...@@ -418,7 +418,7 @@ void do_undo(void) ...@@ -418,7 +418,7 @@ void do_undo(void)
openfile->current_x += strlen(u->strdata); openfile->current_x += strlen(u->strdata);
break; break;
case SPLIT: case SPLIT:
action = _("line split"); undidmsg = _("line split");
free(f->data); free(f->data);
f->data = mallocstrcpy(NULL, u->strdata); f->data = mallocstrcpy(NULL, u->strdata);
if (f->next != NULL) { if (f->next != NULL) {
...@@ -429,7 +429,7 @@ void do_undo(void) ...@@ -429,7 +429,7 @@ void do_undo(void)
renumber(f); renumber(f);
break; break;
case UNSPLIT: case UNSPLIT:
action = _("line join"); undidmsg = _("line join");
t = make_new_node(f); t = make_new_node(f);
t->data = mallocstrcpy(NULL, u->strdata); t->data = mallocstrcpy(NULL, u->strdata);
data = mallocstrncpy(NULL, f->data, u->begin); data = mallocstrncpy(NULL, f->data, u->begin);
...@@ -439,14 +439,26 @@ void do_undo(void) ...@@ -439,14 +439,26 @@ void do_undo(void)
splice_node(f, t, f->next); splice_node(f, t, f->next);
renumber(f); renumber(f);
break; 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: default:
action = _("wtf?"); undidmsg = _("wtf?");
break; break;
} }
openfile->current = f; do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
edit_refresh(); statusbar(_("Undid action (%s)"), undidmsg);
statusbar(_("Undid action (%s)"), action);
openfile->current_undo = openfile->current_undo->next; openfile->current_undo = openfile->current_undo->next;
} }
...@@ -454,9 +466,9 @@ void do_undo(void) ...@@ -454,9 +466,9 @@ void do_undo(void)
void do_redo(void) void do_redo(void)
{ {
undo *u = openfile->undotop; undo *u = openfile->undotop;
filestruct *f = openfile->current, *t; filestruct *f = openfile->current, *t, *t2;
int len = 0; int len = 0, i, i2;
char *action, *data; char *undidmsg, *data;
for (; u != NULL && u->next != openfile->current_undo; u = u->next) for (; u != NULL && u->next != openfile->current_undo; u = u->next)
; ;
...@@ -486,7 +498,7 @@ void do_redo(void) ...@@ -486,7 +498,7 @@ void do_redo(void)
switch(u->type) { switch(u->type) {
case ADD: case ADD:
action = _("text add"); undidmsg = _("text add");
len = strlen(f->data) + strlen(u->strdata) + 1; len = strlen(f->data) + strlen(u->strdata) + 1;
data = charalloc(len); data = charalloc(len);
strcpy(&data[u->begin], u->strdata); strcpy(&data[u->begin], u->strdata);
...@@ -495,7 +507,7 @@ void do_redo(void) ...@@ -495,7 +507,7 @@ void do_redo(void)
f->data = data; f->data = data;
break; break;
case DEL: case DEL:
action = _("text delete"); undidmsg = _("text delete");
len = strlen(f->data) + strlen(u->strdata) + 1; len = strlen(f->data) + strlen(u->strdata) + 1;
data = charalloc(len); data = charalloc(len);
strncpy(data, f->data, u->begin); strncpy(data, f->data, u->begin);
...@@ -504,7 +516,7 @@ void do_redo(void) ...@@ -504,7 +516,7 @@ void do_redo(void)
f->data = data; f->data = data;
break; break;
case SPLIT: case SPLIT:
action = _("line split"); undidmsg = _("line split");
t = make_new_node(f); t = make_new_node(f);
t->data = mallocstrcpy(NULL, u->strdata); t->data = mallocstrcpy(NULL, u->strdata);
data = mallocstrncpy(NULL, f->data, u->begin); data = mallocstrncpy(NULL, f->data, u->begin);
...@@ -515,7 +527,7 @@ void do_redo(void) ...@@ -515,7 +527,7 @@ void do_redo(void)
renumber(f); renumber(f);
break; break;
case UNSPLIT: case UNSPLIT:
action = _("line join"); undidmsg = _("line join");
len = strlen(f->data) + strlen(u->strdata + 1); len = strlen(f->data) + strlen(u->strdata + 1);
data = charalloc(len); data = charalloc(len);
strcpy(data, f->data); strcpy(data, f->data);
...@@ -529,15 +541,33 @@ void do_redo(void) ...@@ -529,15 +541,33 @@ void do_redo(void)
} }
renumber(f); renumber(f);
break; 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: default:
action = _("wtf?"); undidmsg = _("wtf?");
break; break;
} }
openfile->current = f; do_gotolinecolumn(u->lineno, u->begin, FALSE, FALSE, FALSE, TRUE);
openfile->current_x = u->begin; statusbar(_("Redid action (%s)"), undidmsg);
edit_refresh();
statusbar(_("Redid action (%s)"), action);
openfile->current_undo = u; openfile->current_undo = u;
...@@ -697,6 +727,7 @@ bool execute_command(const char *command) ...@@ -697,6 +727,7 @@ bool execute_command(const char *command)
return TRUE; return TRUE;
} }
/* Add a new undo struct to the top of the current pile */
void add_undo(undo_type current_action, openfilestruct *fs) void add_undo(undo_type current_action, openfilestruct *fs)
{ {
undo *u = nmalloc(sizeof(undo)); undo *u = nmalloc(sizeof(undo));
...@@ -713,8 +744,6 @@ void add_undo(undo_type current_action, openfilestruct *fs) ...@@ -713,8 +744,6 @@ void add_undo(undo_type current_action, openfilestruct *fs)
u->type = current_action; u->type = current_action;
u->lineno = fs->current->lineno; u->lineno = fs->current->lineno;
u->begin = fs->current_x; u->begin = fs->current_x;
u->fs = fs->current;
u->xflags = 0;
u->next = fs->undotop; u->next = fs->undotop;
fs->undotop = u; fs->undotop = u;
fs->current_undo = u; fs->current_undo = u;
...@@ -746,27 +775,44 @@ void add_undo(undo_type current_action, openfilestruct *fs) ...@@ -746,27 +775,44 @@ void add_undo(undo_type current_action, openfilestruct *fs)
break; break;
case SPLIT: case SPLIT:
data = mallocstrcpy(NULL, fs->current->data); data = mallocstrcpy(NULL, fs->current->data);
u->strdata = data;
u->begin = fs->current_x; 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; break;
} }
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "fs->current->data = \"%s\", current_x = %d, u->begin = %d, type = %d\n", 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); fs->current->data, fs->current_x, u->begin, current_action);
fprintf(stderr, "u->strdata = \"%s\"\n", u->strdata);
fprintf(stderr, "left update_add...\n"); fprintf(stderr, "left update_add...\n");
#endif #endif
fs->last_action = current_action; 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) void update_undo(undo_type action, openfilestruct *fs)
{ {
undo *u; undo *u;
char *data; char *data;
int len = 0; 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); add_undo(action, fs);
return; return;
} }
...@@ -774,13 +820,6 @@ void update_undo(undo_type action, openfilestruct *fs) ...@@ -774,13 +820,6 @@ void update_undo(undo_type action, openfilestruct *fs)
assert(fs->undotop != NULL); assert(fs->undotop != NULL);
u = fs->undotop; u = fs->undotop;
if (u->fs->data != openfile->current->data || u->lineno != openfile->current->lineno) {
add_undo(action, fs);
return;
}
switch (u->type) { switch (u->type) {
case ADD: case ADD:
#ifdef DEBUG #ifdef DEBUG
...@@ -836,6 +875,12 @@ void update_undo(undo_type action, openfilestruct *fs) ...@@ -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); fprintf(stderr, "current undo data now \"%s\"\nu->begin = %d\n", u->strdata, u->begin);
#endif #endif
break; break;
case CUT:
case CUTTOEND:
case UNCUT:
u->cutbuffer = copy_filestruct(cutbuffer);
u->cutbottom = cutbottom;
break;
case SPLIT: case SPLIT:
case UNSPLIT: case UNSPLIT:
/* We don't really ever update an enter key press, treat it as a new */ /* We don't really ever update an enter key press, treat it as a new */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment