Mercurial > vim
comparison src/evalfunc.c @ 20743:a672feb8fc4f v8.2.0924
patch 8.2.0924: cannot save and restore a register properly
Commit: https://github.com/vim/vim/commit/bb861e293e0170455184079fa537278754b07911
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jun 7 18:16:36 2020 +0200
patch 8.2.0924: cannot save and restore a register properly
Problem: Cannot save and restore a register properly.
Solution: Add getreginfo() and make setreg() accept a dictionary. (Andy
Massimino, closes #3370)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 07 Jun 2020 18:30:03 +0200 |
parents | ab27db64f1fb |
children | d9a2e5dcfd9f |
comparison
equal
deleted
inserted
replaced
20742:8c304b9fcb1a | 20743:a672feb8fc4f |
---|---|
92 static void f_getjumplist(typval_T *argvars, typval_T *rettv); | 92 static void f_getjumplist(typval_T *argvars, typval_T *rettv); |
93 static void f_getpid(typval_T *argvars, typval_T *rettv); | 93 static void f_getpid(typval_T *argvars, typval_T *rettv); |
94 static void f_getcurpos(typval_T *argvars, typval_T *rettv); | 94 static void f_getcurpos(typval_T *argvars, typval_T *rettv); |
95 static void f_getpos(typval_T *argvars, typval_T *rettv); | 95 static void f_getpos(typval_T *argvars, typval_T *rettv); |
96 static void f_getreg(typval_T *argvars, typval_T *rettv); | 96 static void f_getreg(typval_T *argvars, typval_T *rettv); |
97 static void f_getreginfo(typval_T *argvars, typval_T *rettv); | |
97 static void f_getregtype(typval_T *argvars, typval_T *rettv); | 98 static void f_getregtype(typval_T *argvars, typval_T *rettv); |
98 static void f_gettagstack(typval_T *argvars, typval_T *rettv); | 99 static void f_gettagstack(typval_T *argvars, typval_T *rettv); |
99 static void f_haslocaldir(typval_T *argvars, typval_T *rettv); | 100 static void f_haslocaldir(typval_T *argvars, typval_T *rettv); |
100 static void f_hasmapto(typval_T *argvars, typval_T *rettv); | 101 static void f_hasmapto(typval_T *argvars, typval_T *rettv); |
101 static void f_hlID(typval_T *argvars, typval_T *rettv); | 102 static void f_hlID(typval_T *argvars, typval_T *rettv); |
584 {"getmousepos", 0, 0, 0, ret_dict_number, f_getmousepos}, | 585 {"getmousepos", 0, 0, 0, ret_dict_number, f_getmousepos}, |
585 {"getpid", 0, 0, 0, ret_number, f_getpid}, | 586 {"getpid", 0, 0, 0, ret_number, f_getpid}, |
586 {"getpos", 1, 1, FEARG_1, ret_list_number, f_getpos}, | 587 {"getpos", 1, 1, FEARG_1, ret_list_number, f_getpos}, |
587 {"getqflist", 0, 1, 0, ret_list_dict_any, f_getqflist}, | 588 {"getqflist", 0, 1, 0, ret_list_dict_any, f_getqflist}, |
588 {"getreg", 0, 3, FEARG_1, ret_string, f_getreg}, | 589 {"getreg", 0, 3, FEARG_1, ret_string, f_getreg}, |
590 {"getreginfo", 0, 1, FEARG_1, ret_dict_any, f_getreginfo}, | |
589 {"getregtype", 0, 1, FEARG_1, ret_string, f_getregtype}, | 591 {"getregtype", 0, 1, FEARG_1, ret_string, f_getregtype}, |
590 {"gettabinfo", 0, 1, FEARG_1, ret_list_dict_any, f_gettabinfo}, | 592 {"gettabinfo", 0, 1, FEARG_1, ret_list_dict_any, f_gettabinfo}, |
591 {"gettabvar", 2, 3, FEARG_1, ret_any, f_gettabvar}, | 593 {"gettabvar", 2, 3, FEARG_1, ret_any, f_gettabvar}, |
592 {"gettabwinvar", 3, 4, FEARG_1, ret_any, f_gettabwinvar}, | 594 {"gettabwinvar", 3, 4, FEARG_1, ret_any, f_gettabwinvar}, |
593 {"gettagstack", 0, 1, FEARG_1, ret_dict_any, f_gettagstack}, | 595 {"gettagstack", 0, 1, FEARG_1, ret_dict_any, f_gettagstack}, |
6225 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) | 6227 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) |
6226 if (list_append_number(list, (varnumber_T)i) == FAIL) | 6228 if (list_append_number(list, (varnumber_T)i) == FAIL) |
6227 break; | 6229 break; |
6228 } | 6230 } |
6229 | 6231 |
6232 /* | |
6233 * "getreginfo()" function | |
6234 */ | |
6235 static void | |
6236 f_getreginfo(typval_T *argvars, typval_T *rettv) | |
6237 { | |
6238 char_u *strregname; | |
6239 int regname; | |
6240 char_u buf[NUMBUFLEN + 2]; | |
6241 long reglen = 0; | |
6242 dict_T *dict; | |
6243 list_T *list; | |
6244 | |
6245 if (argvars[0].v_type != VAR_UNKNOWN) | |
6246 { | |
6247 strregname = tv_get_string_chk(&argvars[0]); | |
6248 if (strregname == NULL) | |
6249 return; | |
6250 } | |
6251 else | |
6252 strregname = get_vim_var_str(VV_REG); | |
6253 | |
6254 regname = (strregname == NULL ? '"' : *strregname); | |
6255 if (regname == 0 || regname == '@') | |
6256 regname = '"'; | |
6257 | |
6258 if (rettv_dict_alloc(rettv) == FAIL) | |
6259 return; | |
6260 dict = rettv->vval.v_dict; | |
6261 | |
6262 list = (list_T *)get_reg_contents(regname, GREG_EXPR_SRC | GREG_LIST); | |
6263 if (list == NULL) | |
6264 return; | |
6265 dict_add_list(dict, "regcontents", list); | |
6266 | |
6267 buf[0] = NUL; | |
6268 buf[1] = NUL; | |
6269 switch (get_reg_type(regname, ®len)) | |
6270 { | |
6271 case MLINE: buf[0] = 'V'; break; | |
6272 case MCHAR: buf[0] = 'v'; break; | |
6273 case MBLOCK: | |
6274 vim_snprintf((char *)buf, sizeof(buf), "%c%ld", Ctrl_V, | |
6275 reglen + 1); | |
6276 break; | |
6277 } | |
6278 dict_add_string(dict, (char *)"regtype", buf); | |
6279 | |
6280 buf[0] = get_register_name(get_unname_register()); | |
6281 buf[1] = NUL; | |
6282 if (regname == '"') | |
6283 dict_add_string(dict, (char *)"points_to", buf); | |
6284 else | |
6285 { | |
6286 dictitem_T *item = dictitem_alloc((char_u *)"isunnamed"); | |
6287 | |
6288 if (item != NULL) | |
6289 { | |
6290 item->di_tv.v_type = VAR_SPECIAL; | |
6291 item->di_tv.vval.v_number = regname == buf[0] | |
6292 ? VVAL_TRUE : VVAL_FALSE; | |
6293 dict_add(dict, item); | |
6294 } | |
6295 } | |
6296 } | |
6297 | |
6230 static void | 6298 static void |
6231 return_register(int regname, typval_T *rettv) | 6299 return_register(int regname, typval_T *rettv) |
6232 { | 6300 { |
6233 char_u buf[2] = {0, 0}; | 6301 char_u buf[2] = {0, 0}; |
6234 | 6302 |
7201 char_u *stropt; | 7269 char_u *stropt; |
7202 char_u *strval; | 7270 char_u *strval; |
7203 int append; | 7271 int append; |
7204 char_u yank_type; | 7272 char_u yank_type; |
7205 long block_len; | 7273 long block_len; |
7206 | 7274 typval_T *regcontents; |
7275 int pointreg; | |
7276 | |
7277 pointreg = 0; | |
7278 regcontents = NULL; | |
7207 block_len = -1; | 7279 block_len = -1; |
7208 yank_type = MAUTO; | 7280 yank_type = MAUTO; |
7209 append = FALSE; | 7281 append = FALSE; |
7210 | 7282 |
7211 strregname = tv_get_string_chk(argvars); | 7283 strregname = tv_get_string_chk(argvars); |
7214 if (strregname == NULL) | 7286 if (strregname == NULL) |
7215 return; // type error; errmsg already given | 7287 return; // type error; errmsg already given |
7216 regname = *strregname; | 7288 regname = *strregname; |
7217 if (regname == 0 || regname == '@') | 7289 if (regname == 0 || regname == '@') |
7218 regname = '"'; | 7290 regname = '"'; |
7291 | |
7292 if (argvars[1].v_type == VAR_DICT) | |
7293 { | |
7294 dict_T *d = argvars[1].vval.v_dict; | |
7295 dictitem_T *di = dict_find(d, (char_u *)"regcontents", -1); | |
7296 if (di != NULL) | |
7297 regcontents = &di->di_tv; | |
7298 | |
7299 stropt = dict_get_string(d, (char_u *)"regtype", FALSE); | |
7300 if (stropt != NULL) | |
7301 switch (*stropt) | |
7302 { | |
7303 case 'v': // character-wise selection | |
7304 yank_type = MCHAR; | |
7305 break; | |
7306 case 'V': // line-wise selection | |
7307 yank_type = MLINE; | |
7308 break; | |
7309 case Ctrl_V: // block-wise selection | |
7310 yank_type = MBLOCK; | |
7311 if (VIM_ISDIGIT(stropt[1])) | |
7312 { | |
7313 ++stropt; | |
7314 block_len = getdigits(&stropt) - 1; | |
7315 --stropt; | |
7316 } | |
7317 break; | |
7318 } | |
7319 | |
7320 if (regname == '"') | |
7321 { | |
7322 stropt = dict_get_string(d, (char_u *)"points_to", FALSE); | |
7323 if (stropt != NULL) | |
7324 { | |
7325 pointreg = *stropt; | |
7326 regname = pointreg; | |
7327 } | |
7328 } | |
7329 else if (dict_get_number(d, (char_u *)"isunnamed")) | |
7330 pointreg = regname; | |
7331 } | |
7332 else | |
7333 regcontents = &argvars[1]; | |
7219 | 7334 |
7220 if (argvars[2].v_type != VAR_UNKNOWN) | 7335 if (argvars[2].v_type != VAR_UNKNOWN) |
7221 { | 7336 { |
7222 stropt = tv_get_string_chk(&argvars[2]); | 7337 stropt = tv_get_string_chk(&argvars[2]); |
7223 if (stropt == NULL) | 7338 if (stropt == NULL) |
7244 } | 7359 } |
7245 break; | 7360 break; |
7246 } | 7361 } |
7247 } | 7362 } |
7248 | 7363 |
7249 if (argvars[1].v_type == VAR_LIST) | 7364 if (regcontents && regcontents->v_type == VAR_LIST) |
7250 { | 7365 { |
7251 char_u **lstval; | 7366 char_u **lstval; |
7252 char_u **allocval; | 7367 char_u **allocval; |
7253 char_u buf[NUMBUFLEN]; | 7368 char_u buf[NUMBUFLEN]; |
7254 char_u **curval; | 7369 char_u **curval; |
7255 char_u **curallocval; | 7370 char_u **curallocval; |
7256 list_T *ll = argvars[1].vval.v_list; | 7371 list_T *ll = regcontents->vval.v_list; |
7257 listitem_T *li; | 7372 listitem_T *li; |
7258 int len; | 7373 int len; |
7259 | 7374 |
7260 // If the list is NULL handle like an empty list. | 7375 // If the list is NULL handle like an empty list. |
7261 len = ll == NULL ? 0 : ll->lv_len; | 7376 len = ll == NULL ? 0 : ll->lv_len; |
7296 free_lstval: | 7411 free_lstval: |
7297 while (curallocval > allocval) | 7412 while (curallocval > allocval) |
7298 vim_free(*--curallocval); | 7413 vim_free(*--curallocval); |
7299 vim_free(lstval); | 7414 vim_free(lstval); |
7300 } | 7415 } |
7301 else | 7416 else if (regcontents) |
7302 { | 7417 { |
7303 strval = tv_get_string_chk(&argvars[1]); | 7418 strval = tv_get_string_chk(regcontents); |
7304 if (strval == NULL) | 7419 if (strval == NULL) |
7305 return; | 7420 return; |
7306 write_reg_contents_ex(regname, strval, -1, | 7421 write_reg_contents_ex(regname, strval, -1, |
7307 append, yank_type, block_len); | 7422 append, yank_type, block_len); |
7308 } | 7423 } |
7424 if (pointreg != 0) | |
7425 get_yank_register(pointreg, TRUE); | |
7426 | |
7309 rettv->vval.v_number = 0; | 7427 rettv->vval.v_number = 0; |
7310 } | 7428 } |
7311 | 7429 |
7312 /* | 7430 /* |
7313 * "settagstack()" function | 7431 * "settagstack()" function |