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. */
|
/* First line of group. */
|
||||||
ssize_t bottom_line;
|
ssize_t bottom_line;
|
||||||
/* Last line of group. */
|
/* Last line of group. */
|
||||||
|
char **indentations;
|
||||||
|
/* String data used to restore the affected lines; one per line. */
|
||||||
struct undo_group *next;
|
struct undo_group *next;
|
||||||
} undo_group;
|
} undo_group;
|
||||||
|
|
||||||
|
|
|
@ -542,9 +542,7 @@ RETSIGTYPE cancel_command(int signal);
|
||||||
bool execute_command(const char *command);
|
bool execute_command(const char *command);
|
||||||
void discard_until(const undo *thisitem, openfilestruct *thefile);
|
void discard_until(const undo *thisitem, openfilestruct *thefile);
|
||||||
void add_undo(undo_type action);
|
void add_undo(undo_type action);
|
||||||
#ifdef ENABLE_COMMENT
|
void update_multiline_undo(ssize_t lineno, char *indentation);
|
||||||
void update_comment_undo(ssize_t lineno);
|
|
||||||
#endif
|
|
||||||
void update_undo(undo_type action);
|
void update_undo(undo_type action);
|
||||||
#endif /* !NANO_TINY */
|
#endif /* !NANO_TINY */
|
||||||
#ifndef DISABLE_WRAPPING
|
#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) {
|
for (line = top; line != bot->next; line = line->next) {
|
||||||
/* Comment/uncomment a line, and add undo data when line changed. */
|
/* Comment/uncomment a line, and add undo data when line changed. */
|
||||||
if (comment_line(action, line, comment_seq))
|
if (comment_line(action, line, comment_seq))
|
||||||
update_comment_undo(line->lineno);
|
update_multiline_undo(line->lineno, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
set_modified();
|
set_modified();
|
||||||
|
@ -1137,22 +1137,20 @@ bool execute_command(const char *command)
|
||||||
void discard_until(const undo *thisitem, openfilestruct *thefile)
|
void discard_until(const undo *thisitem, openfilestruct *thefile)
|
||||||
{
|
{
|
||||||
undo *dropit = thefile->undotop;
|
undo *dropit = thefile->undotop;
|
||||||
#ifdef ENABLE_COMMENT
|
|
||||||
undo_group *group;
|
undo_group *group;
|
||||||
#endif
|
|
||||||
|
|
||||||
while (dropit != NULL && dropit != thisitem) {
|
while (dropit != NULL && dropit != thisitem) {
|
||||||
thefile->undotop = dropit->next;
|
thefile->undotop = dropit->next;
|
||||||
free(dropit->strdata);
|
free(dropit->strdata);
|
||||||
free_filestruct(dropit->cutbuffer);
|
free_filestruct(dropit->cutbuffer);
|
||||||
#ifdef ENABLE_COMMENT
|
|
||||||
group = dropit->grouping;
|
group = dropit->grouping;
|
||||||
while (group != NULL) {
|
while (group != NULL) {
|
||||||
undo_group *next = group->next;
|
undo_group *next = group->next;
|
||||||
|
free_chararray(group->indentations,
|
||||||
|
group->bottom_line - group->top_line);
|
||||||
free(group);
|
free(group);
|
||||||
group = next;
|
group = next;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
free(dropit);
|
free(dropit);
|
||||||
dropit = thefile->undotop;
|
dropit = thefile->undotop;
|
||||||
}
|
}
|
||||||
|
@ -1297,30 +1295,40 @@ void add_undo(undo_type action)
|
||||||
openfile->last_action = action;
|
openfile->last_action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_COMMENT
|
/* Update a multiline undo item. This should be called once for each line
|
||||||
/* Update a comment undo item. This should be called once for each line
|
* affected by a multiple-line-altering feature. The existing indentation
|
||||||
* affected by the comment/uncomment feature. */
|
* is saved separately for each line in the undo item. */
|
||||||
void update_comment_undo(ssize_t lineno)
|
void update_multiline_undo(ssize_t lineno, char *indentation)
|
||||||
{
|
{
|
||||||
undo *u = openfile->current_undo;
|
undo *u = openfile->current_undo;
|
||||||
|
|
||||||
/* If there already is a group and the current line is contiguous with it,
|
/* If there already is a group and the current line is contiguous with it,
|
||||||
* extend the group; otherwise, create a new group. */
|
* 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++;
|
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));
|
undo_group *born = (undo_group *)nmalloc(sizeof(undo_group));
|
||||||
|
|
||||||
born->next = u->grouping;
|
born->next = u->grouping;
|
||||||
u->grouping = born;
|
u->grouping = born;
|
||||||
born->top_line = lineno;
|
born->top_line = lineno;
|
||||||
born->bottom_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. */
|
/* Store the file size after the change, to be used when redoing. */
|
||||||
u->newsize = openfile->totsize;
|
u->newsize = openfile->totsize;
|
||||||
}
|
}
|
||||||
#endif /* ENABLE_COMMENT */
|
|
||||||
|
|
||||||
/* Update an undo item, or determine whether a new one is really needed
|
/* Update an undo item, or determine whether a new one is really needed
|
||||||
* and bounce the data to add_undo instead. The latter functionality
|
* and bounce the data to add_undo instead. The latter functionality
|
||||||
|
|
Loading…
Reference in New Issue