diff options
Diffstat (limited to 'src/nvim/eval/funcs.c')
-rw-r--r-- | src/nvim/eval/funcs.c | 97 |
1 files changed, 76 insertions, 21 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 60af592108..072d206ecb 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -1953,8 +1953,8 @@ static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat) return (char_u *)(s == NULL ? NULL : xstrdup(s)); } -// "execute(command)" function -static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, + int arg_off) { const int save_msg_silent = msg_silent; const int save_emsg_silent = emsg_silent; @@ -1968,9 +1968,9 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - if (argvars[1].v_type != VAR_UNKNOWN) { + if (argvars[arg_off + 1].v_type != VAR_UNKNOWN) { char buf[NUMBUFLEN]; - const char *const s = tv_get_string_buf_chk(&argvars[1], buf); + const char *const s = tv_get_string_buf_chk(&argvars[arg_off + 1], buf); if (s == NULL) { return; @@ -1997,10 +1997,10 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) msg_col = 0; // prevent leading spaces } - if (argvars[0].v_type != VAR_LIST) { - do_cmdline_cmd(tv_get_string(&argvars[0])); - } else if (argvars[0].vval.v_list != NULL) { - list_T *const list = argvars[0].vval.v_list; + if (argvars[arg_off].v_type != VAR_LIST) { + do_cmdline_cmd(tv_get_string(&argvars[arg_off])); + } else if (argvars[arg_off].vval.v_list != NULL) { + list_T *const list = argvars[arg_off].vval.v_list; tv_list_ref(list); GetListLineCookie cookie = { .l = list, @@ -2032,6 +2032,39 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) capture_ga = save_capture_ga; } +// "execute(command)" function +static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + execute_common(argvars, rettv, fptr, 0); +} + +// "win_execute(win_id, command)" function +static void f_win_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + tabpage_T *tp; + win_T *wp = win_id2wp_tp(argvars, &tp); + win_T *save_curwin; + tabpage_T *save_curtab; + // Return an empty string if something fails. + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + + if (wp != NULL && tp != NULL) { + pos_T curpos = wp->w_cursor; + if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, true) == + OK) { + check_cursor(); + execute_common(argvars, rettv, fptr, 1); + } + restore_win_noblock(save_curwin, save_curtab, true); + + // Update the status line if the cursor moved. + if (win_valid(wp) && !equalpos(curpos, wp->w_cursor)) { + wp->w_redr_status = true; + } + } +} + /// "exepath()" function static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -2737,10 +2770,9 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } else if (strcmp(what, "args") == 0) { rettv->v_type = VAR_LIST; - if (tv_list_alloc_ret(rettv, pt->pt_argc) != NULL) { - for (int i = 0; i < pt->pt_argc; i++) { - tv_list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]); - } + tv_list_alloc_ret(rettv, pt->pt_argc); + for (int i = 0; i < pt->pt_argc; i++) { + tv_list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]); } } else { EMSG2(_(e_invarg2), what); @@ -5507,18 +5539,36 @@ static void f_libcallnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) libcall_common(argvars, rettv, VAR_NUMBER); } -/* - * "line(string)" function - */ +// "line(string, [winid])" function static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr) { linenr_T lnum = 0; - pos_T *fp; + pos_T *fp = NULL; int fnum; - fp = var2fpos(&argvars[0], TRUE, &fnum); - if (fp != NULL) + if (argvars[1].v_type != VAR_UNKNOWN) { + tabpage_T *tp; + win_T *save_curwin; + tabpage_T *save_curtab; + + // use window specified in the second argument + win_T *wp = win_id2wp_tp(&argvars[1], &tp); + if (wp != NULL && tp != NULL) { + if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, true) + == OK) { + check_cursor(); + fp = var2fpos(&argvars[0], true, &fnum); + } + restore_win_noblock(save_curwin, save_curtab, true); + } + } else { + // use current window + fp = var2fpos(&argvars[0], true, &fnum); + } + + if (fp != NULL) { lnum = fp->lnum; + } rettv->vval.v_number = lnum; } @@ -9181,6 +9231,7 @@ static void f_sockconnect(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// struct storing information about current sort typedef struct { int item_compare_ic; + bool item_compare_lc; bool item_compare_numeric; bool item_compare_numbers; bool item_compare_float; @@ -9255,10 +9306,10 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero) p2 = ""; } if (!sortinfo->item_compare_numeric) { - if (sortinfo->item_compare_ic) { - res = STRICMP(p1, p2); + if (sortinfo->item_compare_lc) { + res = strcoll(p1, p2); } else { - res = STRCMP(p1, p2); + res = sortinfo->item_compare_ic ? STRICMP(p1, p2): STRCMP(p1, p2); } } else { double n1, n2; @@ -9393,6 +9444,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } info.item_compare_ic = false; + info.item_compare_lc = false; info.item_compare_numeric = false; info.item_compare_numbers = false; info.item_compare_float = false; @@ -9437,6 +9489,9 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } else if (strcmp(info.item_compare_func, "i") == 0) { info.item_compare_func = NULL; info.item_compare_ic = true; + } else if (strcmp(info.item_compare_func, "l") == 0) { + info.item_compare_func = NULL; + info.item_compare_lc = true; } } } |