diff --git a/src/nano.h b/src/nano.h index 1a77097a415f8a4f962c915a12c80db5be865369..c9127e410b7ddc7838957952717ce6d9e9ba2090 100644 --- a/src/nano.h +++ b/src/nano.h @@ -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; diff --git a/src/proto.h b/src/proto.h index 8ee4eb0e184c6dd7a8cb52b2cf770575ae0869a9..8a3043ce22b56dac2836bb31c05e12bb873017e7 100644 --- a/src/proto.h +++ b/src/proto.h @@ -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 diff --git a/src/text.c b/src/text.c index 45e273f2664170e324039501c33486d476c8573b..9272bb2d84d9d80a0a118efb3a6c419ccf462ac3 100644 --- a/src/text.c +++ b/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