undo: generalize update_comment_undo() into update_multiline_undo()
The function does not contain any comment-specific code, so it can be used to handle any kind of multiline undo item. Also, extend the undo group structure to contain an array of strings, one for each line in the group. When indent/unindent is hooked up to the undo/redo code, this will allow the latter to restore the exact original indents.master
parent
ffc550521c
commit
f722c53223
|
@ -299,6 +299,8 @@ typedef struct undo_group {
|
|||
/* First line of group. */
|
||||
ssize_t bottom_line;
|
||||
/* Last line of group. */
|
||||
char **indentations;
|
||||
/* String data used to restore the affected lines; one per line. */
|
||||
struct undo_group *next;
|
||||
} undo_group;
|
||||
|
||||
|
|
|
@ -542,9 +542,7 @@ RETSIGTYPE cancel_command(int signal);
|
|||
bool execute_command(const char *command);
|
||||
void discard_until(const undo *thisitem, openfilestruct *thefile);
|
||||
void add_undo(undo_type action);
|
||||
#ifdef ENABLE_COMMENT
|
||||
void update_comment_undo(ssize_t lineno);
|
||||
#endif
|
||||
void update_multiline_undo(ssize_t lineno, char *indentation);
|
||||
void update_undo(undo_type action);
|
||||
#endif /* !NANO_TINY */
|
||||
#ifndef DISABLE_WRAPPING
|
||||
|
|
32
src/text.c
32
src/text.c
|
@ -509,7 +509,7 @@ void do_comment(void)
|
|||
for (line = top; line != bot->next; line = line->next) {
|
||||
/* Comment/uncomment a line, and add undo data when line changed. */
|
||||
if (comment_line(action, line, comment_seq))
|
||||
update_comment_undo(line->lineno);
|
||||
update_multiline_undo(line->lineno, "");
|
||||
}
|
||||
|
||||
set_modified();
|
||||
|
@ -1137,22 +1137,20 @@ bool execute_command(const char *command)
|
|||
void discard_until(const undo *thisitem, openfilestruct *thefile)
|
||||
{
|
||||
undo *dropit = thefile->undotop;
|
||||
#ifdef ENABLE_COMMENT
|
||||
undo_group *group;
|
||||
#endif
|
||||
|
||||
while (dropit != NULL && dropit != thisitem) {
|
||||
thefile->undotop = dropit->next;
|
||||
free(dropit->strdata);
|
||||
free_filestruct(dropit->cutbuffer);
|
||||
#ifdef ENABLE_COMMENT
|
||||
group = dropit->grouping;
|
||||
while (group != NULL) {
|
||||
undo_group *next = group->next;
|
||||
free_chararray(group->indentations,
|
||||
group->bottom_line - group->top_line);
|
||||
free(group);
|
||||
group = next;
|
||||
}
|
||||
#endif
|
||||
free(dropit);
|
||||
dropit = thefile->undotop;
|
||||
}
|
||||
|
@ -1297,30 +1295,40 @@ void add_undo(undo_type action)
|
|||
openfile->last_action = action;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COMMENT
|
||||
/* Update a comment undo item. This should be called once for each line
|
||||
* affected by the comment/uncomment feature. */
|
||||
void update_comment_undo(ssize_t lineno)
|
||||
/* Update a multiline undo item. This should be called once for each line
|
||||
* affected by a multiple-line-altering feature. The existing indentation
|
||||
* is saved separately for each line in the undo item. */
|
||||
void update_multiline_undo(ssize_t lineno, char *indentation)
|
||||
{
|
||||
undo *u = openfile->current_undo;
|
||||
|
||||
/* If there already is a group and the current line is contiguous with it,
|
||||
* extend the group; otherwise, create a new group. */
|
||||
if (u->grouping && u->grouping->bottom_line + 1 == lineno)
|
||||
if (u->grouping && u->grouping->bottom_line + 1 == lineno) {
|
||||
size_t number_of_lines;
|
||||
|
||||
u->grouping->bottom_line++;
|
||||
else {
|
||||
|
||||
number_of_lines = u->grouping->bottom_line - u->grouping->top_line + 1;
|
||||
u->grouping->indentations = (char **)nrealloc(u->grouping->indentations,
|
||||
number_of_lines * sizeof(char *));
|
||||
u->grouping->indentations[number_of_lines - 1] = mallocstrcpy(NULL,
|
||||
indentation);
|
||||
} else {
|
||||
undo_group *born = (undo_group *)nmalloc(sizeof(undo_group));
|
||||
|
||||
born->next = u->grouping;
|
||||
u->grouping = born;
|
||||
born->top_line = lineno;
|
||||
born->bottom_line = lineno;
|
||||
|
||||
u->grouping->indentations = (char **)nmalloc(sizeof(char *));
|
||||
u->grouping->indentations[0] = mallocstrcpy(NULL, indentation);
|
||||
}
|
||||
|
||||
/* Store the file size after the change, to be used when redoing. */
|
||||
u->newsize = openfile->totsize;
|
||||
}
|
||||
#endif /* ENABLE_COMMENT */
|
||||
|
||||
/* Update an undo item, or determine whether a new one is really needed
|
||||
* and bounce the data to add_undo instead. The latter functionality
|
||||
|
|
Loading…
Reference in New Issue