diff options
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 129 |
1 files changed, 126 insertions, 3 deletions
diff --git a/src/eval.c b/src/eval.c index 4697e97f2..1b75201f8 100644 --- a/src/eval.c +++ b/src/eval.c @@ -369,6 +369,9 @@ static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty static void list_glob_vars __ARGS((void)); static void list_buf_vars __ARGS((void)); static void list_win_vars __ARGS((void)); +#ifdef FEAT_WINDOWS +static void list_tab_vars __ARGS((void)); +#endif static void list_vim_vars __ARGS((void)); static void list_script_vars __ARGS((void)); static void list_func_vars __ARGS((void)); @@ -567,6 +570,7 @@ static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); @@ -578,6 +582,7 @@ static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); @@ -1685,6 +1690,9 @@ ex_let(eap) list_glob_vars(); list_buf_vars(); list_win_vars(); +#ifdef FEAT_WINDOWS + list_tab_vars(); +#endif list_script_vars(); list_func_vars(); list_vim_vars(); @@ -1947,6 +1955,17 @@ list_win_vars() list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); } +#ifdef FEAT_WINDOWS +/* + * List tab page variables. + */ + static void +list_tab_vars() +{ + list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE); +} +#endif + /* * List Vim variables. */ @@ -2043,6 +2062,9 @@ list_arg_vars(eap, arg) case 'g': list_glob_vars(); break; case 'b': list_buf_vars(); break; case 'w': list_win_vars(); break; +#ifdef FEAT_WINDOWS + case 't': list_tab_vars(); break; +#endif case 'v': list_vim_vars(); break; case 's': list_script_vars(); break; case 'l': list_func_vars(); break; @@ -3577,12 +3599,20 @@ get_user_var_name(xp, idx) static long_u gdone; static long_u bdone; static long_u wdone; +#ifdef FEAT_WINDOWS + static long_u tdone; +#endif static int vidx; static hashitem_T *hi; hashtab_T *ht; if (idx == 0) + { gdone = bdone = wdone = vidx = 0; +#ifdef FEAT_WINDOWS + tdone = 0; +#endif + } /* Global variables */ if (gdone < globvarht.ht_used) @@ -3629,6 +3659,21 @@ get_user_var_name(xp, idx) return cat_prefix_varname('w', hi->hi_key); } +#ifdef FEAT_WINDOWS + /* t: variables */ + ht = &curtab->tp_vars.dv_hashtab; + if (tdone < ht->ht_used) + { + if (tdone++ == 0) + hi = ht->ht_array; + else + ++hi; + while (HASHITEM_EMPTY(hi)) + ++hi; + return cat_prefix_varname('t', hi->hi_key); + } +#endif + /* v: variables */ if (vidx < VV_LEN) return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); @@ -5697,7 +5742,9 @@ list_append_string(l, str, len) list_append(l, li); li->li_tv.v_type = VAR_STRING; li->li_tv.v_lock = 0; - if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) + if (str == NULL) + li->li_tv.vval.v_string = NULL; + else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) : vim_strsave(str))) == NULL) return FAIL; return OK; @@ -5995,6 +6042,9 @@ garbage_collect() int i; funccall_T *fc; int did_free = FALSE; +#ifdef FEAT_WINDOWS + tabpage_T *tp; +#endif /* * 1. Go through all accessible variables and mark all lists and dicts @@ -6009,9 +6059,15 @@ garbage_collect() set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); /* window-local variables */ - FOR_ALL_WINDOWS(wp) + FOR_ALL_TAB_WINDOWS(tp, wp) set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); +#ifdef FEAT_WINDOWS + /* tabpage-local variables */ + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) + set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); +#endif + /* global variables */ set_ref_in_ht(&globvarht, copyID); @@ -7021,6 +7077,7 @@ static struct fst {"maparg", 1, 3, f_maparg}, {"mapcheck", 1, 3, f_mapcheck}, {"match", 2, 4, f_match}, + {"matcharg", 1, 1, f_matcharg}, {"matchend", 2, 4, f_matchend}, {"matchlist", 2, 4, f_matchlist}, {"matchstr", 2, 4, f_matchstr}, @@ -7032,6 +7089,7 @@ static struct fst {"mode", 0, 0, f_mode}, {"nextnonblank", 1, 1, f_nextnonblank}, {"nr2char", 1, 1, f_nr2char}, + {"pathshorten", 1, 1, f_pathshorten}, {"prevnonblank", 1, 1, f_prevnonblank}, {"printf", 2, 19, f_printf}, {"pumvisible", 0, 0, f_pumvisible}, @@ -11484,7 +11542,7 @@ f_islocked(argvars, rettv) } } else if (lv.ll_range) - EMSG(_("E745: Range not allowed")); + EMSG(_("E786: Range not allowed")); else if (lv.ll_newkey != NULL) EMSG2(_(e_dictkey), lv.ll_newkey); else if (lv.ll_list != NULL) @@ -12120,6 +12178,30 @@ f_match(argvars, rettv) } /* + * "matcharg()" function + */ + static void +f_matcharg(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + if (rettv_list_alloc(rettv) == OK) + { +#ifdef FEAT_SEARCH_EXTRA + int mi = get_tv_number(&argvars[0]); + + if (mi >= 1 && mi <= 3) + { + list_append_string(rettv->vval.v_list, + syn_id2name(curwin->w_match_id[mi - 1]), -1); + list_append_string(rettv->vval.v_list, + curwin->w_match_pat[mi - 1], -1); + } +#endif + } +} + +/* * "matchend()" function */ static void @@ -12392,6 +12474,29 @@ f_nr2char(argvars, rettv) } /* + * "pathshorten()" function + */ + static void +f_pathshorten(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + char_u *p; + + rettv->v_type = VAR_STRING; + p = get_tv_string_chk(&argvars[0]); + if (p == NULL) + rettv->vval.v_string = NULL; + else + { + p = vim_strsave(p); + rettv->vval.v_string = p; + if (p != NULL) + shorten_dir(p); + } +} + +/* * "prevnonblank()" function */ static void @@ -16658,6 +16763,10 @@ set_cmdarg(eap, oldarg) len = 8; else len = 0; + + if (eap->read_edit) + len += 7; + if (eap->force_ff != 0) len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; # ifdef FEAT_MBYTE @@ -16677,6 +16786,10 @@ set_cmdarg(eap, oldarg) sprintf((char *)newval, " ++nobin"); else *newval = NUL; + + if (eap->read_edit) + STRCAT(newval, " ++edit"); + if (eap->force_ff != 0) sprintf((char *)newval + STRLEN(newval), " ++ff=%s", eap->cmd + eap->force_ff); @@ -17144,6 +17257,9 @@ find_var_in_ht(ht, varname, writing) case 'v': return &vimvars_var; case 'b': return &curbuf->b_bufvar; case 'w': return &curwin->w_winvar; +#ifdef FEAT_WINDOWS + case 't': return &curtab->tp_winvar; +#endif case 'l': return current_funccal == NULL ? NULL : ¤t_funccal->l_vars_var; case 'a': return current_funccal == NULL @@ -17207,6 +17323,10 @@ find_var_ht(name, varname) return &curbuf->b_vars.dv_hashtab; if (*name == 'w') /* window variable */ return &curwin->w_vars.dv_hashtab; +#ifdef FEAT_WINDOWS + if (*name == 't') /* tab page variable */ + return &curtab->tp_vars.dv_hashtab; +#endif if (*name == 'v') /* v: variable */ return &vimvarht; if (*name == 'a' && current_funccal != NULL) /* function argument */ @@ -18528,6 +18648,9 @@ ex_function(eap) fudi.fd_di->di_tv.v_lock = 0; fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); fp->uf_refcount = 1; + + /* behave like "dict" was used */ + flags |= FC_DICT; } /* insert the new function in the function list */ |