TextYankPost: spurious/too-early dispatch during delete #10392

Problem: delete-with-register dispatches TextYankPost before updating yank registers
Solution: Add flag to op_yank().

Fixes #10225
This commit is contained in:
Jit 2019-07-29 00:50:12 +02:00 committed by Justin M. Keyes
parent 4213492231
commit 7cc2b723d4
4 changed files with 21 additions and 8 deletions

View File

@ -7520,7 +7520,7 @@ static void ex_operators(exarg_T *eap)
case CMD_yank: case CMD_yank:
oa.op_type = OP_YANK; oa.op_type = OP_YANK;
(void)op_yank(&oa, true); (void)op_yank(&oa, true, false);
break; break;
default: /* CMD_rshift or CMD_lshift */ default: /* CMD_rshift or CMD_lshift */

View File

@ -1817,7 +1817,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
} }
} else { } else {
curwin->w_p_lbr = lbr_saved; curwin->w_p_lbr = lbr_saved;
(void)op_yank(oap, !gui_yank); (void)op_yank(oap, !gui_yank, false);
} }
check_cursor_col(); check_cursor_col();
break; break;

View File

@ -1400,9 +1400,11 @@ int op_delete(oparg_T *oap)
*/ */
if (oap->regname != '_') { if (oap->regname != '_') {
yankreg_T *reg = NULL; yankreg_T *reg = NULL;
int did_yank = false;
if (oap->regname != 0) { if (oap->regname != 0) {
//yank without message //yank without message
if (!op_yank(oap, false)) { did_yank = op_yank(oap, false, true);
if (!did_yank) {
// op_yank failed, don't do anything // op_yank failed, don't do anything
return OK; return OK;
} }
@ -1423,6 +1425,7 @@ int op_delete(oparg_T *oap)
y_regs[1].y_array = NULL; // set register "1 to empty y_regs[1].y_array = NULL; // set register "1 to empty
reg = &y_regs[1]; reg = &y_regs[1];
op_yank_reg(oap, false, reg, false); op_yank_reg(oap, false, reg, false);
did_yank = true;
} }
/* Yank into small delete register when no named register specified /* Yank into small delete register when no named register specified
@ -1431,13 +1434,14 @@ int op_delete(oparg_T *oap)
&& oap->line_count == 1) { && oap->line_count == 1) {
reg = get_yank_register('-', YREG_YANK); reg = get_yank_register('-', YREG_YANK);
op_yank_reg(oap, false, reg, false); op_yank_reg(oap, false, reg, false);
did_yank = true;
} }
if (oap->regname == 0) { if (did_yank || oap->regname == 0) {
if (reg == NULL) { if (reg == NULL) {
abort(); abort();
} }
set_clipboard(0, reg); set_clipboard(oap->regname, reg);
do_autocmd_textyankpost(oap, reg); do_autocmd_textyankpost(oap, reg);
} }
@ -2376,8 +2380,9 @@ void free_register(yankreg_T *reg)
/// ///
/// @param oap operator arguments /// @param oap operator arguments
/// @param message show message when more than `&report` lines are yanked. /// @param message show message when more than `&report` lines are yanked.
/// @param deleting whether the function was called from a delete operation.
/// @returns whether the operation register was writable. /// @returns whether the operation register was writable.
bool op_yank(oparg_T *oap, bool message) bool op_yank(oparg_T *oap, bool message, int deleting)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
// check for read-only register // check for read-only register
@ -2391,8 +2396,11 @@ bool op_yank(oparg_T *oap, bool message)
yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK); yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK);
op_yank_reg(oap, message, reg, is_append_register(oap->regname)); op_yank_reg(oap, message, reg, is_append_register(oap->regname));
// op_delete will set_clipboard and do_autocmd
if (!deleting) {
set_clipboard(oap->regname, reg); set_clipboard(oap->regname, reg);
do_autocmd_textyankpost(oap, reg); do_autocmd_textyankpost(oap, reg);
}
return true; return true;
} }

View File

@ -229,4 +229,9 @@ describe('TextYankPost', function()
eq(4, eval('g:count')) eq(4, eval('g:count'))
end) end)
it('updates numbered registers correctly #10225', function()
command('autocmd TextYankPost * let g:reg = getreg("1")')
feed('"adj')
eq('foo\nbar\nbaz text\n', eval('g:reg'))
end)
end) end)