mirror of
https://github.com/vim/vim.git
synced 2025-09-05 21:43:39 -04:00
updated for version 7.0050
This commit is contained in:
parent
4399ef4764
commit
81bf708341
254
src/eval.c
254
src/eval.c
@ -335,10 +335,10 @@ static int list_append_tv __ARGS((list_T *l, typval_T *tv));
|
|||||||
static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
|
static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
|
||||||
static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef));
|
static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef));
|
||||||
static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv));
|
static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv));
|
||||||
static list_T *list_copy __ARGS((list_T *orig, int deep));
|
static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID));
|
||||||
static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
|
static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
|
||||||
static char_u *list2string __ARGS((typval_T *tv));
|
static char_u *list2string __ARGS((typval_T *tv));
|
||||||
static void list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo));
|
static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo));
|
||||||
|
|
||||||
static dict_T *dict_alloc __ARGS((void));
|
static dict_T *dict_alloc __ARGS((void));
|
||||||
static void dict_unref __ARGS((dict_T *d));
|
static void dict_unref __ARGS((dict_T *d));
|
||||||
@ -347,6 +347,7 @@ static dictitem_T *dictitem_alloc __ARGS((char_u *key));
|
|||||||
static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
|
static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
|
||||||
static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
|
static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
|
||||||
static void dictitem_free __ARGS((dictitem_T *item));
|
static void dictitem_free __ARGS((dictitem_T *item));
|
||||||
|
static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID));
|
||||||
static int dict_add __ARGS((dict_T *d, dictitem_T *item));
|
static int dict_add __ARGS((dict_T *d, dictitem_T *item));
|
||||||
static long dict_len __ARGS((dict_T *d));
|
static long dict_len __ARGS((dict_T *d));
|
||||||
static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len));
|
static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len));
|
||||||
@ -361,6 +362,7 @@ static int find_internal_func __ARGS((char_u *name));
|
|||||||
static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
|
static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
|
||||||
static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
|
static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
|
||||||
static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
|
static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
|
||||||
|
static void emsg_funcname __ARGS((char *msg, char_u *name));
|
||||||
|
|
||||||
static void f_add __ARGS((typval_T *argvars, typval_T *rettv));
|
static void f_add __ARGS((typval_T *argvars, typval_T *rettv));
|
||||||
static void f_append __ARGS((typval_T *argvars, typval_T *rettv));
|
static void f_append __ARGS((typval_T *argvars, typval_T *rettv));
|
||||||
@ -562,7 +564,7 @@ static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
|
|||||||
static int var_check_ro __ARGS((int flags, char_u *name));
|
static int var_check_ro __ARGS((int flags, char_u *name));
|
||||||
static int tv_check_lock __ARGS((int lock, char_u *name));
|
static int tv_check_lock __ARGS((int lock, char_u *name));
|
||||||
static void copy_tv __ARGS((typval_T *from, typval_T *to));
|
static void copy_tv __ARGS((typval_T *from, typval_T *to));
|
||||||
static void item_copy __ARGS((typval_T *from, typval_T *to, int deep));
|
static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID));
|
||||||
static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags));
|
static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags));
|
||||||
static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd));
|
static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd));
|
||||||
static int eval_fname_script __ARGS((char_u *p));
|
static int eval_fname_script __ARGS((char_u *p));
|
||||||
@ -2497,10 +2499,7 @@ ex_call(eap)
|
|||||||
|
|
||||||
if (*startarg != '(')
|
if (*startarg != '(')
|
||||||
{
|
{
|
||||||
if (*name == K_SPECIAL)
|
EMSG2(_("E107: Missing braces: %s"), eap->arg);
|
||||||
EMSG2(_("E107: Missing braces: <SNR>%s"), name + 3);
|
|
||||||
else
|
|
||||||
EMSG2(_("E107: Missing braces: %s"), name);
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4961,7 +4960,7 @@ list_concat(l1, l2, tv)
|
|||||||
list_T *l;
|
list_T *l;
|
||||||
|
|
||||||
/* make a copy of the first list. */
|
/* make a copy of the first list. */
|
||||||
l = list_copy(l1, FALSE);
|
l = list_copy(l1, FALSE, 0);
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
tv->v_type = VAR_LIST;
|
tv->v_type = VAR_LIST;
|
||||||
@ -4974,12 +4973,14 @@ list_concat(l1, l2, tv)
|
|||||||
/*
|
/*
|
||||||
* Make a copy of list "orig". Shallow if "deep" is FALSE.
|
* Make a copy of list "orig". Shallow if "deep" is FALSE.
|
||||||
* The refcount of the new list is set to 1.
|
* The refcount of the new list is set to 1.
|
||||||
|
* See item_copy() for "copyID".
|
||||||
* Returns NULL when out of memory.
|
* Returns NULL when out of memory.
|
||||||
*/
|
*/
|
||||||
static list_T *
|
static list_T *
|
||||||
list_copy(orig, deep)
|
list_copy(orig, deep, copyID)
|
||||||
list_T *orig;
|
list_T *orig;
|
||||||
int deep;
|
int deep;
|
||||||
|
int copyID;
|
||||||
{
|
{
|
||||||
list_T *copy;
|
list_T *copy;
|
||||||
listitem_T *item;
|
listitem_T *item;
|
||||||
@ -4991,18 +4992,37 @@ list_copy(orig, deep)
|
|||||||
copy = list_alloc();
|
copy = list_alloc();
|
||||||
if (copy != NULL)
|
if (copy != NULL)
|
||||||
{
|
{
|
||||||
for (item = orig->lv_first; item != NULL; item = item->li_next)
|
if (copyID != 0)
|
||||||
|
{
|
||||||
|
/* Do this before adding the items, because one of the items may
|
||||||
|
* refer back to this list. */
|
||||||
|
orig->lv_copyID = copyID;
|
||||||
|
orig->lv_copylist = copy;
|
||||||
|
}
|
||||||
|
for (item = orig->lv_first; item != NULL && !got_int;
|
||||||
|
item = item->li_next)
|
||||||
{
|
{
|
||||||
ni = listitem_alloc();
|
ni = listitem_alloc();
|
||||||
if (ni == NULL)
|
if (ni == NULL)
|
||||||
break;
|
break;
|
||||||
if (deep)
|
if (deep)
|
||||||
item_copy(&item->li_tv, &ni->li_tv, deep);
|
{
|
||||||
|
if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL)
|
||||||
|
{
|
||||||
|
vim_free(ni);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
copy_tv(&item->li_tv, &ni->li_tv);
|
copy_tv(&item->li_tv, &ni->li_tv);
|
||||||
list_append(copy, ni);
|
list_append(copy, ni);
|
||||||
}
|
}
|
||||||
++copy->lv_refcount;
|
++copy->lv_refcount;
|
||||||
|
if (item != NULL)
|
||||||
|
{
|
||||||
|
list_unref(copy);
|
||||||
|
copy = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
@ -5054,7 +5074,11 @@ list2string(tv)
|
|||||||
return NULL;
|
return NULL;
|
||||||
ga_init2(&ga, (int)sizeof(char), 80);
|
ga_init2(&ga, (int)sizeof(char), 80);
|
||||||
ga_append(&ga, '[');
|
ga_append(&ga, '[');
|
||||||
list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE);
|
if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL)
|
||||||
|
{
|
||||||
|
vim_free(ga.ga_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
ga_append(&ga, ']');
|
ga_append(&ga, ']');
|
||||||
ga_append(&ga, NUL);
|
ga_append(&ga, NUL);
|
||||||
return (char_u *)ga.ga_data;
|
return (char_u *)ga.ga_data;
|
||||||
@ -5063,8 +5087,9 @@ list2string(tv)
|
|||||||
/*
|
/*
|
||||||
* Join list "l" into a string in "*gap", using separator "sep".
|
* Join list "l" into a string in "*gap", using separator "sep".
|
||||||
* When "echo" is TRUE use String as echoed, otherwise as inside a List.
|
* When "echo" is TRUE use String as echoed, otherwise as inside a List.
|
||||||
|
* Return FAIL or OK.
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
list_join(gap, l, sep, echo)
|
list_join(gap, l, sep, echo)
|
||||||
garray_T *gap;
|
garray_T *gap;
|
||||||
list_T *l;
|
list_T *l;
|
||||||
@ -5077,7 +5102,7 @@ list_join(gap, l, sep, echo)
|
|||||||
listitem_T *item;
|
listitem_T *item;
|
||||||
char_u *s;
|
char_u *s;
|
||||||
|
|
||||||
for (item = l->lv_first; item != NULL; item = item->li_next)
|
for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
|
||||||
{
|
{
|
||||||
if (first)
|
if (first)
|
||||||
first = FALSE;
|
first = FALSE;
|
||||||
@ -5091,7 +5116,10 @@ list_join(gap, l, sep, echo)
|
|||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
ga_concat(gap, s);
|
ga_concat(gap, s);
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
|
if (s == NULL)
|
||||||
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5108,6 +5136,7 @@ dict_alloc()
|
|||||||
hash_init(&d->dv_hashtab);
|
hash_init(&d->dv_hashtab);
|
||||||
d->dv_lock = 0;
|
d->dv_lock = 0;
|
||||||
d->dv_refcount = 0;
|
d->dv_refcount = 0;
|
||||||
|
d->dv_copyID = 0;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@ -5222,12 +5251,14 @@ dictitem_free(item)
|
|||||||
/*
|
/*
|
||||||
* Make a copy of dict "d". Shallow if "deep" is FALSE.
|
* Make a copy of dict "d". Shallow if "deep" is FALSE.
|
||||||
* The refcount of the new dict is set to 1.
|
* The refcount of the new dict is set to 1.
|
||||||
|
* See item_copy() for "copyID".
|
||||||
* Returns NULL when out of memory.
|
* Returns NULL when out of memory.
|
||||||
*/
|
*/
|
||||||
static dict_T *
|
static dict_T *
|
||||||
dict_copy(orig, deep)
|
dict_copy(orig, deep, copyID)
|
||||||
dict_T *orig;
|
dict_T *orig;
|
||||||
int deep;
|
int deep;
|
||||||
|
int copyID;
|
||||||
{
|
{
|
||||||
dict_T *copy;
|
dict_T *copy;
|
||||||
dictitem_T *di;
|
dictitem_T *di;
|
||||||
@ -5240,8 +5271,13 @@ dict_copy(orig, deep)
|
|||||||
copy = dict_alloc();
|
copy = dict_alloc();
|
||||||
if (copy != NULL)
|
if (copy != NULL)
|
||||||
{
|
{
|
||||||
|
if (copyID != 0)
|
||||||
|
{
|
||||||
|
orig->dv_copyID = copyID;
|
||||||
|
orig->dv_copydict = copy;
|
||||||
|
}
|
||||||
todo = orig->dv_hashtab.ht_used;
|
todo = orig->dv_hashtab.ht_used;
|
||||||
for (hi = orig->dv_hashtab.ht_array; todo > 0; ++hi)
|
for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
|
||||||
{
|
{
|
||||||
if (!HASHITEM_EMPTY(hi))
|
if (!HASHITEM_EMPTY(hi))
|
||||||
{
|
{
|
||||||
@ -5251,7 +5287,14 @@ dict_copy(orig, deep)
|
|||||||
if (di == NULL)
|
if (di == NULL)
|
||||||
break;
|
break;
|
||||||
if (deep)
|
if (deep)
|
||||||
item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep);
|
{
|
||||||
|
if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep,
|
||||||
|
copyID) == FAIL)
|
||||||
|
{
|
||||||
|
vim_free(di);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
|
copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
|
||||||
if (dict_add(copy, di) == FAIL)
|
if (dict_add(copy, di) == FAIL)
|
||||||
@ -5263,6 +5306,11 @@ dict_copy(orig, deep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
++copy->dv_refcount;
|
++copy->dv_refcount;
|
||||||
|
if (todo > 0)
|
||||||
|
{
|
||||||
|
dict_unref(copy);
|
||||||
|
copy = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
@ -5355,7 +5403,7 @@ dict2string(tv)
|
|||||||
ga_append(&ga, '{');
|
ga_append(&ga, '{');
|
||||||
|
|
||||||
todo = d->dv_hashtab.ht_used;
|
todo = d->dv_hashtab.ht_used;
|
||||||
for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
|
for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
|
||||||
{
|
{
|
||||||
if (!HASHITEM_EMPTY(hi))
|
if (!HASHITEM_EMPTY(hi))
|
||||||
{
|
{
|
||||||
@ -5377,8 +5425,15 @@ dict2string(tv)
|
|||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
ga_concat(&ga, s);
|
ga_concat(&ga, s);
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
|
if (s == NULL)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (todo > 0)
|
||||||
|
{
|
||||||
|
vim_free(ga.ga_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ga_append(&ga, '}');
|
ga_append(&ga, '}');
|
||||||
ga_append(&ga, NUL);
|
ga_append(&ga, NUL);
|
||||||
@ -5721,7 +5776,7 @@ static struct fst
|
|||||||
{"count", 2, 4, f_count},
|
{"count", 2, 4, f_count},
|
||||||
{"cscope_connection",0,3, f_cscope_connection},
|
{"cscope_connection",0,3, f_cscope_connection},
|
||||||
{"cursor", 2, 2, f_cursor},
|
{"cursor", 2, 2, f_cursor},
|
||||||
{"deepcopy", 1, 1, f_deepcopy},
|
{"deepcopy", 1, 2, f_deepcopy},
|
||||||
{"delete", 1, 1, f_delete},
|
{"delete", 1, 1, f_delete},
|
||||||
{"did_filetype", 0, 0, f_did_filetype},
|
{"did_filetype", 0, 0, f_did_filetype},
|
||||||
{"diff_filler", 1, 1, f_diff_filler},
|
{"diff_filler", 1, 1, f_diff_filler},
|
||||||
@ -6043,9 +6098,9 @@ get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange,
|
|||||||
else if (!aborting())
|
else if (!aborting())
|
||||||
{
|
{
|
||||||
if (argcount == MAX_FUNC_ARGS)
|
if (argcount == MAX_FUNC_ARGS)
|
||||||
EMSG2(_("E740: Too many arguments for function %s"), name);
|
emsg_funcname("E740: Too many arguments for function %s", name);
|
||||||
else
|
else
|
||||||
EMSG2(_("E116: Invalid arguments for function %s"), name);
|
emsg_funcname("E116: Invalid arguments for function %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (--argcount >= 0)
|
while (--argcount >= 0)
|
||||||
@ -6247,21 +6302,21 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
|
|||||||
switch (error)
|
switch (error)
|
||||||
{
|
{
|
||||||
case ERROR_UNKNOWN:
|
case ERROR_UNKNOWN:
|
||||||
EMSG2(_("E117: Unknown function: %s"), name);
|
emsg_funcname("E117: Unknown function: %s", name);
|
||||||
break;
|
break;
|
||||||
case ERROR_TOOMANY:
|
case ERROR_TOOMANY:
|
||||||
EMSG2(_(e_toomanyarg), name);
|
emsg_funcname(e_toomanyarg, name);
|
||||||
break;
|
break;
|
||||||
case ERROR_TOOFEW:
|
case ERROR_TOOFEW:
|
||||||
EMSG2(_("E119: Not enough arguments for function: %s"),
|
emsg_funcname("E119: Not enough arguments for function: %s",
|
||||||
name);
|
name);
|
||||||
break;
|
break;
|
||||||
case ERROR_SCRIPT:
|
case ERROR_SCRIPT:
|
||||||
EMSG2(_("E120: Using <SID> not in a script context: %s"),
|
emsg_funcname("E120: Using <SID> not in a script context: %s",
|
||||||
name);
|
name);
|
||||||
break;
|
break;
|
||||||
case ERROR_DICT:
|
case ERROR_DICT:
|
||||||
EMSG2(_("E725: Calling dict function without Dictionary: %s"),
|
emsg_funcname("E725: Calling dict function without Dictionary: %s",
|
||||||
name);
|
name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -6274,6 +6329,25 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Give an error message with a function name. Handle <SNR> things.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
emsg_funcname(msg, name)
|
||||||
|
char *msg;
|
||||||
|
char_u *name;
|
||||||
|
{
|
||||||
|
char_u *p;
|
||||||
|
|
||||||
|
if (*name == K_SPECIAL)
|
||||||
|
p = concat_str((char_u *)"<SNR>", name + 3);
|
||||||
|
else
|
||||||
|
p = name;
|
||||||
|
EMSG2(_(msg), p);
|
||||||
|
if (p != name)
|
||||||
|
vim_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* Implementation of the built-in functions
|
* Implementation of the built-in functions
|
||||||
*/
|
*/
|
||||||
@ -6906,7 +6980,7 @@ f_copy(argvars, rettv)
|
|||||||
typval_T *argvars;
|
typval_T *argvars;
|
||||||
typval_T *rettv;
|
typval_T *rettv;
|
||||||
{
|
{
|
||||||
item_copy(&argvars[0], rettv, FALSE);
|
item_copy(&argvars[0], rettv, FALSE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7052,7 +7126,15 @@ f_deepcopy(argvars, rettv)
|
|||||||
typval_T *argvars;
|
typval_T *argvars;
|
||||||
typval_T *rettv;
|
typval_T *rettv;
|
||||||
{
|
{
|
||||||
item_copy(&argvars[0], rettv, TRUE);
|
static int copyID = 0;
|
||||||
|
int noref = 0;
|
||||||
|
|
||||||
|
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||||
|
noref = get_tv_number(&argvars[1]);
|
||||||
|
if (noref < 0 || noref > 1)
|
||||||
|
EMSG(_(e_invarg));
|
||||||
|
else
|
||||||
|
item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++copyID : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -10200,7 +10282,7 @@ find_some_match(argvars, rettv, type)
|
|||||||
char_u *save_cpo;
|
char_u *save_cpo;
|
||||||
long start = 0;
|
long start = 0;
|
||||||
long nth = 1;
|
long nth = 1;
|
||||||
int match;
|
int match = 0;
|
||||||
list_T *l = NULL;
|
list_T *l = NULL;
|
||||||
listitem_T *li = NULL;
|
listitem_T *li = NULL;
|
||||||
long idx = 0;
|
long idx = 0;
|
||||||
@ -10275,6 +10357,8 @@ find_some_match(argvars, rettv, type)
|
|||||||
}
|
}
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
str = echo_string(&li->li_tv, &tofree, strbuf);
|
str = echo_string(&li->li_tv, &tofree, strbuf);
|
||||||
|
if (str == NULL)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
match = vim_regexec_nl(®match, str, (colnr_T)0);
|
match = vim_regexec_nl(®match, str, (colnr_T)0);
|
||||||
@ -11394,7 +11478,7 @@ f_reverse(argvars, rettv)
|
|||||||
&& !tv_check_lock(l->lv_lock, (char_u *)"reverse()"))
|
&& !tv_check_lock(l->lv_lock, (char_u *)"reverse()"))
|
||||||
{
|
{
|
||||||
li = l->lv_last;
|
li = l->lv_last;
|
||||||
l->lv_first = l->lv_last = li;
|
l->lv_first = l->lv_last = NULL;
|
||||||
l->lv_len = 0;
|
l->lv_len = 0;
|
||||||
while (li != NULL)
|
while (li != NULL)
|
||||||
{
|
{
|
||||||
@ -14338,7 +14422,8 @@ set_var(name, tv, copy)
|
|||||||
}
|
}
|
||||||
if (function_exists(name))
|
if (function_exists(name))
|
||||||
{
|
{
|
||||||
EMSG2(_("705: Variable name conflicts with existing function: %s"), name);
|
EMSG2(_("705: Variable name conflicts with existing function: %s"),
|
||||||
|
name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14520,19 +14605,24 @@ copy_tv(from, to)
|
|||||||
/*
|
/*
|
||||||
* Make a copy of an item.
|
* Make a copy of an item.
|
||||||
* Lists and Dictionaries are also copied. A deep copy if "deep" is set.
|
* Lists and Dictionaries are also copied. A deep copy if "deep" is set.
|
||||||
|
* For deepcopy() "copyID" is zero for a full copy or the ID for when a
|
||||||
|
* reference to an already copied list/dict can be used.
|
||||||
|
* Returns FAIL or OK.
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
item_copy(from, to, deep)
|
item_copy(from, to, deep, copyID)
|
||||||
typval_T *from;
|
typval_T *from;
|
||||||
typval_T *to;
|
typval_T *to;
|
||||||
int deep;
|
int deep;
|
||||||
|
int copyID;
|
||||||
{
|
{
|
||||||
static int recurse = 0;
|
static int recurse = 0;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
if (recurse >= DICT_MAXNEST)
|
if (recurse >= DICT_MAXNEST)
|
||||||
{
|
{
|
||||||
EMSG(_("E698: variable nested too deep for making a copy"));
|
EMSG(_("E698: variable nested too deep for making a copy"));
|
||||||
return;
|
return FAIL;
|
||||||
}
|
}
|
||||||
++recurse;
|
++recurse;
|
||||||
|
|
||||||
@ -14546,17 +14636,41 @@ item_copy(from, to, deep)
|
|||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
to->v_type = VAR_LIST;
|
to->v_type = VAR_LIST;
|
||||||
to->v_lock = 0;
|
to->v_lock = 0;
|
||||||
to->vval.v_list = list_copy(from->vval.v_list, deep);
|
if (from->vval.v_list == NULL)
|
||||||
|
to->vval.v_list = NULL;
|
||||||
|
else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID)
|
||||||
|
{
|
||||||
|
/* use the copy made earlier */
|
||||||
|
to->vval.v_list = from->vval.v_list->lv_copylist;
|
||||||
|
++to->vval.v_list->lv_refcount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
to->vval.v_list = list_copy(from->vval.v_list, deep, copyID);
|
||||||
|
if (to->vval.v_list == NULL)
|
||||||
|
ret = FAIL;
|
||||||
break;
|
break;
|
||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
to->v_type = VAR_DICT;
|
to->v_type = VAR_DICT;
|
||||||
to->v_lock = 0;
|
to->v_lock = 0;
|
||||||
to->vval.v_dict = dict_copy(from->vval.v_dict, deep);
|
if (from->vval.v_dict == NULL)
|
||||||
|
to->vval.v_dict = NULL;
|
||||||
|
else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID)
|
||||||
|
{
|
||||||
|
/* use the copy made earlier */
|
||||||
|
to->vval.v_dict = from->vval.v_dict->dv_copydict;
|
||||||
|
++to->vval.v_dict->dv_refcount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID);
|
||||||
|
if (to->vval.v_dict == NULL)
|
||||||
|
ret = FAIL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
EMSG2(_(e_intern2), "item_copy()");
|
EMSG2(_(e_intern2), "item_copy()");
|
||||||
|
ret = FAIL;
|
||||||
}
|
}
|
||||||
--recurse;
|
--recurse;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -14604,31 +14718,34 @@ ex_echo(eap)
|
|||||||
}
|
}
|
||||||
else if (eap->cmdidx == CMD_echo)
|
else if (eap->cmdidx == CMD_echo)
|
||||||
msg_puts_attr((char_u *)" ", echo_attr);
|
msg_puts_attr((char_u *)" ", echo_attr);
|
||||||
for (p = echo_string(&rettv, &tofree, numbuf);
|
p = echo_string(&rettv, &tofree, numbuf);
|
||||||
*p != NUL && !got_int; ++p)
|
if (p != NULL)
|
||||||
if (*p == '\n' || *p == '\r' || *p == TAB)
|
for ( ; *p != NUL && !got_int; ++p)
|
||||||
{
|
{
|
||||||
if (*p != TAB && needclr)
|
if (*p == '\n' || *p == '\r' || *p == TAB)
|
||||||
{
|
{
|
||||||
/* remove any text still there from the command */
|
if (*p != TAB && needclr)
|
||||||
msg_clr_eos();
|
{
|
||||||
needclr = FALSE;
|
/* remove any text still there from the command */
|
||||||
}
|
msg_clr_eos();
|
||||||
msg_putchar_attr(*p, echo_attr);
|
needclr = FALSE;
|
||||||
}
|
}
|
||||||
else
|
msg_putchar_attr(*p, echo_attr);
|
||||||
{
|
|
||||||
#ifdef FEAT_MBYTE
|
|
||||||
if (has_mbyte)
|
|
||||||
{
|
|
||||||
int i = (*mb_ptr2len_check)(p);
|
|
||||||
|
|
||||||
(void)msg_outtrans_len_attr(p, i, echo_attr);
|
|
||||||
p += i - 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
#ifdef FEAT_MBYTE
|
||||||
|
if (has_mbyte)
|
||||||
|
{
|
||||||
|
int i = (*mb_ptr2len_check)(p);
|
||||||
|
|
||||||
|
(void)msg_outtrans_len_attr(p, i, echo_attr);
|
||||||
|
p += i - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
(void)msg_outtrans_len_attr(p, 1, echo_attr);
|
(void)msg_outtrans_len_attr(p, 1, echo_attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
}
|
}
|
||||||
@ -14906,7 +15023,7 @@ ex_function(eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EMSG2(_("E123: Undefined function: %s"), name);
|
emsg_funcname("E123: Undefined function: %s", name);
|
||||||
}
|
}
|
||||||
goto ret_free;
|
goto ret_free;
|
||||||
}
|
}
|
||||||
@ -15019,7 +15136,7 @@ ex_function(eap)
|
|||||||
if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
|
if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
|
||||||
EMSG(_(e_funcdict));
|
EMSG(_(e_funcdict));
|
||||||
else if (name != NULL && find_func(name) != NULL)
|
else if (name != NULL && find_func(name) != NULL)
|
||||||
EMSG2(_(e_funcexts), name);
|
emsg_funcname(e_funcexts, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg_putchar('\n'); /* don't overwrite the function name */
|
msg_putchar('\n'); /* don't overwrite the function name */
|
||||||
@ -15146,7 +15263,8 @@ ex_function(eap)
|
|||||||
v = find_var(name, NULL);
|
v = find_var(name, NULL);
|
||||||
if (v != NULL && v->di_tv.v_type == VAR_FUNC)
|
if (v != NULL && v->di_tv.v_type == VAR_FUNC)
|
||||||
{
|
{
|
||||||
EMSG2(_("E707: Function name conflicts with variable: %s"), name);
|
emsg_funcname("E707: Function name conflicts with variable: %s",
|
||||||
|
name);
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15155,12 +15273,12 @@ ex_function(eap)
|
|||||||
{
|
{
|
||||||
if (!eap->forceit)
|
if (!eap->forceit)
|
||||||
{
|
{
|
||||||
EMSG2(_(e_funcexts), name);
|
emsg_funcname(e_funcexts, name);
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
if (fp->calls > 0)
|
if (fp->calls > 0)
|
||||||
{
|
{
|
||||||
EMSG2(_("E127: Cannot redefine function %s: It is in use"),
|
emsg_funcname("E127: Cannot redefine function %s: It is in use",
|
||||||
name);
|
name);
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
@ -16192,14 +16310,14 @@ discard_pending_return(rettv)
|
|||||||
get_return_cmd(rettv)
|
get_return_cmd(rettv)
|
||||||
void *rettv;
|
void *rettv;
|
||||||
{
|
{
|
||||||
char_u *s;
|
char_u *s = NULL;
|
||||||
char_u *tofree = NULL;
|
char_u *tofree = NULL;
|
||||||
char_u numbuf[NUMBUFLEN];
|
char_u numbuf[NUMBUFLEN];
|
||||||
|
|
||||||
if (rettv == NULL)
|
if (rettv != NULL)
|
||||||
s = (char_u *)"";
|
|
||||||
else
|
|
||||||
s = echo_string((typval_T *)rettv, &tofree, numbuf);
|
s = echo_string((typval_T *)rettv, &tofree, numbuf);
|
||||||
|
if (s == NULL)
|
||||||
|
s = (char_u *)"";
|
||||||
|
|
||||||
STRCPY(IObuff, ":return ");
|
STRCPY(IObuff, ":return ");
|
||||||
STRNCPY(IObuff + 8, s, IOSIZE - 8);
|
STRNCPY(IObuff + 8, s, IOSIZE - 8);
|
||||||
@ -16368,6 +16486,7 @@ write_viminfo_varlist(fp)
|
|||||||
dictitem_T *this_var;
|
dictitem_T *this_var;
|
||||||
int todo;
|
int todo;
|
||||||
char *s;
|
char *s;
|
||||||
|
char_u *p;
|
||||||
char_u *tofree;
|
char_u *tofree;
|
||||||
char_u numbuf[NUMBUFLEN];
|
char_u numbuf[NUMBUFLEN];
|
||||||
|
|
||||||
@ -16392,8 +16511,9 @@ write_viminfo_varlist(fp)
|
|||||||
default: continue;
|
default: continue;
|
||||||
}
|
}
|
||||||
fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
|
fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
|
||||||
viminfo_writestring(fp, echo_string(&this_var->di_tv,
|
p = echo_string(&this_var->di_tv, &tofree, numbuf);
|
||||||
&tofree, numbuf));
|
if (p != NULL)
|
||||||
|
viminfo_writestring(fp, p);
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3250,32 +3250,57 @@ ex_append(eap)
|
|||||||
char_u *theline;
|
char_u *theline;
|
||||||
int did_undo = FALSE;
|
int did_undo = FALSE;
|
||||||
linenr_T lnum = eap->line2;
|
linenr_T lnum = eap->line2;
|
||||||
|
int indent = 0;
|
||||||
|
char_u *p;
|
||||||
|
int vcol;
|
||||||
|
int empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
|
||||||
|
|
||||||
if (eap->cmdidx != CMD_append)
|
if (eap->cmdidx != CMD_append)
|
||||||
--lnum;
|
--lnum;
|
||||||
|
|
||||||
|
/* when the buffer is empty append to line 0 and delete the dummy line */
|
||||||
|
if (empty && lnum == 1)
|
||||||
|
lnum = 0;
|
||||||
|
|
||||||
State = INSERT; /* behave like in Insert mode */
|
State = INSERT; /* behave like in Insert mode */
|
||||||
if (curbuf->b_p_iminsert == B_IMODE_LMAP)
|
if (curbuf->b_p_iminsert == B_IMODE_LMAP)
|
||||||
State |= LANGMAP;
|
State |= LANGMAP;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
msg_scroll = TRUE;
|
msg_scroll = TRUE;
|
||||||
need_wait_return = FALSE;
|
need_wait_return = FALSE;
|
||||||
|
if (curbuf->b_p_ai && lnum > 0)
|
||||||
|
indent = get_indent_lnum(lnum);
|
||||||
if (eap->getline == NULL)
|
if (eap->getline == NULL)
|
||||||
theline = getcmdline(
|
theline = getcmdline(
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
eap->cstack->cs_looplevel > 0 ? -1 :
|
eap->cstack->cs_looplevel > 0 ? -1 :
|
||||||
#endif
|
#endif
|
||||||
NUL, 0L, 0);
|
NUL, 0L, indent);
|
||||||
else
|
else
|
||||||
theline = eap->getline(
|
theline = eap->getline(
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
eap->cstack->cs_looplevel > 0 ? -1 :
|
eap->cstack->cs_looplevel > 0 ? -1 :
|
||||||
#endif
|
#endif
|
||||||
NUL, eap->cookie, 0);
|
NUL, eap->cookie, indent);
|
||||||
lines_left = Rows - 1;
|
lines_left = Rows - 1;
|
||||||
if (theline == NULL || (theline[0] == '.' && theline[1] == NUL)
|
if (theline == NULL)
|
||||||
|| (!did_undo && u_save(lnum, lnum + 1) == FAIL))
|
break;
|
||||||
|
|
||||||
|
/* Look for the "." after automatic indent. */
|
||||||
|
vcol = 0;
|
||||||
|
for (p = theline; indent > vcol; ++p)
|
||||||
|
{
|
||||||
|
if (*p == ' ')
|
||||||
|
++vcol;
|
||||||
|
else if (*p == TAB)
|
||||||
|
vcol += 8 - vcol % 8;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((p[0] == '.' && p[1] == NUL)
|
||||||
|
|| (!did_undo && u_save(lnum, lnum + 1) == FAIL))
|
||||||
{
|
{
|
||||||
vim_free(theline);
|
vim_free(theline);
|
||||||
break;
|
break;
|
||||||
@ -3288,6 +3313,12 @@ ex_append(eap)
|
|||||||
vim_free(theline);
|
vim_free(theline);
|
||||||
++lnum;
|
++lnum;
|
||||||
msg_didout = TRUE; /* also scroll for empty line */
|
msg_didout = TRUE; /* also scroll for empty line */
|
||||||
|
|
||||||
|
if (empty)
|
||||||
|
{
|
||||||
|
ml_delete(2L, FALSE);
|
||||||
|
empty = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
State = NORMAL;
|
State = NORMAL;
|
||||||
|
|
||||||
@ -3341,14 +3372,22 @@ ex_z(eap)
|
|||||||
exarg_T *eap;
|
exarg_T *eap;
|
||||||
{
|
{
|
||||||
char_u *x;
|
char_u *x;
|
||||||
int bigness = curwin->w_height - 3;
|
int bigness;
|
||||||
char_u kind;
|
char_u *kind;
|
||||||
int numbered = FALSE;
|
int numbered = FALSE;
|
||||||
int minus = 0;
|
int minus = 0;
|
||||||
linenr_T start, end, curs, i;
|
linenr_T start, end, curs, i;
|
||||||
int j;
|
int j;
|
||||||
linenr_T lnum = eap->line2;
|
linenr_T lnum = eap->line2;
|
||||||
|
|
||||||
|
/* Vi compatible: ":z!" uses display height, without a count uses
|
||||||
|
* 'scroll' */
|
||||||
|
if (eap->forceit)
|
||||||
|
bigness = curwin->w_height;
|
||||||
|
else if (firstwin == lastwin)
|
||||||
|
bigness = curwin->w_p_scr * 2;
|
||||||
|
else
|
||||||
|
bigness = curwin->w_height - 3;
|
||||||
if (bigness < 1)
|
if (bigness < 1)
|
||||||
bigness = 1;
|
bigness = 1;
|
||||||
|
|
||||||
@ -3359,8 +3398,11 @@ ex_z(eap)
|
|||||||
++x;
|
++x;
|
||||||
}
|
}
|
||||||
|
|
||||||
kind = *x;
|
kind = x;
|
||||||
if (kind == '-' || kind == '+' || kind == '=' || kind == '^' || kind == '.')
|
if (*kind == '-' || *kind == '+' || *kind == '='
|
||||||
|
|| *kind == '^' || *kind == '.')
|
||||||
|
++x;
|
||||||
|
while (*x == '-' || *x == '+')
|
||||||
++x;
|
++x;
|
||||||
|
|
||||||
if (*x != 0)
|
if (*x != 0)
|
||||||
@ -3371,15 +3413,23 @@ ex_z(eap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
bigness = atoi((char *)x);
|
bigness = atoi((char *)x);
|
||||||
|
p_window = bigness;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (kind)
|
/* the number of '-' and '+' multiplies the distance */
|
||||||
|
if (*kind == '-' || *kind == '+')
|
||||||
|
for (x = kind + 1; *x == *kind; ++x)
|
||||||
|
;
|
||||||
|
|
||||||
|
switch (*kind)
|
||||||
{
|
{
|
||||||
case '-':
|
case '-':
|
||||||
start = lnum - bigness;
|
start = lnum - bigness * (x - kind);
|
||||||
end = lnum;
|
end = start + bigness;
|
||||||
curs = lnum;
|
curs = end;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
@ -3403,7 +3453,9 @@ ex_z(eap)
|
|||||||
|
|
||||||
default: /* '+' */
|
default: /* '+' */
|
||||||
start = lnum;
|
start = lnum;
|
||||||
end = lnum + bigness;
|
if (*kind == '+')
|
||||||
|
start += bigness * (x - kind - 1);
|
||||||
|
end = start + bigness;
|
||||||
curs = end;
|
curs = end;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3526,15 +3578,15 @@ do_sub(eap)
|
|||||||
int which_pat;
|
int which_pat;
|
||||||
char_u *cmd;
|
char_u *cmd;
|
||||||
int save_State;
|
int save_State;
|
||||||
linenr_T first_line = 0; /* first changed line */
|
linenr_T first_line = 0; /* first changed line */
|
||||||
linenr_T last_line= 0; /* below last changed line AFTER the
|
linenr_T last_line= 0; /* below last changed line AFTER the
|
||||||
* change */
|
* change */
|
||||||
linenr_T old_line_count = curbuf->b_ml.ml_line_count;
|
linenr_T old_line_count = curbuf->b_ml.ml_line_count;
|
||||||
linenr_T line2;
|
linenr_T line2;
|
||||||
long nmatch; /* number of lines in match */
|
long nmatch; /* number of lines in match */
|
||||||
linenr_T sub_firstlnum; /* nr of first sub line */
|
linenr_T sub_firstlnum; /* nr of first sub line */
|
||||||
char_u *sub_firstline; /* allocated copy of first sub line */
|
char_u *sub_firstline; /* allocated copy of first sub line */
|
||||||
int endcolumn; /* put cursor in last column when done */
|
int endcolumn = FALSE; /* cursor in last column when done */
|
||||||
|
|
||||||
cmd = eap->arg;
|
cmd = eap->arg;
|
||||||
if (!global_busy)
|
if (!global_busy)
|
||||||
|
@ -609,6 +609,7 @@ ml_close(buf, del_file)
|
|||||||
* Close all existing memlines and memfiles.
|
* Close all existing memlines and memfiles.
|
||||||
* Only used when exiting.
|
* Only used when exiting.
|
||||||
* When 'del_file' is TRUE, delete the memfiles.
|
* When 'del_file' is TRUE, delete the memfiles.
|
||||||
|
* But don't delete files that were ":preserve"d when we are POSIX compatible.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ml_close_all(del_file)
|
ml_close_all(del_file)
|
||||||
@ -617,7 +618,8 @@ ml_close_all(del_file)
|
|||||||
buf_T *buf;
|
buf_T *buf;
|
||||||
|
|
||||||
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
|
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
|
||||||
ml_close(buf, del_file);
|
ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0
|
||||||
|
|| vim_strchr(p_cpo, CPO_PRESERVE) == NULL));
|
||||||
#ifdef TEMPDIRNAMES
|
#ifdef TEMPDIRNAMES
|
||||||
vim_deltempdir(); /* delete created temp directory */
|
vim_deltempdir(); /* delete created temp directory */
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user