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

@ -6002,11 +6002,11 @@ static int srand_seed_for_testing_is_used = FALSE;
f_test_srand_seed(typval_T *argvars, typval_T *rettv UNUSED)
{
if (argvars[0].v_type == VAR_UNKNOWN)
srand_seed_for_testing_is_used = FALSE;
srand_seed_for_testing_is_used = FALSE;
else
{
srand_seed_for_testing = (UINT32_T)tv_get_number(&argvars[0]);
srand_seed_for_testing_is_used = TRUE;
srand_seed_for_testing = (UINT32_T)tv_get_number(&argvars[0]);
srand_seed_for_testing_is_used = TRUE;
}
}
@ -6019,7 +6019,7 @@ init_srand(UINT32_T *x)
if (srand_seed_for_testing_is_used)
{
*x = srand_seed_for_testing;
*x = srand_seed_for_testing;
return;
}
#ifndef MSWIN
@ -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
*/
@ -7302,30 +7333,31 @@ f_setreg(typval_T *argvars, typval_T *rettv)
if (argvars[1].v_type == VAR_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)
regcontents = &di->di_tv;
stropt = dict_get_string(d, (char_u *)"regtype", FALSE);
if (stropt != NULL)
switch (*stropt)
{
int ret = get_yank_type(&stropt, &yank_type, &block_len);
if (ret == FAIL || *++stropt != NUL)
{
case 'v': // character-wise selection
yank_type = MCHAR;
break;
case 'V': // line-wise selection
yank_type = MLINE;
break;
case Ctrl_V: // block-wise selection
yank_type = MBLOCK;
if (VIM_ISDIGIT(stropt[1]))
{
++stropt;
block_len = getdigits(&stropt) - 1;
--stropt;
}
break;
semsg(_(e_invargval), "value");
return;
}
}
if (regname == '"')
{
@ -7344,6 +7376,12 @@ f_setreg(typval_T *argvars, typval_T *rettv)
if (argvars[2].v_type != VAR_UNKNOWN)
{
if (yank_type != MAUTO)
{
semsg(_(e_toomanyarg), "setreg");
return;
}
stropt = tv_get_string_chk(&argvars[2]);
if (stropt == NULL)
return; // type error
@ -7353,21 +7391,8 @@ f_setreg(typval_T *argvars, typval_T *rettv)
case 'a': case 'A': // append
append = TRUE;
break;
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:
get_yank_type(&stropt, &yank_type, &block_len);
}
}

View File

@ -485,6 +485,14 @@ func Test_set_register_dict()
call assert_equal(['six'], getreginfo('0').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!
endfunc

View File

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