mirror of
git://git.sv.gnu.org/nano.git
synced 2024-11-22 12:51:23 +03:00
- 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:
parent
3c1131a5b3
commit
14c8620e0b
@ -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);
|
||||
}
|
||||
|
25
src/files.c
25
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
51
src/text.c
51
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;
|
||||
}
|
||||
|
18
src/utils.c
18
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user