TextYankPost: add v:event["inclusive"] #9717

This commit is contained in:
Justin M. Keyes 2019-03-13 03:24:09 +01:00 committed by GitHub
parent 2af1e23278
commit 7fcf2f926f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 19 deletions

View File

@ -809,20 +809,25 @@ InsertCharPre When a character is typed in Insert mode,
a different character. When |v:char| is set
to more than one character this text is
inserted literally.
It is not allowed to change the text |textlock|.
The event is not triggered when 'paste' is
set.
Cannot change the text. |textlock|
Not triggered when 'paste' is set.
*TextYankPost*
TextYankPost Just after a |yank| or |deleting| command, but not
if the black hole register |quote_| is used nor
for |setreg()|. Pattern must be *.
Sets these |v:event| keys:
inclusive
operator
regcontents
regname
regtype
The `inclusive` flag combined with the |'[|
and |']| marks can be used to calculate the
precise region of the operation.
Recursion is ignored.
It is not allowed to change the text |textlock|.
Cannot change the text. |textlock|
*InsertEnter*
InsertEnter Just before starting Insert mode. Also for
Replace mode and Virtual Replace mode. The
@ -972,7 +977,6 @@ SwapExists Detected an existing swap file when starting
It is not allowed to change to another buffer,
change a buffer name or change directory
here.
{only available with the +eval feature}
*Syntax*
Syntax When the 'syntax' option has been set. The
pattern is matched against the syntax name.

View File

@ -1539,6 +1539,7 @@ v:event Dictionary of event data for the current |autocommand|. Valid
cmdlevel Level of cmdline.
cmdtype Type of cmdline, |cmdline-char|.
cwd Current working directory.
inclusive Motion is |inclusive|, else exclusive.
scope Event-specific scope name.
operator Current |operator|. Also set for Ex
commands (unlike |v:operator|). For

View File

@ -66,10 +66,11 @@ and end position. Generally, motions that move between lines affect lines
characterwise). However, there are some exceptions.
*exclusive* *inclusive*
A character motion is either inclusive or exclusive. When inclusive, the
Character motion is either inclusive or exclusive. When inclusive, the
start and end position of the motion are included in the operation. When
exclusive, the last character towards the end of the buffer is not included.
Linewise motions always include the start and end position.
Linewise motions always include the start and end position. Plugins can
check the v:event.inclusive flag of the |TextYankPost| event.
Which motions are linewise, inclusive or exclusive is mentioned with the
command. There are however, two general exceptions:

View File

@ -2605,17 +2605,16 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
static bool recursive = false;
if (recursive || !has_event(EVENT_TEXTYANKPOST)) {
// No autocommand was defined
// or we yanked from this autocommand.
// No autocommand was defined, or we yanked from this autocommand.
return;
}
recursive = true;
// set v:event to a dictionary with information about the yank
// Set the v:event dictionary with information about the yank.
dict_T *dict = get_vim_var_dict(VV_EVENT);
// the yanked text
// The yanked text contents.
list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
for (size_t i = 0; i < reg->y_size; i++) {
tv_list_append_string(list, (const char *)reg->y_array[i], -1);
@ -2623,17 +2622,21 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
tv_list_set_lock(list, VAR_FIXED);
tv_dict_add_list(dict, S_LEN("regcontents"), list);
// the register type
// Register type.
char buf[NUMBUFLEN+2];
format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf));
tv_dict_add_str(dict, S_LEN("regtype"), buf);
// name of requested register or the empty string for an unnamed operation.
// Name of requested register, or empty string for unnamed operation.
buf[0] = (char)oap->regname;
buf[1] = NUL;
tv_dict_add_str(dict, S_LEN("regname"), buf);
// kind of operation (yank/delete/change)
// Motion type: inclusive or exclusive.
tv_dict_add_special(dict, S_LEN("inclusive"),
oap->inclusive ? kSpecialVarTrue : kSpecialVarFalse);
// Kind of operation: yank, delete, change).
buf[0] = (char)get_op_char(oap->op_type);
buf[1] = NUL;
tv_dict_add_str(dict, S_LEN("operator"), buf);

View File

@ -1161,23 +1161,23 @@ func Test_TextYankPost()
norm "ayiw
call assert_equal(
\{'regcontents': ['foo'], 'regname': 'a', 'operator': 'y', 'regtype': 'v'},
\{'regcontents': ['foo'], 'inclusive': v:true, 'regname': 'a', 'operator': 'y', 'regtype': 'v'},
\g:event)
norm y_
call assert_equal(
\{'regcontents': ['foo'], 'regname': '', 'operator': 'y', 'regtype': 'V'},
\{'regcontents': ['foo'], 'inclusive': v:false, 'regname': '', 'operator': 'y', 'regtype': 'V'},
\g:event)
call feedkeys("\<C-V>y", 'x')
call assert_equal(
\{'regcontents': ['f'], 'regname': '', 'operator': 'y', 'regtype': "\x161"},
\{'regcontents': ['f'], 'inclusive': v:true, 'regname': '', 'operator': 'y', 'regtype': "\x161"},
\g:event)
norm "xciwbar
call assert_equal(
\{'regcontents': ['foo'], 'regname': 'x', 'operator': 'c', 'regtype': 'v'},
\{'regcontents': ['foo'], 'inclusive': v:true, 'regname': 'x', 'operator': 'c', 'regtype': 'v'},
\g:event)
norm "bdiw
call assert_equal(
\{'regcontents': ['bar'], 'regname': 'b', 'operator': 'd', 'regtype': 'v'},
\{'regcontents': ['bar'], 'inclusive': v:true, 'regname': 'b', 'operator': 'd', 'regtype': 'v'},
\g:event)
call assert_equal({}, v:event)

View File

@ -23,6 +23,7 @@ describe('TextYankPost', function()
it('is executed after yank and handles register types', function()
feed('yy')
eq({
inclusive = false,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '',
@ -35,6 +36,7 @@ describe('TextYankPost', function()
feed('+yw')
eq({
inclusive = false,
operator = 'y',
regcontents = { 'baz ' },
regname = '',
@ -44,6 +46,7 @@ describe('TextYankPost', function()
feed('<c-v>eky')
eq({
inclusive = true,
operator = 'y',
regcontents = { 'foo', 'baz' },
regname = '',
@ -55,6 +58,7 @@ describe('TextYankPost', function()
it('makes v:event immutable', function()
feed('yy')
eq({
inclusive = false,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '',
@ -84,6 +88,7 @@ describe('TextYankPost', function()
command('autocmd TextYankPost * normal "+yy')
feed('yy')
eq({
inclusive = false,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '',
@ -96,6 +101,7 @@ describe('TextYankPost', function()
it('is executed after delete and change', function()
feed('dw')
eq({
inclusive = false,
operator = 'd',
regcontents = { 'foo' },
regname = '',
@ -105,6 +111,7 @@ describe('TextYankPost', function()
feed('dd')
eq({
inclusive = false,
operator = 'd',
regcontents = { '\nbar' },
regname = '',
@ -114,6 +121,7 @@ describe('TextYankPost', function()
feed('cwspam<esc>')
eq({
inclusive = true,
operator = 'c',
regcontents = { 'baz' },
regname = '',
@ -141,6 +149,7 @@ describe('TextYankPost', function()
it('gives the correct register name', function()
feed('$"byiw')
eq({
inclusive = true,
operator = 'y',
regcontents = { 'bar' },
regname = 'b',
@ -149,6 +158,7 @@ describe('TextYankPost', function()
feed('"*yy')
eq({
inclusive = true,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '*',
@ -160,6 +170,7 @@ describe('TextYankPost', function()
-- regname still shows the name the user requested
feed('yy')
eq({
inclusive = true,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '',
@ -168,6 +179,7 @@ describe('TextYankPost', function()
feed('"*yy')
eq({
inclusive = true,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '*',
@ -178,6 +190,7 @@ describe('TextYankPost', function()
it('works with Ex commands', function()
command('1delete +')
eq({
inclusive = false,
operator = 'd',
regcontents = { 'foo\nbar' },
regname = '+',
@ -187,6 +200,7 @@ describe('TextYankPost', function()
command('yank')
eq({
inclusive = false,
operator = 'y',
regcontents = { 'baz text' },
regname = '',
@ -196,6 +210,7 @@ describe('TextYankPost', function()
command('normal yw')
eq({
inclusive = false,
operator = 'y',
regcontents = { 'baz ' },
regname = '',
@ -205,6 +220,7 @@ describe('TextYankPost', function()
command('normal! dd')
eq({
inclusive = false,
operator = 'd',
regcontents = { 'baz text' },
regname = '',