comparison src/evalfunc.c @ 34451:d06ffca91441 v9.1.0142

patch 9.1.0142: getregion() can be improved Commit: https://github.com/vim/vim/commit/19b718828d8d5fab52d94c6cdba694641879ab38 Author: Shougo Matsushita <Shougo.Matsu@gmail.com> Date: Wed Feb 28 22:48:12 2024 +0100 patch 9.1.0142: getregion() can be improved Problem: getregion() can be improved (after v9.1.120) Solution: change getregion() implementation to use pos as lists and one optional {opt} dictionary (Shougo Matsushita) Note: The following is a breaking change! Currently, the getregion() function (included as of patch v9.1.120) takes 3 arguments: the first 2 arguments are strings, describing a position, arg3 is the type string. However, that is slightly inflexible, there is no way to specify additional arguments. So let's instead change the function signature to: getregion(pos1, pos2 [, {Dict}]) where both pos1 and pos2 are lists. This is slightly cleaner, and gives us the flexibility to specify additional arguments as key/value pairs to the optional Dict arg. Now it supports the "type" key to specify the selection type (characterwise, blockwise or linewise) and now in addition one can also define the selection type, independently of what the 'selection' option actually is. Technically, this is a breaking change, but since the getregion() Vimscript function is still quite new, this should be fine. closes: #14090 Co-authored-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Wed, 28 Feb 2024 23:00:03 +0100
parents 5337abbdf88e
children 5c1a025192ed
comparison
equal deleted inserted replaced
34450:4b3ffb6965ec 34451:d06ffca91441
1149 static argcheck_T arg3_buffer_string_any[] = {arg_buffer, arg_string, arg_any}; 1149 static argcheck_T arg3_buffer_string_any[] = {arg_buffer, arg_string, arg_any};
1150 static argcheck_T arg3_buffer_string_dict[] = {arg_buffer, arg_string, arg_dict_any}; 1150 static argcheck_T arg3_buffer_string_dict[] = {arg_buffer, arg_string, arg_dict_any};
1151 static argcheck_T arg3_dict_number_number[] = {arg_dict_any, arg_number, arg_number}; 1151 static argcheck_T arg3_dict_number_number[] = {arg_dict_any, arg_number, arg_number};
1152 static argcheck_T arg3_diff[] = {arg_list_string, arg_list_string, arg_dict_any}; 1152 static argcheck_T arg3_diff[] = {arg_list_string, arg_list_string, arg_dict_any};
1153 static argcheck_T arg3_list_string_dict[] = {arg_list_any, arg_string, arg_dict_any}; 1153 static argcheck_T arg3_list_string_dict[] = {arg_list_any, arg_string, arg_dict_any};
1154 static argcheck_T arg3_list_list_dict[] = {arg_list_any, arg_list_any, arg_dict_any};
1154 static argcheck_T arg3_lnum_number_bool[] = {arg_lnum, arg_number, arg_bool}; 1155 static argcheck_T arg3_lnum_number_bool[] = {arg_lnum, arg_number, arg_bool};
1155 static argcheck_T arg3_number[] = {arg_number, arg_number, arg_number}; 1156 static argcheck_T arg3_number[] = {arg_number, arg_number, arg_number};
1156 static argcheck_T arg3_number_any_dict[] = {arg_number, arg_any, arg_dict_any}; 1157 static argcheck_T arg3_number_any_dict[] = {arg_number, arg_any, arg_dict_any};
1157 static argcheck_T arg3_number_number_dict[] = {arg_number, arg_number, arg_dict_any}; 1158 static argcheck_T arg3_number_number_dict[] = {arg_number, arg_number, arg_dict_any};
1158 static argcheck_T arg3_number_string_any[] = {arg_number, arg_string, arg_any}; 1159 static argcheck_T arg3_number_string_any[] = {arg_number, arg_string, arg_any};
2130 ret_list_or_dict_0, f_getqflist}, 2131 ret_list_or_dict_0, f_getqflist},
2131 {"getreg", 0, 3, FEARG_1, arg3_string_bool_bool, 2132 {"getreg", 0, 3, FEARG_1, arg3_string_bool_bool,
2132 ret_getreg, f_getreg}, 2133 ret_getreg, f_getreg},
2133 {"getreginfo", 0, 1, FEARG_1, arg1_string, 2134 {"getreginfo", 0, 1, FEARG_1, arg1_string,
2134 ret_dict_any, f_getreginfo}, 2135 ret_dict_any, f_getreginfo},
2135 {"getregion", 3, 3, FEARG_1, arg3_string, 2136 {"getregion", 2, 3, FEARG_1, arg3_list_list_dict,
2136 ret_list_string, f_getregion}, 2137 ret_list_string, f_getregion},
2137 {"getregtype", 0, 1, FEARG_1, arg1_string, 2138 {"getregtype", 0, 1, FEARG_1, arg1_string,
2138 ret_string, f_getregtype}, 2139 ret_string, f_getregtype},
2139 {"getscriptinfo", 0, 1, 0, arg1_dict_any, 2140 {"getscriptinfo", 0, 1, 0, arg1_dict_any,
2140 ret_list_dict_any, f_getscriptinfo}, 2141 ret_list_dict_any, f_getscriptinfo},
5489 struct block_def bd; 5490 struct block_def bd;
5490 char_u *akt = NULL; 5491 char_u *akt = NULL;
5491 int inclusive = TRUE; 5492 int inclusive = TRUE;
5492 int fnum = -1; 5493 int fnum = -1;
5493 pos_T p1, p2; 5494 pos_T p1, p2;
5494 pos_T *fp = NULL; 5495 char_u *type;
5495 char_u *pos1, *pos2, *type; 5496 char_u default_type[] = "v";
5496 int save_virtual = -1; 5497 int save_virtual = -1;
5497 int l; 5498 int l;
5498 int region_type = -1; 5499 int region_type = -1;
5499 int is_visual; 5500 int is_select_exclusive;
5500 5501
5501 if (rettv_list_alloc(rettv) == FAIL) 5502 if (rettv_list_alloc(rettv) == FAIL)
5502 return; 5503 return;
5503 5504
5504 if (check_for_string_arg(argvars, 0) == FAIL 5505 if (check_for_list_arg(argvars, 0) == FAIL
5505 || check_for_string_arg(argvars, 1) == FAIL 5506 || check_for_list_arg(argvars, 1) == FAIL
5506 || check_for_string_arg(argvars, 2) == FAIL) 5507 || check_for_opt_dict_arg(argvars, 2) == FAIL)
5507 return; 5508 return;
5508 5509
5509 // NOTE: var2fpos() returns static pointer. 5510 if (list2fpos(&argvars[0], &p1, &fnum, NULL, FALSE) != OK
5510 fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE); 5511 || (fnum >= 0 && fnum != curbuf->b_fnum))
5511 if (fp == NULL || (fnum >= 0 && fnum != curbuf->b_fnum)) 5512 return;
5512 return; 5513
5513 p1 = *fp; 5514 if (list2fpos(&argvars[1], &p2, &fnum, NULL, FALSE) != OK
5514 5515 || (fnum >= 0 && fnum != curbuf->b_fnum))
5515 fp = var2fpos(&argvars[1], TRUE, &fnum, FALSE); 5516 return;
5516 if (fp == NULL || (fnum >= 0 && fnum != curbuf->b_fnum)) 5517
5517 return; 5518 if (argvars[2].v_type == VAR_DICT)
5518 p2 = *fp; 5519 {
5519 5520 is_select_exclusive = dict_get_bool(
5520 pos1 = tv_get_string(&argvars[0]); 5521 argvars[2].vval.v_dict, "exclusive", *p_sel == 'e');
5521 pos2 = tv_get_string(&argvars[1]); 5522 type = dict_get_string(
5522 type = tv_get_string(&argvars[2]); 5523 argvars[2].vval.v_dict, "type", FALSE);
5523 5524 if (type == NULL)
5524 is_visual = (pos1[0] == 'v' && pos1[1] == NUL) 5525 type = default_type;
5525 || (pos2[0] == 'v' && pos2[1] == NUL); 5526 }
5526 5527 else
5527 if (is_visual && !VIsual_active) 5528 {
5528 return; 5529 is_select_exclusive = *p_sel == 'e';
5530 type = default_type;
5531 }
5529 5532
5530 if (type[0] == 'v' && type[1] == NUL) 5533 if (type[0] == 'v' && type[1] == NUL)
5531 region_type = MCHAR; 5534 region_type = MCHAR;
5532 else if (type[0] == 'V' && type[1] == NUL) 5535 else if (type[0] == 'V' && type[1] == NUL)
5533 region_type = MLINE; 5536 region_type = MLINE;
5537 return; 5540 return;
5538 5541
5539 save_virtual = virtual_op; 5542 save_virtual = virtual_op;
5540 virtual_op = virtual_active(); 5543 virtual_op = virtual_active();
5541 5544
5545 // NOTE: Adjust is needed.
5546 p1.col--;
5547 p2.col--;
5548
5542 if (!LT_POS(p1, p2)) 5549 if (!LT_POS(p1, p2))
5543 { 5550 {
5544 // swap position 5551 // swap position
5545 pos_T p; 5552 pos_T p;
5546 5553
5550 } 5557 }
5551 5558
5552 if (region_type == MCHAR) 5559 if (region_type == MCHAR)
5553 { 5560 {
5554 // handle 'selection' == "exclusive" 5561 // handle 'selection' == "exclusive"
5555 if (*p_sel == 'e' && !EQUAL_POS(p1, p2)) 5562 if (is_select_exclusive && !EQUAL_POS(p1, p2))
5556 { 5563 {
5557 if (p2.coladd > 0) 5564 if (p2.coladd > 0)
5558 p2.coladd--; 5565 p2.coladd--;
5559 else if (p2.col > 0) 5566 else if (p2.col > 0)
5560 { 5567 {
5588 oa.inclusive = TRUE; 5595 oa.inclusive = TRUE;
5589 oa.op_type = OP_NOP; 5596 oa.op_type = OP_NOP;
5590 oa.start = p1; 5597 oa.start = p1;
5591 oa.end = p2; 5598 oa.end = p2;
5592 oa.start_vcol = MIN(sc1, sc2); 5599 oa.start_vcol = MIN(sc1, sc2);
5593 if (*p_sel == 'e' && ec1 < sc2 && 0 < sc2 && ec2 > ec1) 5600 if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1)
5594 oa.end_vcol = sc2 - 1; 5601 oa.end_vcol = sc2 - 1;
5595 else 5602 else
5596 oa.end_vcol = MAX(ec1, ec2); 5603 oa.end_vcol = MAX(ec1, ec2);
5597 } 5604 }
5598 5605