mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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 vim/vim#3370)
7633fe595e
Do not getdigits for block_len strictly. For example, a user could
previously abort Nvim using:
:call setreg("0", "abort!", "\<C-V>999999999999999999")
or, after v8.2.0924's port:
:call setreg("0", #{regcontents: ["abort!"],
\ regtype: "\<C-V>999999999999999999"})
Instead, default to 0 so block_len is -1, which acts like the selection
width was omitted (defaults to length of longest line).
This commit is contained in:
parent
f8241f825a
commit
f1bf70c2f9
@ -9094,6 +9094,36 @@ static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
set_qf_ll_list(NULL, argvars, rettv);
|
set_qf_ll_list(NULL, argvars, rettv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Translate a register type string to the yank type and block length
|
||||||
|
static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *const block_len)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
char_u *stropt = *pp;
|
||||||
|
switch (*stropt) {
|
||||||
|
case 'v':
|
||||||
|
case 'c': // character-wise selection
|
||||||
|
*yank_type = kMTCharWise;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
case 'l': // line-wise selection
|
||||||
|
*yank_type = kMTLineWise;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
case Ctrl_V: // block-wise selection
|
||||||
|
*yank_type = kMTBlockWise;
|
||||||
|
if (ascii_isdigit(stropt[1])) {
|
||||||
|
stropt++;
|
||||||
|
*block_len = getdigits_long(&stropt, false, 0) - 1;
|
||||||
|
stropt--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
*pp = stropt;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "setreg()" function
|
* "setreg()" function
|
||||||
*/
|
*/
|
||||||
@ -9122,6 +9152,14 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
int pointreg = 0;
|
int pointreg = 0;
|
||||||
if (argvars[1].v_type == VAR_DICT) {
|
if (argvars[1].v_type == VAR_DICT) {
|
||||||
dict_T *const d = argvars[1].vval.v_dict;
|
dict_T *const d = argvars[1].vval.v_dict;
|
||||||
|
|
||||||
|
if (tv_dict_len(d) == 0) {
|
||||||
|
// Empty dict, clear the register (like setreg(0, []))
|
||||||
|
char_u *lstval[2] = { NULL, NULL };
|
||||||
|
write_reg_contents_lst(regname, lstval, false, kMTUnknown, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dictitem_T *const di = tv_dict_find(d, "regcontents", -1);
|
dictitem_T *const di = tv_dict_find(d, "regcontents", -1);
|
||||||
if (di != NULL) {
|
if (di != NULL) {
|
||||||
regcontents = &di->di_tv;
|
regcontents = &di->di_tv;
|
||||||
@ -9129,21 +9167,11 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
const char *stropt = tv_dict_get_string(d, "regtype", false);
|
const char *stropt = tv_dict_get_string(d, "regtype", false);
|
||||||
if (stropt != NULL) {
|
if (stropt != NULL) {
|
||||||
switch (*stropt) {
|
const int ret = get_yank_type((char_u **)&stropt, &yank_type, &block_len);
|
||||||
case 'v': // character-wise selection
|
|
||||||
yank_type = kMTCharWise;
|
if (ret == FAIL || *(++stropt) != NUL) {
|
||||||
break;
|
EMSG2(_(e_invargval), "value");
|
||||||
case 'V': // line-wise selection
|
return;
|
||||||
yank_type = kMTLineWise;
|
|
||||||
break;
|
|
||||||
case Ctrl_V: // block-wise selection
|
|
||||||
yank_type = kMTBlockWise;
|
|
||||||
if (ascii_isdigit(stropt[1])) {
|
|
||||||
stropt++;
|
|
||||||
block_len = getdigits_long((char_u **)&stropt, true, 0) - 1;
|
|
||||||
stropt--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9162,6 +9190,11 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
bool set_unnamed = false;
|
bool set_unnamed = false;
|
||||||
if (argvars[2].v_type != VAR_UNKNOWN) {
|
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||||
|
if (yank_type != kMTUnknown) {
|
||||||
|
EMSG2(_(e_toomanyarg), "setreg");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char *stropt = tv_get_string_chk(&argvars[2]);
|
const char *stropt = tv_get_string_chk(&argvars[2]);
|
||||||
if (stropt == NULL) {
|
if (stropt == NULL) {
|
||||||
return; // Type error.
|
return; // Type error.
|
||||||
@ -9172,27 +9205,12 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
case 'A': // append
|
case 'A': // append
|
||||||
append = true;
|
append = true;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
|
||||||
case 'c': // character-wise selection
|
|
||||||
yank_type = kMTCharWise;
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
case 'l': // line-wise selection
|
|
||||||
yank_type = kMTLineWise;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
case Ctrl_V: // block-wise selection
|
|
||||||
yank_type = kMTBlockWise;
|
|
||||||
if (ascii_isdigit(stropt[1])) {
|
|
||||||
stropt++;
|
|
||||||
block_len = getdigits_long((char_u **)&stropt, true, 0) - 1;
|
|
||||||
stropt--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'u':
|
case 'u':
|
||||||
case '"': // unnamed register
|
case '"': // unnamed register
|
||||||
set_unnamed = true;
|
set_unnamed = true;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
get_yank_type((char_u **)&stropt, &yank_type, &block_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,6 +352,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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user