- Change add_undo and current_undo to only take action arg, as openfilestruct arg is always openfile

- Add ability to undo a file/cmd insert, needed to add undoable flag to read_file and open_buffer as a result



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4291 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
Chris Allegretta 2008-08-03 04:48:05 +00:00
parent 3c1131a5b3
commit 14c8620e0b
8 changed files with 85 additions and 36 deletions

View File

@ -205,7 +205,7 @@ void do_cut_text(
if (!old_no_newlines)
UNSET(NO_NEWLINES);
} else if (!undoing)
update_undo(CUT, openfile);
update_undo(CUT);
#endif
/* Leave the text in the cutbuffer, and mark the file as
* modified. */
@ -224,7 +224,7 @@ void do_cut_text(
void do_cut_text_void(void)
{
#ifndef NANO_TINY
add_undo(CUT, openfile);
add_undo(CUT);
#endif
do_cut_text(
#ifndef NANO_TINY
@ -245,7 +245,7 @@ void do_copy_text(void)
void do_cut_till_end(void)
{
#ifndef NANO_TINY
add_undo(CUTTOEND, openfile);
add_undo(CUTTOEND);
#endif
do_cut_text(FALSE, TRUE, FALSE);
}

View File

@ -101,7 +101,7 @@ void initialize_buffer_text(void)
/* If it's not "", filename is a file to open. We make a new buffer, if
* necessary, and then open and read the file, if applicable. */
void open_buffer(const char *filename)
void open_buffer(const char *filename, bool undoable)
{
bool new_buffer = (openfile == NULL
#ifdef ENABLE_MULTIBUFFER
@ -142,7 +142,7 @@ void open_buffer(const char *filename)
/* If we have a non-new file, read it in. Then, if the buffer has
* no stat, update the stat, if applicable. */
if (rc == 0) {
read_file(f, filename);
read_file(f, filename, undoable);
#ifndef NANO_TINY
if (openfile->current_stat == NULL) {
openfile->current_stat =
@ -192,7 +192,7 @@ void replace_buffer(const char *filename)
/* If we have a non-new file, read it in. */
if (rc == 0)
read_file(f, filename);
read_file(f, filename, FALSE);
/* Move back to the beginning of the first line of the buffer. */
openfile->current = openfile->fileage;
@ -339,8 +339,9 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
}
/* Read an open file into the current buffer. f should be set to the
* open file, and filename should be set to the name of the file. */
void read_file(FILE *f, const char *filename)
* open file, and filename should be set to the name of the file.
undoable means do we want to create undo records to try and undo this */
void read_file(FILE *f, const char *filename, bool undoable)
{
size_t num_lines = 0;
/* The number of lines in the file. */
@ -371,6 +372,11 @@ void read_file(FILE *f, const char *filename)
buf = charalloc(bufx);
buf[0] = '\0';
#ifndef NANO_TINY
if (undoable)
add_undo(INSERT);
#endif
if (openfile->current == openfile->fileage)
first_line_ins = TRUE;
else
@ -489,7 +495,7 @@ void read_file(FILE *f, const char *filename)
/* If we didn't get a file and we don't already have one, open a
* blank buffer. */
if (fileptr == NULL)
open_buffer("");
open_buffer("", FALSE);
/* Attach the file we got to the filestruct. If we got a file of
* zero bytes, don't do anything. */
@ -561,6 +567,9 @@ void read_file(FILE *f, const char *filename)
openfile->placewewant = xplustabs();
#ifndef NANO_TINY
if (undoable)
update_undo(INSERT);
if (format == 3)
statusbar(
P_("Read %lu line (Converted from DOS and Mac format)",
@ -853,7 +862,7 @@ void do_insertfile(
#ifdef ENABLE_MULTIBUFFER
if (ISSET(MULTIBUFFER))
/* Open a blank buffer. */
open_buffer("");
open_buffer("", FALSE);
#endif
/* Save the command's output in the current buffer. */
@ -877,7 +886,7 @@ void do_insertfile(
/* Save the file specified in answer in the current
* buffer. */
open_buffer(answer);
open_buffer(answer, TRUE);
#ifndef NANO_TINY
}
#endif

View File

@ -1647,7 +1647,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
set_modified();
#ifndef NANO_TINY
update_undo(ADD, openfile);
update_undo(ADD);
/* Note that current_x has not yet been incremented. */
@ -2232,7 +2232,7 @@ int main(int argc, char **argv)
icol == 1)
parse_line_column(&argv[i][1], &iline, &icol);
else {
open_buffer(argv[i]);
open_buffer(argv[i], FALSE);
if (iline > 1 || icol > 1) {
do_gotolinecolumn(iline, icol, FALSE, FALSE, FALSE,
@ -2249,14 +2249,14 @@ int main(int argc, char **argv)
* buffer or a new buffer, depending on whether multibuffer mode is
* enabled. */
if (optind < argc)
open_buffer(argv[optind]);
open_buffer(argv[optind], FALSE);
/* We didn't open any files if all the command line arguments were
* invalid files like directories or if there were no command line
* arguments given. In this case, we have to load a blank buffer.
* Also, we unset view mode to allow editing. */
if (openfile == NULL) {
open_buffer("");
open_buffer("", FALSE);
UNSET(VIEW_MODE);
}

View File

@ -170,7 +170,7 @@ typedef enum {
} function_type;
typedef enum {
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, CUTTOEND, UNCUT, OTHER
ADD, DEL, REPLACE, SPLIT, UNSPLIT, CUT, CUTTOEND, UNCUT, INSERT, OTHER
} undo_type;
/* Structure types. */

View File

@ -255,7 +255,7 @@ void do_uncut_text(void);
void make_new_buffer(void);
void initialize_buffer(void);
void initialize_buffer_text(void);
void open_buffer(const char *filename);
void open_buffer(const char *filename, bool undoable);
#ifndef DISABLE_SPELLER
void replace_buffer(const char *filename);
#endif
@ -268,7 +268,7 @@ bool close_buffer(void);
#endif
filestruct *read_line(char *buf, filestruct *prevnode, bool
*first_line_ins, size_t buf_len);
void read_file(FILE *f, const char *filename);
void read_file(FILE *f, const char *filename, bool undoable);
int open_file(const char *filename, bool newfie, FILE **f);
char *get_next_filename(const char *name, const char *suffix);
void do_insertfile(
@ -707,10 +707,11 @@ void new_magicline(void);
void remove_magicline(void);
void mark_order(const filestruct **top, size_t *top_x, const filestruct
**bot, size_t *bot_x, bool *right_side_up);
void add_undo(undo_type current_action, openfilestruct *fs);
void update_undo(undo_type action, openfilestruct *fs);
void add_undo(undo_type current_action);
void update_undo(undo_type action);
#endif
size_t get_totsize(const filestruct *begin, const filestruct *end);
filestruct *fsfromline(ssize_t lineno);
#ifdef DEBUG
void dump_filestruct(const filestruct *inptr);
void dump_filestruct_reverse(void);

View File

@ -789,7 +789,7 @@ ssize_t do_replace_loop(
size_t length_change;
#ifndef NANO_TINY
update_undo(REPLACE, openfile);
update_undo(REPLACE);
#endif
if (i == 2)
replaceall = TRUE;

View File

@ -71,7 +71,7 @@ void do_delete(void)
* just update_line()? */
#ifndef NANO_TINY
update_undo(DEL, openfile);
update_undo(DEL);
#endif
assert(openfile->current != NULL && openfile->current->data != NULL && openfile->current_x <= strlen(openfile->current->data));
@ -371,6 +371,7 @@ void do_undo(void)
filestruct *f = openfile->current, *t;
int len = 0;
char *undidmsg, *data;
filestruct *oldcutbuffer = cutbuffer, *oldcutbottom = cutbottom;
if (!u) {
statusbar(_("Nothing in undo buffer!"));
@ -458,6 +459,24 @@ void do_undo(void)
free_filestruct(cutbuffer);
cutbuffer = NULL;
break;
case INSERT:
undidmsg = _("text insert");
cutbuffer = NULL;
cutbottom = NULL;
/* When we updated mark_begin_lineno in update_undo, it was effectively how many line
were inserted due to being partitioned before read_file was called. So we
add its value here */
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);
cut_marked();
u->cutbuffer = cutbuffer;
u->cutbottom = cutbottom;
cutbuffer = oldcutbuffer;
cutbottom = oldcutbottom;
openfile->mark_set = FALSE;
break;
case REPLACE:
undidmsg = _("text replace");
data = u->strdata;
@ -622,7 +641,7 @@ void do_enter(void)
assert(openfile->current != NULL && xopenfile->current->data != NULL);
#ifndef NANO_TINY
update_undo(SPLIT, openfile);
update_undo(SPLIT);
/* Do auto-indenting, like the neolithic Turbo Pascal editor. */
@ -750,7 +769,7 @@ bool execute_command(const char *command)
if (f == NULL)
nperror("fdopen");
read_file(f, "stdin");
read_file(f, "stdin", TRUE);
if (wait(NULL) == -1)
nperror("wait");
@ -767,10 +786,11 @@ bool execute_command(const char *command)
}
/* 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)
{
undo *u;
char *data;
openfilestruct *fs = openfile;
/* Ugh, if we were called while cutting not-to-end, non-marked and on the same lineno,
we need to abort here */
@ -831,12 +851,11 @@ void add_undo(undo_type current_action, openfilestruct *fs)
data = mallocstrcpy(NULL, fs->current->next->data);
u->strdata = data;
}
u->begin = fs->current_x;
break;
case INSERT:
case SPLIT:
case REPLACE:
data = mallocstrcpy(NULL, fs->current->data);
u->begin = fs->current_x;
u->strdata = data;
break;
case CUT:
@ -868,12 +887,12 @@ void add_undo(undo_type current_action, openfilestruct *fs)
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)
{
undo *u;
char *data;
int len = 0;
openfilestruct *fs = openfile;
#ifdef DEBUG
fprintf(stderr, "action = %d, fs->last_action = %d, openfile->current->lineno = %d",
@ -887,9 +906,9 @@ void update_undo(undo_type action, openfilestruct *fs)
/* 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
|| (action != CUT && action != CUTTOEND && action != INSERT
&& openfile->current->lineno != fs->current_undo->lineno)) {
add_undo(action, fs);
add_undo(action);
return;
}
@ -919,7 +938,7 @@ void update_undo(undo_type action, openfilestruct *fs)
if (!u->xflags)
u->xflags = UNDO_DEL_DEL;
else if (u->xflags != UNDO_DEL_DEL) {
add_undo(action, fs);
add_undo(action);
return;
}
data = charalloc(len);
@ -933,7 +952,7 @@ void update_undo(undo_type action, openfilestruct *fs)
if (!u->xflags)
u->xflags = UNDO_DEL_BACKSPACE;
else if (u->xflags != UNDO_DEL_BACKSPACE) {
add_undo(action, fs);
add_undo(action);
return;
}
data = charalloc(len);
@ -944,7 +963,7 @@ void update_undo(undo_type action, openfilestruct *fs)
u->begin--;
} else {
/* They deleted something else on the line */
add_undo(DEL, fs);
add_undo(DEL);
return;
}
#ifdef DEBUG
@ -961,8 +980,10 @@ void update_undo(undo_type action, openfilestruct *fs)
u->linescut++;
break;
case REPLACE:
add_undo(action, fs);
add_undo(action);
break;
case INSERT:
u->mark_begin_lineno = openfile->current->lineno;
case SPLIT:
case UNSPLIT:
/* These cases are handled by the earlier check for a new line and action */
@ -977,7 +998,7 @@ void update_undo(undo_type action, openfilestruct *fs)
#ifdef DEBUG
fprintf(stderr, "Starting add_undo for new action as it does not match last_action\n");
#endif
add_undo(action, openfile);
add_undo(action);
}
fs->last_action = action;
}

View File

@ -603,6 +603,24 @@ void dump_filestruct(const filestruct *inptr)
}
}
/* Get back a pointer given a line number in the current openfilestruct */
filestruct *fsfromline(ssize_t lineno)
{
filestruct *f = openfile->current;
if (lineno <= openfile->current->lineno)
for (; f->lineno != lineno && f != openfile->fileage; f = f->prev)
;
else
for (; f->lineno != lineno && f->next != NULL; f = f->next)
if (f->lineno != lineno)
return NULL;
return f;
}
/* Dump the current buffer's filestruct to stderr in reverse. */
void dump_filestruct_reverse(void)
{