Commit f722c532 authored by David Lawrence Ramsey's avatar David Lawrence Ramsey Committed by Benno Schulenberg
Browse files

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.
No related merge requests found
Showing with 23 additions and 15 deletions
+23 -15
......@@ -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
......
......@@ -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
......
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