commit 14c8620e0b08fefede6261b5ddee657694bf9314
parent 3c1131a5b37bc81a22e8275625016f2269aff993
Author: Chris Allegretta <chrisa@asty.org>
Date: Sun, 3 Aug 2008 04:48:05 +0000
- 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
Diffstat:
8 files changed, 85 insertions(+), 36 deletions(-)
diff --git a/src/cut.c b/src/cut.c
@@ -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);
}
diff --git a/src/files.c b/src/files.c
@@ -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
diff --git a/src/nano.c b/src/nano.c
@@ -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);
}
diff --git a/src/nano.h b/src/nano.h
@@ -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. */
diff --git a/src/proto.h b/src/proto.h
@@ -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);
diff --git a/src/search.c b/src/search.c
@@ -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;
diff --git a/src/text.c b/src/text.c
@@ -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;
}
diff --git a/src/utils.c b/src/utils.c
@@ -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)
{