filtering: pair the cut and the insert, so they can be undone together

When executing a command in the current buffer and piping this buffer
(or marked region) to that command, then the cutting of the existing
text and the insertion of the new text should be undone and redone
together, as to the user they appear as a single operation.

With-help-from: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
This commit is contained in:
Benno Schulenberg 2018-05-17 12:10:06 +02:00
parent 5ffd8d96ae
commit 5d02ee64b6
2 changed files with 32 additions and 5 deletions

View File

@ -178,7 +178,7 @@ typedef enum {
#ifdef ENABLE_COMMENT #ifdef ENABLE_COMMENT
COMMENT, UNCOMMENT, PREFLIGHT, COMMENT, UNCOMMENT, PREFLIGHT,
#endif #endif
CUT, CUT_TO_EOF, PASTE, INSERT, OTHER CUT, CUT_TO_EOF, PASTE, INSERT, COUPLE_BEGIN, COUPLE_END, OTHER
} undo_type; } undo_type;
/* Structure types. */ /* Structure types. */

View File

@ -800,6 +800,15 @@ void do_undo(void)
cutbuffer = oldcutbuffer; cutbuffer = oldcutbuffer;
cutbottom = oldcutbottom; cutbottom = oldcutbottom;
break; break;
case COUPLE_BEGIN:
undidmsg = _("filtering");
break;
case COUPLE_END:
openfile->current_undo = openfile->current_undo->next;
do_undo();
do_undo();
do_undo();
return;
case INDENT: case INDENT:
handle_indent_action(u, TRUE, TRUE); handle_indent_action(u, TRUE, TRUE);
undidmsg = _("indent"); undidmsg = _("indent");
@ -962,6 +971,15 @@ void do_redo(void)
free_filestruct(u->cutbuffer); free_filestruct(u->cutbuffer);
u->cutbuffer = NULL; u->cutbuffer = NULL;
break; break;
case COUPLE_BEGIN:
openfile->current_undo = u;
do_redo();
do_redo();
do_redo();
return;
case COUPLE_END:
redidmsg = _("filtering");
break;
case INDENT: case INDENT:
handle_indent_action(u, FALSE, TRUE); handle_indent_action(u, FALSE, TRUE);
redidmsg = _("indent"); redidmsg = _("indent");
@ -1159,16 +1177,18 @@ bool execute_command(const char *command)
filestruct *was_cutbuffer = cutbuffer; filestruct *was_cutbuffer = cutbuffer;
cutbuffer = NULL; cutbuffer = NULL;
if (ISSET(MULTIBUFFER)) if (ISSET(MULTIBUFFER)) {
switch_to_prev_buffer(); switch_to_prev_buffer();
if (has_selection)
if (has_selection || !ISSET(MULTIBUFFER)) { do_cut_text(TRUE, FALSE);
} else {
add_undo(COUPLE_BEGIN);
if (!has_selection) { if (!has_selection) {
openfile->current = openfile->fileage; openfile->current = openfile->fileage;
openfile->current_x = 0; openfile->current_x = 0;
} }
add_undo(CUT); add_undo(CUT);
do_cut_text(ISSET(MULTIBUFFER), !has_selection); do_cut_text(FALSE, !has_selection);
update_undo(CUT); update_undo(CUT);
} }
@ -1211,6 +1231,9 @@ bool execute_command(const char *command)
else else
read_file(stream, 0, "pipe", TRUE); read_file(stream, 0, "pipe", TRUE);
if (should_pipe && !ISSET(MULTIBUFFER))
add_undo(COUPLE_END);
if (wait(NULL) == -1) if (wait(NULL) == -1)
nperror("wait"); nperror("wait");
@ -1377,6 +1400,8 @@ void add_undo(undo_type action)
u->lineno += cutbottom->lineno - cutbuffer->lineno; u->lineno += cutbottom->lineno - cutbuffer->lineno;
break; break;
case INSERT: case INSERT:
case COUPLE_BEGIN:
case COUPLE_END:
break; break;
case INDENT: case INDENT:
case UNINDENT: case UNINDENT:
@ -1537,6 +1562,8 @@ fprintf(stderr, " >> Updating an undo... action = %d\n", action);
case INSERT: case INSERT:
u->mark_begin_lineno = openfile->current->lineno; u->mark_begin_lineno = openfile->current->lineno;
u->mark_begin_x = openfile->current_x; u->mark_begin_x = openfile->current_x;
case COUPLE_BEGIN:
case COUPLE_END:
break; break;
default: default:
statusline(ALERT, "Wrong undo update type -- please report a bug"); statusline(ALERT, "Wrong undo update type -- please report a bug");