1
0
forked from aniani/vim

patch 8.2.1035: setreg() does not always clear the register

Problem:    setreg() does not always clear the register.
Solution:   Clear the register if the dict argument is empty. (Andy Massimino,
            closes #3370)
This commit is contained in:
Bram Moolenaar
2020-06-22 19:10:56 +02:00
parent 38041da1c2
commit 7633fe595e
3 changed files with 71 additions and 36 deletions

View File

@@ -7268,6 +7268,37 @@ f_setpos(typval_T *argvars, typval_T *rettv)
} }
} }
/*
* Translate a register type string to the yank type and block length
*/
static int
get_yank_type(char_u **pp, char_u *yank_type, long *block_len)
{
char_u *stropt = *pp;
switch (*stropt)
{
case 'v': case 'c': // character-wise selection
*yank_type = MCHAR;
break;
case 'V': case 'l': // line-wise selection
*yank_type = MLINE;
break;
case 'b': case Ctrl_V: // block-wise selection
*yank_type = MBLOCK;
if (VIM_ISDIGIT(stropt[1]))
{
++stropt;
*block_len = getdigits(&stropt) - 1;
--stropt;
}
break;
default:
return FAIL;
}
*pp = stropt;
return OK;
}
/* /*
* "setreg()" function * "setreg()" function
*/ */
@@ -7302,29 +7333,30 @@ f_setreg(typval_T *argvars, typval_T *rettv)
if (argvars[1].v_type == VAR_DICT) if (argvars[1].v_type == VAR_DICT)
{ {
dict_T *d = argvars[1].vval.v_dict; dict_T *d = argvars[1].vval.v_dict;
dictitem_T *di = dict_find(d, (char_u *)"regcontents", -1); dictitem_T *di;
if (d == NULL || d->dv_hashtab.ht_used == 0)
{
// Empty dict, clear the register (like setreg(0, []))
char_u *lstval[2] = {NULL, NULL};
write_reg_contents_lst(regname, lstval, 0, FALSE, MAUTO, -1);
return;
}
di = dict_find(d, (char_u *)"regcontents", -1);
if (di != NULL) if (di != NULL)
regcontents = &di->di_tv; regcontents = &di->di_tv;
stropt = dict_get_string(d, (char_u *)"regtype", FALSE); stropt = dict_get_string(d, (char_u *)"regtype", FALSE);
if (stropt != NULL) if (stropt != NULL)
switch (*stropt)
{ {
case 'v': // character-wise selection int ret = get_yank_type(&stropt, &yank_type, &block_len);
yank_type = MCHAR;
break; if (ret == FAIL || *++stropt != NUL)
case 'V': // line-wise selection
yank_type = MLINE;
break;
case Ctrl_V: // block-wise selection
yank_type = MBLOCK;
if (VIM_ISDIGIT(stropt[1]))
{ {
++stropt; semsg(_(e_invargval), "value");
block_len = getdigits(&stropt) - 1; return;
--stropt;
} }
break;
} }
if (regname == '"') if (regname == '"')
@@ -7344,6 +7376,12 @@ f_setreg(typval_T *argvars, typval_T *rettv)
if (argvars[2].v_type != VAR_UNKNOWN) if (argvars[2].v_type != VAR_UNKNOWN)
{ {
if (yank_type != MAUTO)
{
semsg(_(e_toomanyarg), "setreg");
return;
}
stropt = tv_get_string_chk(&argvars[2]); stropt = tv_get_string_chk(&argvars[2]);
if (stropt == NULL) if (stropt == NULL)
return; // type error return; // type error
@@ -7353,21 +7391,8 @@ f_setreg(typval_T *argvars, typval_T *rettv)
case 'a': case 'A': // append case 'a': case 'A': // append
append = TRUE; append = TRUE;
break; break;
case 'v': case 'c': // character-wise selection default:
yank_type = MCHAR; get_yank_type(&stropt, &yank_type, &block_len);
break;
case 'V': case 'l': // line-wise selection
yank_type = MLINE;
break;
case 'b': case Ctrl_V: // block-wise selection
yank_type = MBLOCK;
if (VIM_ISDIGIT(stropt[1]))
{
++stropt;
block_len = getdigits(&stropt) - 1;
--stropt;
}
break;
} }
} }

View File

@@ -485,6 +485,14 @@ func Test_set_register_dict()
call assert_equal(['six'], getreginfo('0').regcontents) call assert_equal(['six'], getreginfo('0').regcontents)
call assert_equal(['six'], getreginfo('"').regcontents) call assert_equal(['six'], getreginfo('"').regcontents)
let @x = 'one'
call setreg('x', {})
call assert_equal(1, len(split(execute('reg x'), '\n')))
call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:')
call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:')
call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:')
bwipe! bwipe!
endfunc endfunc

View File

@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1035,
/**/ /**/
1034, 1034,
/**/ /**/